From 88ed57777725be8778b7236894e060ed21cce33d Mon Sep 17 00:00:00 2001 From: JustHadi <35467011+HadiKhai@users.noreply.github.com> Date: Wed, 13 Nov 2024 19:01:59 +0200 Subject: [PATCH] Develop (#61) * feat: expandableCard (#54) * Hadi/console fixes (#56) * Develop (#48) * Console (#43) * fix: naming app name * fix: packages * fix(console): deployment * fix: trial * fix(console): trial * trial * trial * trial * trial * trial * trial * trial --------- Co-authored-by: anthony2399 * fix: error from useEnsWalletClient * Develop (#44) * feat: remove mapps from justverified * fix yarn.lock * fix * feat: efp * feat: efp and storybook for react sdk * chore(release): publish - project: justweb3-efp-plugin 0.1.0 * chore(release): publish - project: justweb3-efp-plugin 0.1.1 * chore(release): publish - project: justweb3-efp-plugin 0.1.2 * chore(release): publish - project: justweb3-efp-plugin 0.1.3 * feat: console fixes * chore(release): publish - project: justweb3-efp-plugin 0.1.4 * feat: added docs and the sign in should only show ens set to default resolver or justaname resolver only * feat: add verbose to the test in ci * trial * trial * trial * trial * Trial (#42) * trial * trial * trial * trial * trial * fix: lint fix on react and package json of projects * fix: lint fix on react and package json of projects * Console (#43) * fix: naming app name * fix: packages * fix(console): deployment * fix: trial * fix(console): trial * trial * trial * trial * trial * trial * trial * trial --------- Co-authored-by: anthony2399 * fix: error from useEnsWalletClient --------- Co-authored-by: anthony2399 * release * chore(release): publish - project: @justaname.id/sdk 0.2.125 - project: @justaname.id/react 0.3.128 - project: @justaname.id/siwens 0.0.58 - project: @justweb3/ui 0.0.64 - project: @justweb3/widget 0.0.64 - project: @justverified/plugin 0.0.63 - project: @justweb3/efp-plugin 0.1.24 * release * chore(release): publish - project: @justaname.id/sdk 0.2.126 - project: @justaname.id/react 0.3.129 - project: @justaname.id/siwens 0.0.59 - project: @justweb3/ui 0.0.65 - project: @justweb3/widget 0.0.65 - project: @justverified/plugin 0.0.64 - project: @justweb3/efp-plugin 0.1.25 * chore(release): publish - project: @justaname.id/sdk 0.2.127 - project: @justaname.id/react 0.3.130 - project: @justaname.id/siwens 0.0.60 - project: @justweb3/ui 0.0.66 - project: @justweb3/widget 0.0.66 - project: @justverified/plugin 0.0.65 - project: @justweb3/efp-plugin 0.1.26 * chore(release): publish - project: @justaname.id/sdk 0.2.128 - project: @justaname.id/react 0.3.131 - project: @justaname.id/siwens 0.0.61 - project: @justweb3/ui 0.0.67 - project: @justweb3/widget 0.0.67 - project: @justverified/plugin 0.0.66 - project: @justweb3/efp-plugin 0.1.27 * fix: update rest call and ui fixes * fix: console * Develop (#47) * feat: remove mapps from justverified * fix yarn.lock * fix * feat: efp * feat: efp and storybook for react sdk * chore(release): publish - project: justweb3-efp-plugin 0.1.0 * chore(release): publish - project: justweb3-efp-plugin 0.1.1 * chore(release): publish - project: justweb3-efp-plugin 0.1.2 * chore(release): publish - project: justweb3-efp-plugin 0.1.3 * feat: console fixes * chore(release): publish - project: justweb3-efp-plugin 0.1.4 * feat: added docs and the sign in should only show ens set to default resolver or justaname resolver only * feat: add verbose to the test in ci * trial * trial * trial * trial * Trial (#42) * trial * trial * trial * trial * trial * fix: lint fix on react and package json of projects * fix: lint fix on react and package json of projects * Console (#43) * fix: naming app name * fix: packages * fix(console): deployment * fix: trial * fix(console): trial * trial * trial * trial * trial * trial * trial * trial --------- Co-authored-by: anthony2399 * fix: error from useEnsWalletClient * fix: update rest call and ui fixes * fix: console --------- Co-authored-by: HadiKhai Co-authored-by: JustHadi <35467011+HadiKhai@users.noreply.github.com> * chore(release): publish - project: @justaname.id/sdk 0.2.129 - project: @justaname.id/react 0.3.132 - project: @justaname.id/siwens 0.0.62 - project: @justweb3/ui 0.0.68 - project: @justweb3/widget 0.0.68 - project: @justverified/plugin 0.0.67 - project: @justweb3/efp-plugin 0.1.28 * chore(release): publish - project: @justaname.id/sdk 0.2.130 - project: @justaname.id/react 0.3.133 - project: @justaname.id/siwens 0.0.63 - project: @justweb3/ui 0.0.69 - project: @justweb3/widget 0.0.69 - project: @justverified/plugin 0.0.68 - project: @justweb3/efp-plugin 0.1.29 * chore(release): publish - project: @justaname.id/sdk 0.2.131 - project: @justaname.id/react 0.3.134 - project: @justaname.id/siwens 0.0.64 - project: @justweb3/ui 0.0.70 - project: @justweb3/widget 0.0.70 - project: @justverified/plugin 0.0.69 - project: @justweb3/efp-plugin 0.1.30 * chore(release): publish - project: @justaname.id/sdk 0.2.132 - project: @justaname.id/react 0.3.135 - project: @justaname.id/siwens 0.0.65 - project: @justweb3/ui 0.0.71 - project: @justweb3/widget 0.0.71 - project: @justverified/plugin 0.0.70 - project: @justweb3/efp-plugin 0.1.31 * chore(release): publish - project: @justaname.id/sdk 0.2.133 - project: @justaname.id/react 0.3.136 - project: @justaname.id/siwens 0.0.66 - project: @justweb3/ui 0.0.72 - project: @justweb3/widget 0.0.72 - project: @justverified/plugin 0.0.71 - project: @justweb3/efp-plugin 0.1.32 --------- Co-authored-by: JustHadi <35467011+HadiKhai@users.noreply.github.com> Co-authored-by: HadiKhai Co-authored-by: HadiKhai Co-authored-by: justaname-sdk-publisher[bot] Co-authored-by: anthony23991 * feat: dialog fixes and logo needs to be fixed * fixes * Anthony/console mobile (#53) * fixes * feat: console responsive * feat: query * feat: defaultOptions * fix: removed unused file * fix: scroll in mobile drawer --------- Co-authored-by: HadiKhai --------- Co-authored-by: Anthony Khoury Co-authored-by: HadiKhai Co-authored-by: justaname-sdk-publisher[bot] Co-authored-by: anthony23991 * feat: community members tab (#55) * Console (#58) * Develop (#48) * Console (#43) * fix: naming app name * fix: packages * fix(console): deployment * fix: trial * fix(console): trial * trial * trial * trial * trial * trial * trial * trial --------- Co-authored-by: anthony2399 * fix: error from useEnsWalletClient * Develop (#44) * feat: remove mapps from justverified * fix yarn.lock * fix * feat: efp * feat: efp and storybook for react sdk * chore(release): publish - project: justweb3-efp-plugin 0.1.0 * chore(release): publish - project: justweb3-efp-plugin 0.1.1 * chore(release): publish - project: justweb3-efp-plugin 0.1.2 * chore(release): publish - project: justweb3-efp-plugin 0.1.3 * feat: console fixes * chore(release): publish - project: justweb3-efp-plugin 0.1.4 * feat: added docs and the sign in should only show ens set to default resolver or justaname resolver only * feat: add verbose to the test in ci * trial * trial * trial * trial * Trial (#42) * trial * trial * trial * trial * trial * fix: lint fix on react and package json of projects * fix: lint fix on react and package json of projects * Console (#43) * fix: naming app name * fix: packages * fix(console): deployment * fix: trial * fix(console): trial * trial * trial * trial * trial * trial * trial * trial --------- Co-authored-by: anthony2399 * fix: error from useEnsWalletClient --------- Co-authored-by: anthony2399 * release * chore(release): publish - project: @justaname.id/sdk 0.2.125 - project: @justaname.id/react 0.3.128 - project: @justaname.id/siwens 0.0.58 - project: @justweb3/ui 0.0.64 - project: @justweb3/widget 0.0.64 - project: @justverified/plugin 0.0.63 - project: @justweb3/efp-plugin 0.1.24 * release * chore(release): publish - project: @justaname.id/sdk 0.2.126 - project: @justaname.id/react 0.3.129 - project: @justaname.id/siwens 0.0.59 - project: @justweb3/ui 0.0.65 - project: @justweb3/widget 0.0.65 - project: @justverified/plugin 0.0.64 - project: @justweb3/efp-plugin 0.1.25 * chore(release): publish - project: @justaname.id/sdk 0.2.127 - project: @justaname.id/react 0.3.130 - project: @justaname.id/siwens 0.0.60 - project: @justweb3/ui 0.0.66 - project: @justweb3/widget 0.0.66 - project: @justverified/plugin 0.0.65 - project: @justweb3/efp-plugin 0.1.26 * chore(release): publish - project: @justaname.id/sdk 0.2.128 - project: @justaname.id/react 0.3.131 - project: @justaname.id/siwens 0.0.61 - project: @justweb3/ui 0.0.67 - project: @justweb3/widget 0.0.67 - project: @justverified/plugin 0.0.66 - project: @justweb3/efp-plugin 0.1.27 * fix: update rest call and ui fixes * fix: console * Develop (#47) * feat: remove mapps from justverified * fix yarn.lock * fix * feat: efp * feat: efp and storybook for react sdk * chore(release): publish - project: justweb3-efp-plugin 0.1.0 * chore(release): publish - project: justweb3-efp-plugin 0.1.1 * chore(release): publish - project: justweb3-efp-plugin 0.1.2 * chore(release): publish - project: justweb3-efp-plugin 0.1.3 * feat: console fixes * chore(release): publish - project: justweb3-efp-plugin 0.1.4 * feat: added docs and the sign in should only show ens set to default resolver or justaname resolver only * feat: add verbose to the test in ci * trial * trial * trial * trial * Trial (#42) * trial * trial * trial * trial * trial * fix: lint fix on react and package json of projects * fix: lint fix on react and package json of projects * Console (#43) * fix: naming app name * fix: packages * fix(console): deployment * fix: trial * fix(console): trial * trial * trial * trial * trial * trial * trial * trial --------- Co-authored-by: anthony2399 * fix: error from useEnsWalletClient * fix: update rest call and ui fixes * fix: console --------- Co-authored-by: HadiKhai Co-authored-by: JustHadi <35467011+HadiKhai@users.noreply.github.com> * chore(release): publish - project: @justaname.id/sdk 0.2.129 - project: @justaname.id/react 0.3.132 - project: @justaname.id/siwens 0.0.62 - project: @justweb3/ui 0.0.68 - project: @justweb3/widget 0.0.68 - project: @justverified/plugin 0.0.67 - project: @justweb3/efp-plugin 0.1.28 * chore(release): publish - project: @justaname.id/sdk 0.2.130 - project: @justaname.id/react 0.3.133 - project: @justaname.id/siwens 0.0.63 - project: @justweb3/ui 0.0.69 - project: @justweb3/widget 0.0.69 - project: @justverified/plugin 0.0.68 - project: @justweb3/efp-plugin 0.1.29 * chore(release): publish - project: @justaname.id/sdk 0.2.131 - project: @justaname.id/react 0.3.134 - project: @justaname.id/siwens 0.0.64 - project: @justweb3/ui 0.0.70 - project: @justweb3/widget 0.0.70 - project: @justverified/plugin 0.0.69 - project: @justweb3/efp-plugin 0.1.30 * chore(release): publish - project: @justaname.id/sdk 0.2.132 - project: @justaname.id/react 0.3.135 - project: @justaname.id/siwens 0.0.65 - project: @justweb3/ui 0.0.71 - project: @justweb3/widget 0.0.71 - project: @justverified/plugin 0.0.70 - project: @justweb3/efp-plugin 0.1.31 * chore(release): publish - project: @justaname.id/sdk 0.2.133 - project: @justaname.id/react 0.3.136 - project: @justaname.id/siwens 0.0.66 - project: @justweb3/ui 0.0.72 - project: @justweb3/widget 0.0.72 - project: @justverified/plugin 0.0.71 - project: @justweb3/efp-plugin 0.1.32 --------- Co-authored-by: JustHadi <35467011+HadiKhai@users.noreply.github.com> Co-authored-by: HadiKhai Co-authored-by: HadiKhai Co-authored-by: justaname-sdk-publisher[bot] Co-authored-by: anthony23991 * feat: dialog fixes and logo needs to be fixed * Anthony/console mobile (#53) * fixes * feat: console responsive * feat: query * feat: defaultOptions * fix: removed unused file * fix: scroll in mobile drawer --------- Co-authored-by: HadiKhai --------- Co-authored-by: Anthony Khoury Co-authored-by: HadiKhai Co-authored-by: justaname-sdk-publisher[bot] Co-authored-by: anthony23991 * Hadi/coinbase fix (#59) * Develop (#48) * Console (#43) * fix: naming app name * fix: packages * fix(console): deployment * fix: trial * fix(console): trial * trial * trial * trial * trial * trial * trial * trial --------- Co-authored-by: anthony2399 * fix: error from useEnsWalletClient * Develop (#44) * feat: remove mapps from justverified * fix yarn.lock * fix * feat: efp * feat: efp and storybook for react sdk * chore(release): publish - project: justweb3-efp-plugin 0.1.0 * chore(release): publish - project: justweb3-efp-plugin 0.1.1 * chore(release): publish - project: justweb3-efp-plugin 0.1.2 * chore(release): publish - project: justweb3-efp-plugin 0.1.3 * feat: console fixes * chore(release): publish - project: justweb3-efp-plugin 0.1.4 * feat: added docs and the sign in should only show ens set to default resolver or justaname resolver only * feat: add verbose to the test in ci * trial * trial * trial * trial * Trial (#42) * trial * trial * trial * trial * trial * fix: lint fix on react and package json of projects * fix: lint fix on react and package json of projects * Console (#43) * fix: naming app name * fix: packages * fix(console): deployment * fix: trial * fix(console): trial * trial * trial * trial * trial * trial * trial * trial --------- Co-authored-by: anthony2399 * fix: error from useEnsWalletClient --------- Co-authored-by: anthony2399 * release * chore(release): publish - project: @justaname.id/sdk 0.2.125 - project: @justaname.id/react 0.3.128 - project: @justaname.id/siwens 0.0.58 - project: @justweb3/ui 0.0.64 - project: @justweb3/widget 0.0.64 - project: @justverified/plugin 0.0.63 - project: @justweb3/efp-plugin 0.1.24 * release * chore(release): publish - project: @justaname.id/sdk 0.2.126 - project: @justaname.id/react 0.3.129 - project: @justaname.id/siwens 0.0.59 - project: @justweb3/ui 0.0.65 - project: @justweb3/widget 0.0.65 - project: @justverified/plugin 0.0.64 - project: @justweb3/efp-plugin 0.1.25 * chore(release): publish - project: @justaname.id/sdk 0.2.127 - project: @justaname.id/react 0.3.130 - project: @justaname.id/siwens 0.0.60 - project: @justweb3/ui 0.0.66 - project: @justweb3/widget 0.0.66 - project: @justverified/plugin 0.0.65 - project: @justweb3/efp-plugin 0.1.26 * chore(release): publish - project: @justaname.id/sdk 0.2.128 - project: @justaname.id/react 0.3.131 - project: @justaname.id/siwens 0.0.61 - project: @justweb3/ui 0.0.67 - project: @justweb3/widget 0.0.67 - project: @justverified/plugin 0.0.66 - project: @justweb3/efp-plugin 0.1.27 * fix: update rest call and ui fixes * fix: console * Develop (#47) * feat: remove mapps from justverified * fix yarn.lock * fix * feat: efp * feat: efp and storybook for react sdk * chore(release): publish - project: justweb3-efp-plugin 0.1.0 * chore(release): publish - project: justweb3-efp-plugin 0.1.1 * chore(release): publish - project: justweb3-efp-plugin 0.1.2 * chore(release): publish - project: justweb3-efp-plugin 0.1.3 * feat: console fixes * chore(release): publish - project: justweb3-efp-plugin 0.1.4 * feat: added docs and the sign in should only show ens set to default resolver or justaname resolver only * feat: add verbose to the test in ci * trial * trial * trial * trial * Trial (#42) * trial * trial * trial * trial * trial * fix: lint fix on react and package json of projects * fix: lint fix on react and package json of projects * Console (#43) * fix: naming app name * fix: packages * fix(console): deployment * fix: trial * fix(console): trial * trial * trial * trial * trial * trial * trial * trial --------- Co-authored-by: anthony2399 * fix: error from useEnsWalletClient * fix: update rest call and ui fixes * fix: console --------- Co-authored-by: HadiKhai Co-authored-by: JustHadi <35467011+HadiKhai@users.noreply.github.com> * chore(release): publish - project: @justaname.id/sdk 0.2.129 - project: @justaname.id/react 0.3.132 - project: @justaname.id/siwens 0.0.62 - project: @justweb3/ui 0.0.68 - project: @justweb3/widget 0.0.68 - project: @justverified/plugin 0.0.67 - project: @justweb3/efp-plugin 0.1.28 * chore(release): publish - project: @justaname.id/sdk 0.2.130 - project: @justaname.id/react 0.3.133 - project: @justaname.id/siwens 0.0.63 - project: @justweb3/ui 0.0.69 - project: @justweb3/widget 0.0.69 - project: @justverified/plugin 0.0.68 - project: @justweb3/efp-plugin 0.1.29 * chore(release): publish - project: @justaname.id/sdk 0.2.131 - project: @justaname.id/react 0.3.134 - project: @justaname.id/siwens 0.0.64 - project: @justweb3/ui 0.0.70 - project: @justweb3/widget 0.0.70 - project: @justverified/plugin 0.0.69 - project: @justweb3/efp-plugin 0.1.30 * chore(release): publish - project: @justaname.id/sdk 0.2.132 - project: @justaname.id/react 0.3.135 - project: @justaname.id/siwens 0.0.65 - project: @justweb3/ui 0.0.71 - project: @justweb3/widget 0.0.71 - project: @justverified/plugin 0.0.70 - project: @justweb3/efp-plugin 0.1.31 * chore(release): publish - project: @justaname.id/sdk 0.2.133 - project: @justaname.id/react 0.3.136 - project: @justaname.id/siwens 0.0.66 - project: @justweb3/ui 0.0.72 - project: @justweb3/widget 0.0.72 - project: @justverified/plugin 0.0.71 - project: @justweb3/efp-plugin 0.1.32 --------- Co-authored-by: JustHadi <35467011+HadiKhai@users.noreply.github.com> Co-authored-by: HadiKhai Co-authored-by: HadiKhai Co-authored-by: justaname-sdk-publisher[bot] Co-authored-by: anthony23991 * feat: dialog fixes and logo needs to be fixed * Anthony/console mobile (#53) * fixes * feat: console responsive * feat: query * feat: defaultOptions * fix: removed unused file * fix: scroll in mobile drawer --------- Co-authored-by: HadiKhai * fix: signature for coinbase wallet and popups --------- Co-authored-by: Anthony Khoury Co-authored-by: HadiKhai Co-authored-by: justaname-sdk-publisher[bot] Co-authored-by: anthony23991 * Console (#60) * Develop (#48) * Console (#43) * fix: naming app name * fix: packages * fix(console): deployment * fix: trial * fix(console): trial * trial * trial * trial * trial * trial * trial * trial --------- Co-authored-by: anthony2399 * fix: error from useEnsWalletClient * Develop (#44) * feat: remove mapps from justverified * fix yarn.lock * fix * feat: efp * feat: efp and storybook for react sdk * chore(release): publish - project: justweb3-efp-plugin 0.1.0 * chore(release): publish - project: justweb3-efp-plugin 0.1.1 * chore(release): publish - project: justweb3-efp-plugin 0.1.2 * chore(release): publish - project: justweb3-efp-plugin 0.1.3 * feat: console fixes * chore(release): publish - project: justweb3-efp-plugin 0.1.4 * feat: added docs and the sign in should only show ens set to default resolver or justaname resolver only * feat: add verbose to the test in ci * trial * trial * trial * trial * Trial (#42) * trial * trial * trial * trial * trial * fix: lint fix on react and package json of projects * fix: lint fix on react and package json of projects * Console (#43) * fix: naming app name * fix: packages * fix(console): deployment * fix: trial * fix(console): trial * trial * trial * trial * trial * trial * trial * trial --------- Co-authored-by: anthony2399 * fix: error from useEnsWalletClient --------- Co-authored-by: anthony2399 * release * chore(release): publish - project: @justaname.id/sdk 0.2.125 - project: @justaname.id/react 0.3.128 - project: @justaname.id/siwens 0.0.58 - project: @justweb3/ui 0.0.64 - project: @justweb3/widget 0.0.64 - project: @justverified/plugin 0.0.63 - project: @justweb3/efp-plugin 0.1.24 * release * chore(release): publish - project: @justaname.id/sdk 0.2.126 - project: @justaname.id/react 0.3.129 - project: @justaname.id/siwens 0.0.59 - project: @justweb3/ui 0.0.65 - project: @justweb3/widget 0.0.65 - project: @justverified/plugin 0.0.64 - project: @justweb3/efp-plugin 0.1.25 * chore(release): publish - project: @justaname.id/sdk 0.2.127 - project: @justaname.id/react 0.3.130 - project: @justaname.id/siwens 0.0.60 - project: @justweb3/ui 0.0.66 - project: @justweb3/widget 0.0.66 - project: @justverified/plugin 0.0.65 - project: @justweb3/efp-plugin 0.1.26 * chore(release): publish - project: @justaname.id/sdk 0.2.128 - project: @justaname.id/react 0.3.131 - project: @justaname.id/siwens 0.0.61 - project: @justweb3/ui 0.0.67 - project: @justweb3/widget 0.0.67 - project: @justverified/plugin 0.0.66 - project: @justweb3/efp-plugin 0.1.27 * fix: update rest call and ui fixes * fix: console * Develop (#47) * feat: remove mapps from justverified * fix yarn.lock * fix * feat: efp * feat: efp and storybook for react sdk * chore(release): publish - project: justweb3-efp-plugin 0.1.0 * chore(release): publish - project: justweb3-efp-plugin 0.1.1 * chore(release): publish - project: justweb3-efp-plugin 0.1.2 * chore(release): publish - project: justweb3-efp-plugin 0.1.3 * feat: console fixes * chore(release): publish - project: justweb3-efp-plugin 0.1.4 * feat: added docs and the sign in should only show ens set to default resolver or justaname resolver only * feat: add verbose to the test in ci * trial * trial * trial * trial * Trial (#42) * trial * trial * trial * trial * trial * fix: lint fix on react and package json of projects * fix: lint fix on react and package json of projects * Console (#43) * fix: naming app name * fix: packages * fix(console): deployment * fix: trial * fix(console): trial * trial * trial * trial * trial * trial * trial * trial --------- Co-authored-by: anthony2399 * fix: error from useEnsWalletClient * fix: update rest call and ui fixes * fix: console --------- Co-authored-by: HadiKhai Co-authored-by: JustHadi <35467011+HadiKhai@users.noreply.github.com> * chore(release): publish - project: @justaname.id/sdk 0.2.129 - project: @justaname.id/react 0.3.132 - project: @justaname.id/siwens 0.0.62 - project: @justweb3/ui 0.0.68 - project: @justweb3/widget 0.0.68 - project: @justverified/plugin 0.0.67 - project: @justweb3/efp-plugin 0.1.28 * chore(release): publish - project: @justaname.id/sdk 0.2.130 - project: @justaname.id/react 0.3.133 - project: @justaname.id/siwens 0.0.63 - project: @justweb3/ui 0.0.69 - project: @justweb3/widget 0.0.69 - project: @justverified/plugin 0.0.68 - project: @justweb3/efp-plugin 0.1.29 * chore(release): publish - project: @justaname.id/sdk 0.2.131 - project: @justaname.id/react 0.3.134 - project: @justaname.id/siwens 0.0.64 - project: @justweb3/ui 0.0.70 - project: @justweb3/widget 0.0.70 - project: @justverified/plugin 0.0.69 - project: @justweb3/efp-plugin 0.1.30 * chore(release): publish - project: @justaname.id/sdk 0.2.132 - project: @justaname.id/react 0.3.135 - project: @justaname.id/siwens 0.0.65 - project: @justweb3/ui 0.0.71 - project: @justweb3/widget 0.0.71 - project: @justverified/plugin 0.0.70 - project: @justweb3/efp-plugin 0.1.31 * chore(release): publish - project: @justaname.id/sdk 0.2.133 - project: @justaname.id/react 0.3.136 - project: @justaname.id/siwens 0.0.66 - project: @justweb3/ui 0.0.72 - project: @justweb3/widget 0.0.72 - project: @justverified/plugin 0.0.71 - project: @justweb3/efp-plugin 0.1.32 --------- Co-authored-by: JustHadi <35467011+HadiKhai@users.noreply.github.com> Co-authored-by: HadiKhai Co-authored-by: HadiKhai Co-authored-by: justaname-sdk-publisher[bot] Co-authored-by: anthony23991 * feat: dialog fixes and logo needs to be fixed * Anthony/console mobile (#53) * fixes * feat: console responsive * feat: query * feat: defaultOptions * fix: removed unused file * fix: scroll in mobile drawer --------- Co-authored-by: HadiKhai * fixes (#57) --------- Co-authored-by: Anthony Khoury Co-authored-by: HadiKhai Co-authored-by: justaname-sdk-publisher[bot] Co-authored-by: anthony23991 --------- Co-authored-by: Anthony Khoury Co-authored-by: HadiKhai Co-authored-by: justaname-sdk-publisher[bot] Co-authored-by: anthony23991 --- .../customizer/ClaimSection/index.tsx | 40 ++++-- demo/server/src/main.ts | 4 +- .../react/src/lib/hooks/signIn/useEnsNonce.ts | 71 ++++++++++ .../src/lib/hooks/signIn/useEnsSignIn.ts | 86 ++++++------ .../src/lib/hooks/signIn/useEnsSignOut.ts | 16 ++- .../lib/hooks/uploadMedia/useUploadMedia.ts | 6 +- .../src/lib/providers/JustaNameProvider.tsx | 2 +- .../sdk/src/lib/api/axiosController.ts | 1 + .../lib/errors/ChallengeRequest.expection.ts | 40 ++++++ .../errors/InvalidConfiguration.exception.ts | 20 ++- .../lib/features/subname-challenge/index.ts | 73 ++++++++-- .../sdk/src/lib/features/subnames/index.ts | 130 +++++++++++++++--- .../sdk/src/lib/types/headers/index.ts | 6 +- .../lib/types/mApps/add-mApp-permission.ts | 6 +- .../lib/types/mApps/revoke-mApp-permission.ts | 7 +- .../sdk/src/lib/types/signin/index.ts | 23 ++-- .../src/lib/types/siwe/verify-challenge.ts | 9 +- .../sdk/src/lib/types/subnames/accept.ts | 27 ++-- .../sdk/src/lib/types/subnames/add.ts | 2 + .../sdk/src/lib/types/subnames/reject.ts | 11 +- .../sdk/src/lib/types/subnames/revoke.ts | 2 + .../sdk/src/lib/types/subnames/update.ts | 33 +++-- .../src/test/integration/justaname.spec.ts | 29 ++-- .../components/EmailCredentialItem/index.tsx | 2 +- .../providers/JustVerifiedProvider/index.tsx | 1 + .../ClickableItem/ClickableItem.module.css | 68 ++++----- .../lib/icons/components/general/Avatar.tsx | 31 +++++ .../lib/icons/components/general/Banner.tsx | 18 +++ .../lib/icons/components/general/Nickname.tsx | 31 +++++ .../src/lib/icons/components/general/index.ts | 9 ++ .../ui/src/lib/icons/svgs/general/avatar.svg | 10 ++ .../ui/src/lib/icons/svgs/general/banner.svg | 5 + .../src/lib/icons/svgs/general/nickname.svg | 10 ++ .../JustEnsCard/JustEnsCard.module.css | 76 ++++++---- .../src/lib/components/JustEnsCard/index.tsx | 53 ++++++- .../lib/components/JustWeb3Button/index.tsx | 73 +++++----- .../Profile/ContentSection/index.tsx | 18 ++- .../MembersSection/MembersSection.module.css | 40 ++++++ .../Profile/MembersSection/index.tsx | 77 +++++++++++ .../src/lib/dialogs/SignInDialog/index.tsx | 11 +- .../src/lib/icons/records-icons/index.tsx | 14 +- .../lib/providers/JustWeb3Provider/index.tsx | 6 +- .../widget/src/stories/signin2.stories.tsx | 5 +- 43 files changed, 927 insertions(+), 275 deletions(-) create mode 100644 packages/@justaname.id/react/src/lib/hooks/signIn/useEnsNonce.ts create mode 100644 packages/@justaname.id/sdk/src/lib/errors/ChallengeRequest.expection.ts create mode 100644 packages/@justweb3/ui/src/lib/icons/components/general/Avatar.tsx create mode 100644 packages/@justweb3/ui/src/lib/icons/components/general/Banner.tsx create mode 100644 packages/@justweb3/ui/src/lib/icons/components/general/Nickname.tsx create mode 100644 packages/@justweb3/ui/src/lib/icons/svgs/general/avatar.svg create mode 100644 packages/@justweb3/ui/src/lib/icons/svgs/general/banner.svg create mode 100644 packages/@justweb3/ui/src/lib/icons/svgs/general/nickname.svg create mode 100644 packages/@justweb3/widget/src/lib/components/Profile/MembersSection/MembersSection.module.css create mode 100644 packages/@justweb3/widget/src/lib/components/Profile/MembersSection/index.tsx diff --git a/apps/console/src/components/sections/customizer/ClaimSection/index.tsx b/apps/console/src/components/sections/customizer/ClaimSection/index.tsx index ebeecdba..341f6bdd 100644 --- a/apps/console/src/components/sections/customizer/ClaimSection/index.tsx +++ b/apps/console/src/components/sections/customizer/ClaimSection/index.tsx @@ -93,7 +93,6 @@ export const ClaimSection = () => { setEnsByApiKey(res.data.result.data.domains); }) .catch((err) => { - console.log(err); setEnsByApiKey([]); handleEnsSelect(defaultTestnetValue, 11155111); handleEnsSelect(defaultMainnetValue, 1); @@ -123,18 +122,39 @@ export const ClaimSection = () => { onChange={(e) => setApiKey(e.target.value)} placeholder="Justaname API Key" rightIcon={ - + - - + + - + diff --git a/demo/server/src/main.ts b/demo/server/src/main.ts index 1d06195b..b3d71883 100644 --- a/demo/server/src/main.ts +++ b/demo/server/src/main.ts @@ -150,9 +150,9 @@ app.post('/api/subnames/add', async (req: Request, res) => { text: text, addresses: addresses, contentHash, + signature: req.body.signature, }, { - xSignature: req.body.signature, xAddress: req.body.address, xMessage: req.body.message, } @@ -187,9 +187,9 @@ app.post('/api/subnames/revoke', async (req: Request, res) => { { username, ensDomain, + signature: req.body.signature, }, { - xSignature: req.body.signature, xAddress: req.body.address, xMessage: req.body.message, } diff --git a/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsNonce.ts b/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsNonce.ts new file mode 100644 index 00000000..33564c92 --- /dev/null +++ b/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsNonce.ts @@ -0,0 +1,71 @@ +import { useMemo } from 'react'; +import { useJustaName } from '../../providers'; +import { useQuery } from '@tanstack/react-query'; +import { defaultOptions } from '../../query'; + +export const buildNonceKey = ( + backendUrl: string, + route: string, + address: string +) => ['ENS_NONCE', backendUrl, route, address]; + +export interface UseEnsNonceParams { + signinNonceRoute?: string; + backendUrl?: string; + address?: string; +} + +export interface UseEnsNonceResult { + nonce: string | undefined; + refetchNonce: () => void; + isNoncePending: boolean; + isNonceLoading: boolean; + isNonceFetching: boolean; +} + +export const useEnsNonce = (params?: UseEnsNonceParams): UseEnsNonceResult => { + const { backendUrl, routes } = useJustaName(); + + const _backendUrl = useMemo( + () => params?.backendUrl || backendUrl || '', + [backendUrl, params?.backendUrl] + ); + const _signinNonceRoute = useMemo( + () => params?.signinNonceRoute || routes.signinNonceRoute, + [routes.signinNonceRoute, params?.signinNonceRoute] + ); + const nonceEndpoint = useMemo( + () => _backendUrl + _signinNonceRoute, + [_backendUrl, _signinNonceRoute] + ); + + const query = useQuery({ + ...defaultOptions, + staleTime: Infinity, + queryKey: buildNonceKey( + _backendUrl, + _signinNonceRoute, + params?.address || '' + ), + queryFn: async () => { + const nonceResponse = await fetch(nonceEndpoint, { + credentials: 'include', + }); + + if (!nonceResponse.ok) { + throw new Error('Failed to fetch nonce'); + } + + return nonceResponse.text(); + }, + enabled: Boolean(params?.address), + }); + + return { + nonce: query.data, + refetchNonce: query.refetch, + isNoncePending: query.isFetching, + isNonceLoading: query.isLoading, + isNonceFetching: query.isFetching, + }; +}; diff --git a/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsSignIn.ts b/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsSignIn.ts index 7bb2cc9d..9184d4df 100644 --- a/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsSignIn.ts +++ b/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsSignIn.ts @@ -7,6 +7,7 @@ import { useJustaName } from '../../providers'; import { useSignMessage } from 'wagmi'; import { RequestSignInParams } from '@justaname.id/sdk'; import { useEnsAuth } from './useEnsAuth'; +import { useEnsNonce } from './useEnsNonce'; export type UseEnsSignInFunctionParams = Omit< RequestSignInParams, @@ -41,18 +42,12 @@ export const useEnsSignIn = ( () => params?.backendUrl || backendUrl || '', [backendUrl, params?.backendUrl] ); - const _signinNonceRoute = useMemo( - () => params?.signinNonceRoute || routes.signinNonceRoute, - [routes.signinNonceRoute, params?.signinNonceRoute] - ); + const _signinRoute = useMemo( () => params?.signinRoute || routes.signinRoute, [routes.signinRoute, params?.signinRoute] ); - const nonceEndpoint = useMemo( - () => _backendUrl + _signinNonceRoute, - [_backendUrl, _signinNonceRoute] - ); + const signinEndpoint = useMemo( () => _backendUrl + _signinRoute, [_backendUrl, _signinRoute] @@ -66,48 +61,57 @@ export const useEnsSignIn = ( currentEnsRoute: _currentEnsRoute, }); + const { nonce, refetchNonce } = useEnsNonce({ + backendUrl: params?.backendUrl, + signinNonceRoute: params?.signinNonceRoute, + address, + }); + const mutation = useMutation({ mutationFn: async (_params: UseEnsSignInFunctionParams) => { if (!address) { throw new Error('No address found'); } - const nonceResponse = await fetch(nonceEndpoint, { - credentials: 'include', - }); - - const nonce = await nonceResponse.text(); - - const message = justaname.signIn.requestSignIn({ - ens: _params.ens, - ttl: config?.signInTtl, - uri: config?.origin, - domain: config?.domain, - chainId: chainId, - address, - nonce, - }); - - const signature = await signMessageAsync({ - message: message, - account: address, - }); - - const response = await fetch(signinEndpoint, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - signature: signature, + if (!nonce) { + throw new Error('No nonce found'); + } + + try { + const message = justaname.signIn.requestSignIn({ + ens: _params.ens, + ttl: config?.signInTtl, + uri: config?.origin, + domain: config?.domain, + chainId: chainId, + address, + nonce, + }); + + const signature = await signMessageAsync({ message: message, - }), - credentials: 'include', - }); + account: address, + }); - refreshEnsAuth(); + const response = await fetch(signinEndpoint, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + signature: signature, + message: message, + }), + credentials: 'include', + }); - return response.text(); + refreshEnsAuth(); + + return response.text(); + } catch (e) { + refetchNonce(); + throw e; + } }, }); diff --git a/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsSignOut.ts b/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsSignOut.ts index 3b0811b8..085fbf29 100644 --- a/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsSignOut.ts +++ b/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsSignOut.ts @@ -4,6 +4,7 @@ import { useMemo } from 'react'; import { useMutation } from '@tanstack/react-query'; import { useJustaName } from '../../providers'; import { useEnsAuth } from './useEnsAuth'; +import { useEnsNonce } from './useEnsNonce'; export interface UseEnsSignOutResult { signOut: () => Promise; @@ -14,6 +15,7 @@ export interface UseEnsSignOutParams { backendUrl?: string; signoutRoute?: string; currentEnsRoute?: string; + signinNonceRoute?: string; } export const useEnsSignOut = ( @@ -36,11 +38,22 @@ export const useEnsSignOut = ( () => params?.currentEnsRoute || routes.currentEnsRoute, [routes.currentEnsRoute, params?.currentEnsRoute] ); - const { refreshEnsAuth } = useEnsAuth({ + const _signinNonceRoute = useMemo( + () => params?.signinNonceRoute || routes.signinNonceRoute, + [routes.signinNonceRoute, params?.signinNonceRoute] + ); + + const { refreshEnsAuth, connectedEns } = useEnsAuth({ backendUrl: _backendUrl, currentEnsRoute: _currentEnsRoute, }); + const { refetchNonce } = useEnsNonce({ + backendUrl: _backendUrl, + signinNonceRoute: _signinNonceRoute, + address: connectedEns?.address, + }); + const mutation = useMutation({ mutationFn: async () => { await fetch(signoutEndpoint, { @@ -49,6 +62,7 @@ export const useEnsSignOut = ( }); refreshEnsAuth(); + refetchNonce(); }, }); diff --git a/packages/@justaname.id/react/src/lib/hooks/uploadMedia/useUploadMedia.ts b/packages/@justaname.id/react/src/lib/hooks/uploadMedia/useUploadMedia.ts index 13984dbe..9cb383d1 100644 --- a/packages/@justaname.id/react/src/lib/hooks/uploadMedia/useUploadMedia.ts +++ b/packages/@justaname.id/react/src/lib/hooks/uploadMedia/useUploadMedia.ts @@ -65,9 +65,12 @@ export const useUploadMedia = ( } const { signature, message, address } = await getSignature(); + + _params.form.append('signature', signature); + // const baseUrl = 'http://localhost:3000'; const baseUrl = dev ? 'https://api-staging.justaname.id' - : 'https://api.justaname.id'; + : 'http://localhost:3000'; const result = await axios.post<{ result: { data: { @@ -83,7 +86,6 @@ export const useUploadMedia = ( _params.form, { headers: { - 'x-signature': signature, 'x-message': message.replace(/\n/g, '\\n'), 'x-address': address, }, diff --git a/packages/@justaname.id/react/src/lib/providers/JustaNameProvider.tsx b/packages/@justaname.id/react/src/lib/providers/JustaNameProvider.tsx index f299818f..2b49b9cb 100644 --- a/packages/@justaname.id/react/src/lib/providers/JustaNameProvider.tsx +++ b/packages/@justaname.id/react/src/lib/providers/JustaNameProvider.tsx @@ -187,7 +187,7 @@ export const useSubnameSignature = (): UseSubnameSignatureResult => { throw new Error('No chainId found'); } - const message = await justaname.siwe.requestChallenge({ + const message = justaname.siwe.requestChallenge({ address, chainId, }); diff --git a/packages/@justaname.id/sdk/src/lib/api/axiosController.ts b/packages/@justaname.id/sdk/src/lib/api/axiosController.ts index 8f3270df..4e84ddc5 100644 --- a/packages/@justaname.id/sdk/src/lib/api/axiosController.ts +++ b/packages/@justaname.id/sdk/src/lib/api/axiosController.ts @@ -2,6 +2,7 @@ import axios, { AxiosError, AxiosPromise } from 'axios'; import { BaseResponse } from '../types'; export function getBaseUrl(dev = false) { + // return 'http://localhost:3000'; if (dev) { return 'https://api-staging.justaname.id'; } diff --git a/packages/@justaname.id/sdk/src/lib/errors/ChallengeRequest.expection.ts b/packages/@justaname.id/sdk/src/lib/errors/ChallengeRequest.expection.ts new file mode 100644 index 00000000..51dc680a --- /dev/null +++ b/packages/@justaname.id/sdk/src/lib/errors/ChallengeRequest.expection.ts @@ -0,0 +1,40 @@ +export class ChallengeRequestException extends Error { + constructor(message: string) { + super(message); + } + + static invalidTimeValue(): ChallengeRequestException { + const message = 'ChallengeRequestException: Invalid time value'; + return new ChallengeRequestException(message); + } + + static invalidOrigin(origin: string): ChallengeRequestException { + const message = `ChallengeRequestException: Invalid origin: ${origin}`; + return new ChallengeRequestException(message); + } + + static domainRequired(): ChallengeRequestException { + const message = 'ChallengeRequestException: Domain is required'; + return new ChallengeRequestException(message); + } + + static invalidChainId(chainId: number): ChallengeRequestException { + const message = `ChallengeRequestException: Invalid chainId: ${chainId}, only 1 and 11155111 are supported`; + return new ChallengeRequestException(message); + } + + static originRequired(): ChallengeRequestException { + const message = 'ChallengeRequestException: Origin is required'; + return new ChallengeRequestException(message); + } + + static invalidAddress(address: string): ChallengeRequestException { + const message = `ChallengeRequestException: Invalid address: ${address}`; + return new ChallengeRequestException(message); + } + + static generatingChallengeFailed(): ChallengeRequestException { + const message = 'ChallengeRequestException: Generating challenge failed'; + return new ChallengeRequestException(message); + } +} diff --git a/packages/@justaname.id/sdk/src/lib/errors/InvalidConfiguration.exception.ts b/packages/@justaname.id/sdk/src/lib/errors/InvalidConfiguration.exception.ts index 3a528a17..ae8d0aac 100644 --- a/packages/@justaname.id/sdk/src/lib/errors/InvalidConfiguration.exception.ts +++ b/packages/@justaname.id/sdk/src/lib/errors/InvalidConfiguration.exception.ts @@ -5,10 +5,24 @@ export class InvalidConfigurationException extends Error { } static missingParameters(parameters: string[]) { - return new InvalidConfigurationException(`Missing parameters: ${parameters.join(', ')}, please provide them in the configuration or in the function parameters`); + return new InvalidConfigurationException( + `Missing parameters: ${parameters.join( + ', ' + )}, please provide them in the configuration or in the function parameters` + ); } static missingHeaders(headers: string[]) { - return new InvalidConfigurationException(`Missing headers: ${headers.join(', ')}, please provide them in the configuration or in the function parameters`); + return new InvalidConfigurationException( + `Missing headers: ${headers.join( + ', ' + )}, please provide them in the configuration or in the function parameters` + ); } -} \ No newline at end of file + + static missingParameterOrHeader(parameterOrHeader: string) { + return new InvalidConfigurationException( + `Missing parameter or header: ${parameterOrHeader}, please provide them in the headers or in the function parameters` + ); + } +} diff --git a/packages/@justaname.id/sdk/src/lib/features/subname-challenge/index.ts b/packages/@justaname.id/sdk/src/lib/features/subname-challenge/index.ts index 90905b87..f1aa62d0 100644 --- a/packages/@justaname.id/sdk/src/lib/features/subname-challenge/index.ts +++ b/packages/@justaname.id/sdk/src/lib/features/subname-challenge/index.ts @@ -5,6 +5,8 @@ import { VerifyMessageRoute, } from '../../types'; import { SiweConfig } from '../../types/siwe/siwe-config'; +import { ChallengeRequestException } from '../../errors/ChallengeRequest.expection'; +import { SiweMessage } from 'siwe'; /** * Represents the Sign-In with Ethereum (SIWE) functionality, providing methods @@ -63,20 +65,59 @@ export class SubnameChallenge { */ requestChallenge( params: RequestChallengeRoute['params'] - ): Promise { - const { chainId, ttl, origin, domain, ...rest } = params; - const _ttl = this.subnameChallengeTtl || ttl || 120000; - const _chainId = this.chainId || chainId; + ): RequestChallengeRoute['response'] { + const { chainId, ttl, origin, domain, address } = params; + const _ttl = ttl || this.subnameChallengeTtl || 120000; + const _chainId = chainId || this.chainId; const _origin = this.siweConfig?.origin || origin; const _domain = this.siweConfig?.domain || domain; + const _address = address; - return assertRestCall('SIWE_REQUEST_CHALLENGE_ROUTE', 'POST', { - ttl: _ttl, - chainId: _chainId, - origin: _origin, + if (!_origin) { + throw ChallengeRequestException.originRequired(); + } + + if (!_domain) { + throw ChallengeRequestException.domainRequired(); + } + + if (_chainId !== 1 && _chainId !== 11155111) { + throw ChallengeRequestException.invalidChainId(_chainId); + } + + if (_ttl <= 0 || _ttl + Date.now() >= Number.MAX_SAFE_INTEGER) { + throw ChallengeRequestException.invalidTimeValue(); + } + + const urlRegex = new RegExp('^(http|https)://', 'i'); + if (!urlRegex.test(_origin)) { + throw ChallengeRequestException.invalidOrigin(_origin); + } + + const ethAddressRegex = new RegExp('^0x[a-fA-F0-9]{40}$'); + if (!ethAddressRegex.test(_address)) { + throw ChallengeRequestException.invalidAddress(_address); + } + + const statement = `Please sign this message to verify that you want to add/update your subdomain provided by ${_domain} to your account ${_address} using JustAName`; + + const { expirationTime, issuedAt } = + this.generateIssuedAndExpirationTime(_ttl); + + const siweMessage = new SiweMessage({ domain: _domain, - ...rest, - }, undefined , this.dev)(['origin', 'domain', 'chainId']); + uri: _origin, + address: _address, + statement: statement, + chainId: _chainId, + version: '1', + issuedAt, + expirationTime, + }); + + return { + challenge: siweMessage.prepareMessage(), + }; } /** @@ -92,8 +133,18 @@ export class SubnameChallenge { 'SIWE_VERIFY_MESSAGE_ROUTE', 'POST', params, - undefined , + undefined, this.dev )(['address', 'signature', 'message']); } + + private generateIssuedAndExpirationTime(ttl: number) { + const date = new Date(); + const issuedAt = date.toISOString(); + const expirationTime = new Date(date.getTime() + ttl).toISOString(); + return { + issuedAt, + expirationTime, + }; + } } diff --git a/packages/@justaname.id/sdk/src/lib/features/subnames/index.ts b/packages/@justaname.id/sdk/src/lib/features/subnames/index.ts index 5f605f92..12df85ed 100644 --- a/packages/@justaname.id/sdk/src/lib/features/subnames/index.ts +++ b/packages/@justaname.id/sdk/src/lib/features/subnames/index.ts @@ -20,6 +20,7 @@ import { } from '../../types'; import { sanitizeAddresses, sanitizeTexts } from '../../utils'; import { PrimaryNameGetByAddressRoute } from '../../types/primary-name'; +import { InvalidConfigurationException } from '../../errors'; export interface SubnamesConfig { /** @@ -66,7 +67,20 @@ export class Subnames { params: SubnameAcceptRoute['params'], headers: SubnameAcceptRoute['headers'] ): Promise { - const { text, addresses, ensDomain, chainId, ...rest } = params; + const { + text, + addresses, + ensDomain, + chainId, + signature: paramSignature, + ...rest + } = params; + + const { signature, xSignature } = this.checkSignature( + paramSignature, + headers.xSignature + ); + const sanitizedAddresses = sanitizeAddresses(params.addresses); const hasAddress60 = sanitizedAddresses?.some( (address) => address.coinType === 60 @@ -95,14 +109,14 @@ export class Subnames { ...(sanitizedAddresses === undefined ? [] : sanitizedAddresses), ], ...rest, + signature, + }, + { + ...headers, + xSignature, }, - - headers, this.dev - )( - ['username', 'ensDomain', 'chainId'], - ['xSignature', 'xMessage', 'xAddress'] - ); + )(['username', 'ensDomain', 'chainId'], ['xMessage', 'xAddress']); } async reserveSubname( @@ -138,7 +152,21 @@ export class Subnames { params: SubnameAddRoute['params'], headers: SubnameAddRoute['headers'] ): Promise { - const { text, addresses, ensDomain, chainId, apiKey, ...rest } = params; + const { + text, + addresses, + ensDomain, + chainId, + apiKey, + signature: paramSignature, + ...rest + } = params; + + const { signature, xSignature } = this.checkSignature( + paramSignature, + headers.xSignature + ); + const sanitizedAddresses = sanitizeAddresses(params.addresses); const hasAddress60 = sanitizedAddresses?.some( (address) => address.coinType === 60 @@ -173,15 +201,17 @@ export class Subnames { ...(sanitizedAddresses === undefined ? [] : sanitizedAddresses), ], ...rest, + signature, }, { ...headers, + xSignature, xApiKey: _apiKey, }, this.dev )( ['username', 'ensDomain', 'chainId'], - ['xApiKey', 'xAddress', 'xMessage', 'xSignature'] + ['xApiKey', 'xAddress', 'xMessage'] ); } @@ -189,7 +219,20 @@ export class Subnames { params: SubnameUpdateRoute['params'], headers: SubnameUpdateRoute['headers'] ): Promise { - const { text, addresses, ensDomain, chainId, ...rest } = params; + const { + text, + addresses, + ensDomain, + chainId, + signature: paramSignature, + ...rest + } = params; + + const { signature, xSignature } = this.checkSignature( + paramSignature, + headers.xSignature + ); + const _chainId = chainId || this.chainId; const _ensDomain = ensDomain || @@ -205,23 +248,35 @@ export class Subnames { text: sanitizeTexts(params.text), addresses: sanitizeAddresses(params.addresses), ...rest, + signature, }, { ...headers, + xSignature, }, this.dev - )( - ['username', 'ensDomain', 'chainId'], - ['xSignature', 'xMessage', 'xAddress'] - ); + )(['username', 'ensDomain', 'chainId'], ['xMessage', 'xAddress']); } async revokeSubname( params: SubnameRevokeRoute['params'], headers: SubnameRevokeRoute['headers'] ): Promise { - const { ensDomain, chainId, apiKey, ...rest } = params; + const { + ensDomain, + chainId, + apiKey, + signature: paramSignature, + ...rest + } = params; + + const { signature, xSignature } = this.checkSignature( + paramSignature, + headers.xSignature + ); + const _chainId = chainId || this.chainId; + const _ensDomain = ensDomain || this.ensDomains?.find((ensDomain) => ensDomain.chainId === _chainId) @@ -239,15 +294,17 @@ export class Subnames { chainId: _chainId, ensDomain: _ensDomain, ...rest, + signature, }, { ...headers, xApiKey: _apiKey, + xSignature, }, this.dev )( ['username', 'ensDomain', 'chainId'], - ['xApiKey', 'xAddress', 'xMessage', 'xSignature'] + ['xApiKey', 'xAddress', 'xMessage'] ); } @@ -255,7 +312,13 @@ export class Subnames { params: SubnameRejectRoute['params'], headers: SubnameRejectRoute['headers'] ): Promise { - const { ensDomain, chainId, username } = params; + const { ensDomain, chainId, username, signature: paramSignature } = params; + + const { signature, xSignature } = this.checkSignature( + paramSignature, + headers.xSignature + ); + const _chainId = chainId || this.chainId; const _ensDomain = ensDomain || @@ -269,15 +332,14 @@ export class Subnames { chainId: _chainId, ensDomain: _ensDomain, username, + signature, }, { ...headers, + xSignature, }, this.dev - )( - ['username', 'ensDomain', 'chainId'], - ['xSignature', 'xMessage', 'xAddress'] - ); + )(['username', 'ensDomain', 'chainId'], ['xMessage', 'xAddress']); } async getSubnamesByEnsDomainWithCount( @@ -452,4 +514,30 @@ export class Subnames { this.dev )(['chainId']); } + + private checkSignature( + params: string | undefined, + headers: string | undefined + ): { + signature: string | undefined; + xSignature: string | undefined; + } { + const signature = params || headers; + + if (!signature) { + throw InvalidConfigurationException.missingParameterOrHeader('signature'); + } + + if (signature.length > 15000) { + return { + signature, + xSignature: undefined, + }; + } + + return { + signature: undefined, + xSignature: signature, + }; + } } diff --git a/packages/@justaname.id/sdk/src/lib/types/headers/index.ts b/packages/@justaname.id/sdk/src/lib/types/headers/index.ts index 7da9e30d..33c1b387 100644 --- a/packages/@justaname.id/sdk/src/lib/types/headers/index.ts +++ b/packages/@justaname.id/sdk/src/lib/types/headers/index.ts @@ -2,7 +2,7 @@ * Specifies the headers required for Sign-In with Ethereum (SIWE) requests. * These headers are essential for authenticating requests using Ethereum-based signatures, * ensuring the caller controls a specific Ethereum address. - * + * * @interface SIWEHeaders * @property {string} xMessage - The original message that was signed by the user. This message typically * contains a challenge or nonce to prevent replay attacks. @@ -13,15 +13,15 @@ */ export interface SIWEHeaders { xMessage: string; - xSignature: string; xAddress: string; + xSignature?: string; } /** * Defines the headers for API requests that require an API key for authentication. * The `xApiKey` header is used to pass the API key associated with the client making the request. * This is a common method for controlling access to restricted API endpoints. - * + * * @interface ApiKeyHeaders * @property {string} xApiKey - The API key provided to the client. This key should be included in API * requests to authenticate and authorize the client's access to the API. diff --git a/packages/@justaname.id/sdk/src/lib/types/mApps/add-mApp-permission.ts b/packages/@justaname.id/sdk/src/lib/types/mApps/add-mApp-permission.ts index 84f1ed52..8073dc05 100644 --- a/packages/@justaname.id/sdk/src/lib/types/mApps/add-mApp-permission.ts +++ b/packages/@justaname.id/sdk/src/lib/types/mApps/add-mApp-permission.ts @@ -1,10 +1,10 @@ import { IRequest, IRoute, SubnameResponse } from '../common'; - export interface AddMAppPermissionRequest extends IRequest { address: string; - signature: string; + signature?: string; message: string; } -export interface AddMAppPermissionRoute extends IRoute {} \ No newline at end of file +export interface AddMAppPermissionRoute + extends IRoute {} diff --git a/packages/@justaname.id/sdk/src/lib/types/mApps/revoke-mApp-permission.ts b/packages/@justaname.id/sdk/src/lib/types/mApps/revoke-mApp-permission.ts index b55ccdc1..c1145ab5 100644 --- a/packages/@justaname.id/sdk/src/lib/types/mApps/revoke-mApp-permission.ts +++ b/packages/@justaname.id/sdk/src/lib/types/mApps/revoke-mApp-permission.ts @@ -1,11 +1,10 @@ import { IRequest, IRoute, SubnameResponse } from '../common'; - export interface RevokeMAppPermissionRequest extends IRequest { - address: string; - signature: string; + signature?: string; message: string; } -export interface RevokeMAppPermissionRoute extends IRoute {} \ No newline at end of file +export interface RevokeMAppPermissionRoute + extends IRoute {} diff --git a/packages/@justaname.id/sdk/src/lib/types/signin/index.ts b/packages/@justaname.id/sdk/src/lib/types/signin/index.ts index 682cb395..3796e2c6 100644 --- a/packages/@justaname.id/sdk/src/lib/types/signin/index.ts +++ b/packages/@justaname.id/sdk/src/lib/types/signin/index.ts @@ -1,18 +1,19 @@ import { SiwensParams } from '@justaname.id/siwens'; import { ChainId } from '../common'; -export * from './signin-config' +export * from './signin-config'; -export interface RequestSignInParams extends Omit { - origin?: string, - domain?: string, - chainId?: ChainId - ttl?: number +export interface RequestSignInParams + extends Omit { + origin?: string; + domain?: string; + chainId?: ChainId; + ttl?: number; } export interface SignInFunctionParams { - message: string, - signature: string - nonce?: string - domain?: string -} \ No newline at end of file + message: string; + signature: string; + nonce?: string; + domain?: string; +} diff --git a/packages/@justaname.id/sdk/src/lib/types/siwe/verify-challenge.ts b/packages/@justaname.id/sdk/src/lib/types/siwe/verify-challenge.ts index c563b6f7..c2b56ccf 100644 --- a/packages/@justaname.id/sdk/src/lib/types/siwe/verify-challenge.ts +++ b/packages/@justaname.id/sdk/src/lib/types/siwe/verify-challenge.ts @@ -2,7 +2,7 @@ import { EmptyHeaders, IRequest, IResponse, IRoute } from '../common'; export interface VerifyChallengeRequest extends IRequest { address: string; - signature: string; + signature?: string; message: string; } @@ -10,4 +10,9 @@ export interface VerifyChallengeResponse extends IResponse { verified: boolean; } -export interface VerifyMessageRoute extends IRoute{} \ No newline at end of file +export interface VerifyMessageRoute + extends IRoute< + VerifyChallengeRequest, + VerifyChallengeResponse, + EmptyHeaders + > {} diff --git a/packages/@justaname.id/sdk/src/lib/types/subnames/accept.ts b/packages/@justaname.id/sdk/src/lib/types/subnames/accept.ts index bbeaa525..59fa8138 100644 --- a/packages/@justaname.id/sdk/src/lib/types/subnames/accept.ts +++ b/packages/@justaname.id/sdk/src/lib/types/subnames/accept.ts @@ -3,19 +3,17 @@ import { IRequest, IRoute, PartialAddressJson, - SubnameResponse + SubnameResponse, } from '../common'; import { ApiKeyHeaders, SIWEHeaders } from '../headers'; interface AddressAcceptRequest { - address: string; coinType: number; } interface TextRecordAcceptRequest { - key: string; value: string; @@ -33,14 +31,19 @@ export interface SubnameAcceptRequest extends IRequest { text?: TextRecordAcceptRequest[]; contentHash?: string; -} + signature?: string; +} -export interface SubnameAcceptRoute extends IRoute< - SubnameAcceptRequest, - SubnameResponse, - ApiKeyHeaders & SIWEHeaders, - 'ensDomain' | 'chainId', - 'addresses' | 'text', - { addresses?: PartialAddressJson | AddressWithTypedCoins[]; text?: Record | TextRecordAcceptRequest[] } -> {} \ No newline at end of file +export interface SubnameAcceptRoute + extends IRoute< + SubnameAcceptRequest, + SubnameResponse, + ApiKeyHeaders & SIWEHeaders, + 'ensDomain' | 'chainId', + 'addresses' | 'text', + { + addresses?: PartialAddressJson | AddressWithTypedCoins[]; + text?: Record | TextRecordAcceptRequest[]; + } + > {} diff --git a/packages/@justaname.id/sdk/src/lib/types/subnames/add.ts b/packages/@justaname.id/sdk/src/lib/types/subnames/add.ts index 849c7f0b..2fcbcaef 100644 --- a/packages/@justaname.id/sdk/src/lib/types/subnames/add.ts +++ b/packages/@justaname.id/sdk/src/lib/types/subnames/add.ts @@ -32,6 +32,8 @@ export interface SubnameAddRequest extends IRequest { text?: TextRecordAddRequest[]; contentHash?: string; + + signature?: string; } export interface SubnameAddRoute diff --git a/packages/@justaname.id/sdk/src/lib/types/subnames/reject.ts b/packages/@justaname.id/sdk/src/lib/types/subnames/reject.ts index 5b7342d0..b66d65c9 100644 --- a/packages/@justaname.id/sdk/src/lib/types/subnames/reject.ts +++ b/packages/@justaname.id/sdk/src/lib/types/subnames/reject.ts @@ -1,13 +1,20 @@ import { IRequest, IRoute, SubnameResponse } from '../common'; import { SIWEHeaders } from '../headers'; - export interface SubnameRejectRequest extends IRequest { ensDomain: string; username: string; chainId: number; + + signature?: string; } -export interface SubnameRejectRoute extends IRoute {} +export interface SubnameRejectRoute + extends IRoute< + SubnameRejectRequest, + SubnameResponse, + SIWEHeaders, + 'ensDomain' | 'chainId' + > {} diff --git a/packages/@justaname.id/sdk/src/lib/types/subnames/revoke.ts b/packages/@justaname.id/sdk/src/lib/types/subnames/revoke.ts index 93a67741..bd8b751e 100644 --- a/packages/@justaname.id/sdk/src/lib/types/subnames/revoke.ts +++ b/packages/@justaname.id/sdk/src/lib/types/subnames/revoke.ts @@ -7,6 +7,8 @@ export interface SubnameRevokeRequest extends IRequest { username: string; chainId: ChainId; + + signature?: string; } export interface SubnameRevokeRoute diff --git a/packages/@justaname.id/sdk/src/lib/types/subnames/update.ts b/packages/@justaname.id/sdk/src/lib/types/subnames/update.ts index e593be08..7869dbdb 100644 --- a/packages/@justaname.id/sdk/src/lib/types/subnames/update.ts +++ b/packages/@justaname.id/sdk/src/lib/types/subnames/update.ts @@ -3,26 +3,24 @@ import { AddressWithTypedCoins, ChainId, IRequest, - IRoute, PartialAddressJson, - SubnameResponse + IRoute, + PartialAddressJson, + SubnameResponse, } from '../common'; interface AddressUpdateRequest { - address: string; coinType: number; } interface TextRecordUpdateRequest { - key: string; value: string; } -export interface SubnameUpdateRequest extends IRequest{ - +export interface SubnameUpdateRequest extends IRequest { username: string; ensDomain: string; @@ -34,14 +32,19 @@ export interface SubnameUpdateRequest extends IRequest{ text?: TextRecordUpdateRequest[]; contentHash?: string; -} + signature?: string; +} -export interface SubnameUpdateRoute extends IRoute< - SubnameUpdateRequest, - SubnameResponse, - SIWEHeaders, - 'ensDomain' | 'chainId' , - 'addresses' | 'text', - { addresses?: PartialAddressJson | AddressWithTypedCoins[]; text?: Record | TextRecordUpdateRequest[] } -> {} \ No newline at end of file +export interface SubnameUpdateRoute + extends IRoute< + SubnameUpdateRequest, + SubnameResponse, + SIWEHeaders, + 'ensDomain' | 'chainId', + 'addresses' | 'text', + { + addresses?: PartialAddressJson | AddressWithTypedCoins[]; + text?: Record | TextRecordUpdateRequest[]; + } + > {} diff --git a/packages/@justaname.id/sdk/src/test/integration/justaname.spec.ts b/packages/@justaname.id/sdk/src/test/integration/justaname.spec.ts index 135bb8af..b47cf2f7 100644 --- a/packages/@justaname.id/sdk/src/test/integration/justaname.spec.ts +++ b/packages/@justaname.id/sdk/src/test/integration/justaname.spec.ts @@ -4,7 +4,7 @@ import { initializeJustaName } from '../helpers/initializeJustaName'; import { ethers } from 'ethers'; import * as dotenv from 'dotenv'; import { ChainId } from '../../lib/types'; -import { InvalidConfigurationException } from '../../lib/errors'; +import { ChallengeRequestException } from '../../lib/errors/ChallengeRequest.expection'; dotenv.config(); @@ -62,9 +62,7 @@ describe('justaname', () => { return justaname.siwe.requestChallenge({ address: '0x59c44836630760F97b74b569B379ca94c37B93ca', }); - }).toThrow( - InvalidConfigurationException.missingParameters(['origin', 'domain']) - ); + }).toThrow(ChallengeRequestException.originRequired()); }); it('should sign in be 1 day', async () => { @@ -97,6 +95,7 @@ describe('justaname', () => { { username: subnameToBeAdded, chainId: CHAIN_ID, + // signature, }, { xMessage: challenge.challenge, @@ -138,11 +137,11 @@ describe('justaname', () => { }, contentHash: 'ipfs://bafybeiear427jnvpwhlnvptsc3n6shccecoclur2poxnsvlsqfgskdrjfi', + signature, }, { xMessage: challenge.challenge, xAddress: subnameSigner.address, - xSignature: signature, } ); @@ -181,11 +180,11 @@ describe('justaname', () => { ], contentHash: 'ipns://k51qzi5uqu5dgccx524mfjv7znyfsa6g013o6v4yvis9dxnrjbwojc62pt0430', + signature, }, { xMessage: challenge.challenge, xAddress: subnameSigner.address, - xSignature: signature, } ); @@ -251,11 +250,11 @@ describe('justaname', () => { test: 'test', test2: 'test2', }, + signature, }, { xMessage: challenge.challenge, xAddress: subnameSigner.address, - xSignature: signature, } ); @@ -277,11 +276,11 @@ describe('justaname', () => { chainId: CHAIN_ID, ensDomain: ENS_DOMAIN, contentHash: 'invalid-content-hash', + signature, }, { xMessage: challenge.challenge, xAddress: subnameSigner.address, - xSignature: signature, } ); } catch (e) { @@ -311,11 +310,11 @@ describe('justaname', () => { ensDomain: ENS_DOMAIN, contentHash: 'ipfs://bafybeiear427jnvpwhlnvptsc3n6shccecoclur2poxnsvlsqfgskdrjfi', + signature, }, { xMessage: challenge.challenge, xAddress: subnameSigner.address, - xSignature: signature, } ); const records2 = await justaname.subnames.getRecords({ @@ -350,11 +349,11 @@ describe('justaname', () => { mApps: 'shouldntBeUpdated', [`test_${MAPP}`]: 'shouldBeOverrideWhenMAppPermissionIsAdded', }, + signature, }, { xMessage: challenge.challenge, xAddress: subnameSigner.address, - xSignature: signature, } ); @@ -380,11 +379,11 @@ describe('justaname', () => { text: { test: '', }, + signature, }, { xMessage: challenge.challenge, xAddress: subnameSigner.address, - xSignature: signature, } ); @@ -547,11 +546,11 @@ describe('justaname', () => { text: { [`test2_${MAPP}`]: 'shouldntBeUpdated', }, + signature, }, { xMessage: challenge.challenge, xAddress: subnameSigner.address, - xSignature: signature, } ); @@ -584,11 +583,11 @@ describe('justaname', () => { chainId: CHAIN_ID, ensDomain: ENS_DOMAIN, contentHash: '', + signature, }, { xMessage: challenge.challenge, xAddress: subnameSigner.address, - xSignature: signature, } ); @@ -703,10 +702,10 @@ describe('justaname', () => { chainId: CHAIN_ID, ensDomain: ENS_DOMAIN, username: subnameToBeAdded, + signature, }, { xAddress: subnameSigner.address, - xSignature: signature, xMessage: challenge.challenge, } ); @@ -728,10 +727,10 @@ describe('justaname', () => { chainId: CHAIN_ID, ensDomain: ENS_DOMAIN, username: subnameToBeAdded + '2', + signature, }, { xAddress: subnameSigner.address, - xSignature: signature, xMessage: challenge.challenge, } ); diff --git a/packages/@justverified/plugin/src/lib/components/EmailCredentialItem/index.tsx b/packages/@justverified/plugin/src/lib/components/EmailCredentialItem/index.tsx index d14c9e63..effbfacf 100644 --- a/packages/@justverified/plugin/src/lib/components/EmailCredentialItem/index.tsx +++ b/packages/@justverified/plugin/src/lib/components/EmailCredentialItem/index.tsx @@ -33,7 +33,7 @@ export const EmailCredentialItem: FC = ({ ); const loading = useMemo( () => selectedCredential === 'email', - [selectedCredential, 'email'] + [selectedCredential] ); const handleEmailChange = (e: React.ChangeEvent) => { diff --git a/packages/@justverified/plugin/src/lib/providers/JustVerifiedProvider/index.tsx b/packages/@justverified/plugin/src/lib/providers/JustVerifiedProvider/index.tsx index e45609db..46db0aa5 100644 --- a/packages/@justverified/plugin/src/lib/providers/JustVerifiedProvider/index.tsx +++ b/packages/@justverified/plugin/src/lib/providers/JustVerifiedProvider/index.tsx @@ -71,6 +71,7 @@ export const JustVerifiedProvider: FC = ({ const { signOut, isSignOutPending } = useEnsSignOut({ backendUrl: verificationBackendUrl, signoutRoute: '/auth/signout', + signinNonceRoute: '/auth/nonce', currentEnsRoute: '/auth/current', }); diff --git a/packages/@justweb3/ui/src/lib/components/ClickableItem/ClickableItem.module.css b/packages/@justweb3/ui/src/lib/components/ClickableItem/ClickableItem.module.css index 730eef12..d57cea37 100644 --- a/packages/@justweb3/ui/src/lib/components/ClickableItem/ClickableItem.module.css +++ b/packages/@justweb3/ui/src/lib/components/ClickableItem/ClickableItem.module.css @@ -1,56 +1,56 @@ - .listItemWrapper { - display: flex; - align-items: center; - padding: 10px; - border-radius: 100px; - box-sizing: border-box; - width: 300px; - background-color: var(--justweb3-background-color); - transition: background-color 0.2s ease; - max-width: 100%; - height: fit-content; - gap: 10px; + display: flex; + align-items: center; + padding: 10px; + border-radius: 100px; + box-sizing: border-box; + width: 300px; + background-color: var(--justweb3-background-color); + transition: background-color 0.2s ease; + max-width: 100%; + height: fit-content; + gap: 10px; } .listItemWrapper.disabled { - cursor: not-allowed; - opacity: 0.5; + cursor: not-allowed; + opacity: 0.5; } .listItemWrapper.enabled { - cursor: pointer; + cursor: pointer; } .listItemWrapper.hover { - border: 1px solid var(--justweb3-primary-color); + border: 1px solid var(--justweb3-primary-color); } .listItemWrapper.default { - border: 1px solid var(--justweb3-foreground-color-4); + border: 1px solid var(--justweb3-foreground-color-4); } .listItemWrapper.loading { - cursor: not-allowed; - border: 1px solid var(--justweb3-primary-color); + cursor: not-allowed; + border: 1px solid var(--justweb3-primary-color); } .content { - flex-grow: 1; - flex-shrink: 1; - flex-basis: 0; - display: flex; - flex-direction: column; - overflow: hidden; - place-content: space-around; + flex-grow: 1; + flex-shrink: 1; + flex-basis: 0; + display: flex; + flex-direction: column; + overflow: hidden; + place-content: space-around; } .truncatedText { - font-size: 10px; - font-weight: 400; - overflow: hidden; - text-overflow: ellipsis; - display: -webkit-box; - -webkit-line-clamp: 2; - -webkit-box-orient: vertical; -} \ No newline at end of file + font-size: 10px; + font-weight: 400; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + line-clamp: 2; + -webkit-box-orient: vertical; +} diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Avatar.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Avatar.tsx new file mode 100644 index 00000000..7b2e1d5a --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Avatar.tsx @@ -0,0 +1,31 @@ +import type { SVGProps } from 'react'; +export default function Avatar(props: SVGProps) { + return ( + + + + + + + + + ); +} diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Banner.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Banner.tsx new file mode 100644 index 00000000..bcf35d2e --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Banner.tsx @@ -0,0 +1,18 @@ +import type { SVGProps } from 'react'; +export default function Banner(props: SVGProps) { + return ( + + + + ); +} diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Nickname.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Nickname.tsx new file mode 100644 index 00000000..d4191046 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Nickname.tsx @@ -0,0 +1,31 @@ +import type { SVGProps } from 'react'; +export default function Nickname(props: SVGProps) { + return ( + + + + + + + + + ); +} diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/index.ts b/packages/@justweb3/ui/src/lib/icons/components/general/index.ts index 17fbc99e..be8c648a 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/index.ts +++ b/packages/@justweb3/ui/src/lib/icons/components/general/index.ts @@ -4,6 +4,8 @@ import AddressIcon from './Address'; import ArrowWhiteIcon from './ArrowWhite'; import ArrowIcon from './Arrow'; import AttachmentIcon from './Attachment'; +import AvatarIcon from './Avatar'; +import BannerIcon from './Banner'; import ClipIcon from './Clip'; import CloseIcon from './Close'; import ComicIcon from './Comic'; @@ -20,6 +22,7 @@ import MappIcon from './Mapp'; import MaximizeIcon from './Maximize'; import MinimizeIcon from './Minimize'; import MinusIcon from './Minus'; +import NicknameIcon from './Nickname'; import NotificationIcon from './Notification'; import PenIcon from './Pen'; import PersonEditIcon from './PersonEdit'; @@ -37,6 +40,8 @@ const general = { 'arrow-white': ArrowWhiteIcon, arrow: ArrowIcon, attachment: AttachmentIcon, + avatar: AvatarIcon, + banner: BannerIcon, clip: ClipIcon, close: CloseIcon, comic: ComicIcon, @@ -53,6 +58,7 @@ const general = { maximize: MaximizeIcon, minimize: MinimizeIcon, minus: MinusIcon, + nickname: NicknameIcon, notification: NotificationIcon, pen: PenIcon, 'person-edit': PersonEditIcon, @@ -73,6 +79,8 @@ export { ArrowWhiteIcon, ArrowIcon, AttachmentIcon, + AvatarIcon, + BannerIcon, ClipIcon, CloseIcon, ComicIcon, @@ -89,6 +97,7 @@ export { MaximizeIcon, MinimizeIcon, MinusIcon, + NicknameIcon, NotificationIcon, PenIcon, PersonEditIcon, diff --git a/packages/@justweb3/ui/src/lib/icons/svgs/general/avatar.svg b/packages/@justweb3/ui/src/lib/icons/svgs/general/avatar.svg new file mode 100644 index 00000000..e49d788f --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/svgs/general/avatar.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/packages/@justweb3/ui/src/lib/icons/svgs/general/banner.svg b/packages/@justweb3/ui/src/lib/icons/svgs/general/banner.svg new file mode 100644 index 00000000..5dc69c2e --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/svgs/general/banner.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/@justweb3/ui/src/lib/icons/svgs/general/nickname.svg b/packages/@justweb3/ui/src/lib/icons/svgs/general/nickname.svg new file mode 100644 index 00000000..73045e82 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/svgs/general/nickname.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/packages/@justweb3/widget/src/lib/components/JustEnsCard/JustEnsCard.module.css b/packages/@justweb3/widget/src/lib/components/JustEnsCard/JustEnsCard.module.css index bfb7d2a4..9e21bdf4 100644 --- a/packages/@justweb3/widget/src/lib/components/JustEnsCard/JustEnsCard.module.css +++ b/packages/@justweb3/widget/src/lib/components/JustEnsCard/JustEnsCard.module.css @@ -1,40 +1,70 @@ - .expandableCard { - height: 250px; - width: 400px; - display: flex; - flex-direction: column; - position: relative; - border-radius: 20px; - overflow: hidden; - cursor: pointer; - box-shadow: 2px 4px 20px 0px rgba(0, 0, 0, 0.05); - border: 1px solid var(--justweb3-foreground-color-4); + height: 200px; + width: 400px; + display: flex; + flex-direction: column; + position: relative; + border-radius: 20px; + overflow: hidden; + cursor: pointer; + box-shadow: 2px 4px 20px 0px rgba(0, 0, 0, 0.05); + border: 1px solid var(--justweb3-foreground-color-4); +} + +.expandableCard:hover { + border: 1px solid var(--justweb3-primary-color); + box-shadow: 1px 1px 5px 0px var(--justweb3-primary-color); +} + +.descriptionText { + color: var(--justweb3-foreground-color-2); + text-align: right; + font-size: 10px; + font-style: normal; + font-weight: 400; + line-height: normal; + opacity: 0.75; + max-width: 180px; + overflow: hidden; + display: -webkit-box; + line-clamp: 3; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; } .bannerImage { - object-fit: cover; - height: 100px; - width: 100%; + object-fit: cover; + height: 100px; + width: 100%; } .avatarContainer { - padding: 0 20px; - position: absolute; - top: 50px; + padding: 0 20px; + position: absolute; + top: 50px; +} + +.expandableCardContent { + padding: 35px 20px 20px 20px; } .titleText { - font-weight: 700; - color: var(--justweb3-primary-color); - font-size: 12px; + font-weight: 700; + color: var(--justweb3-primary-color); + font-size: 12px; +} + +.expandabletitleText { + font-weight: 700; + color: var(--justweb3-foreground-color-2); + font-size: 16px; } .clickableItem { - color: var(--justweb3-primary-color); + color: var(--justweb3-primary-color); } .socialIconsContainer { - display: flex; - gap: 5px; + display: flex; + gap: 5px; } diff --git a/packages/@justweb3/widget/src/lib/components/JustEnsCard/index.tsx b/packages/@justweb3/widget/src/lib/components/JustEnsCard/index.tsx index 0c760476..154ecc17 100644 --- a/packages/@justweb3/widget/src/lib/components/JustEnsCard/index.tsx +++ b/packages/@justweb3/widget/src/lib/components/JustEnsCard/index.tsx @@ -3,7 +3,7 @@ import React, { FC } from 'react'; import { ChainId } from '@justaname.id/sdk'; import { useJustWeb3 } from '../../providers'; import { useEnsAvatar, usePrimaryName, useRecords } from '@justaname.id/react'; -import { Avatar, ClickableItem, Flex, formatText, P } from '@justweb3/ui'; +import { Avatar, ClickableItem, CopiedIcon, CopyIcon, Flex, formatText, P } from '@justweb3/ui'; import { getTextRecordIcon } from '../../icons/records-icons'; import styles from './JustEnsCard.module.css'; // Import CSS module @@ -21,6 +21,7 @@ export const JustEnsCard: FC = ({ style, }) => { const { openEnsProfile } = useJustWeb3(); + const [isCopied, setIsCopied] = React.useState(false) const isEns = addressOrEns?.includes('.'); const { primaryName } = usePrimaryName({ address: isEns ? undefined : (addressOrEns as `0x${string}`), @@ -39,13 +40,25 @@ export const JustEnsCard: FC = ({ if (!isEns && !primaryName) { return; } - openEnsProfile(ens, chainId); }; + const copyToClipboard = () => { + navigator.clipboard + .writeText(ens) + .then(() => { + setIsCopied(true); + setTimeout(() => setIsCopied(false), 3000); + }) + .catch((err) => { + console.error('Failed to copy text: ', err); + }); + }; + if (expanded) { return ( -
+
handleEnsClick()} + > = ({ borderSize="4px" /> + + + +

{ens}

+ {isCopied ? ( + + ) : ( + { + e.stopPropagation(); + copyToClipboard() + }} + /> + )} +
+ {records && records?.sanitizedRecords?.socials?.length > 0 && ( + + {records.sanitizedRecords.socials.map((social, index) => + React.cloneElement(getTextRecordIcon(social.key), { + key: `${ens}-${index}-${social.key}`, + width: 15, + height: 15, + }) + )} + + )} +
+ {records?.sanitizedRecords.description && +

{records?.sanitizedRecords.description}

+ } +
); } diff --git a/packages/@justweb3/widget/src/lib/components/JustWeb3Button/index.tsx b/packages/@justweb3/widget/src/lib/components/JustWeb3Button/index.tsx index e872568e..0ce526a0 100644 --- a/packages/@justweb3/widget/src/lib/components/JustWeb3Button/index.tsx +++ b/packages/@justweb3/widget/src/lib/components/JustWeb3Button/index.tsx @@ -46,7 +46,7 @@ export const JustWeb3Button: FC = ({ const [openMApps, setOpenMApps] = useState(false); const { plugins, mApps, config } = useContext(JustWeb3Context); const { createPluginApi } = useContext(PluginContext); - const { address } = useMountedAccount(); + const { address, isConnected } = useMountedAccount(); const [mobileDialogOpen, setMobileDialogOpen] = useState(false); const { disconnect } = useDisconnect(); const { @@ -73,10 +73,6 @@ export const JustWeb3Button: FC = ({ const { avatar } = useEnsAvatar({ ens: connectedEns?.ens, }); - // const { data, isLoading } = useBalance({ - // address: connectedEns?.address as `0x${string}`, - // }); - const hasTwitterOrX = useMemo(() => { return records?.sanitizedRecords.socials.find( (social) => social.key === 'com.twitter' || social.key === 'com.x' @@ -89,7 +85,6 @@ export const JustWeb3Button: FC = ({ } }; - // if (isEnsAuthLoading || isLoading || (connectedEns && isRecordsPending)) { if (isEnsAuthLoading || (connectedEns && isRecordsPending)) { return ( = ({ } if (!connectedEns) { - if (address) { + if (isConnected && address) { return ( = ({ width={15} onClick={(e) => { e.stopPropagation(); + e.preventDefault(); disconnect(); logout && logout(); }} @@ -185,22 +181,22 @@ export const JustWeb3Button: FC = ({ setMobileDialogOpen(true); } }} - // right={ - // - // {address && formatText(address, 4)} - // - // - // } + // right={ + // + // {address && formatText(address, 4)} + // + // + // } /> - ) - } + ); + }; const connectedEnsProfileContent = ( @@ -322,19 +318,17 @@ export const JustWeb3Button: FC = ({ onClick={() => setOpenMApps(true)} right={ - {mAppsToEnable && - canEnableMApps && - mAppsToEnable.length > 0 && ( - - Configuration Required - - )} + {mAppsToEnable && canEnableMApps && mAppsToEnable.length > 0 && ( + + Configuration Required + + )} = ({ /> - ) + ); return ( <>
- - {connectedEnsBtn(false)} - - + {connectedEnsBtn(false)} + {connectedEnsProfileContent} @@ -382,7 +374,6 @@ export const JustWeb3Button: FC = ({ }} header={} fullScreen={false} - > {connectedEnsProfileContent} diff --git a/packages/@justweb3/widget/src/lib/components/Profile/ContentSection/index.tsx b/packages/@justweb3/widget/src/lib/components/Profile/ContentSection/index.tsx index c2093b02..095d242f 100644 --- a/packages/@justweb3/widget/src/lib/components/Profile/ContentSection/index.tsx +++ b/packages/@justweb3/widget/src/lib/components/Profile/ContentSection/index.tsx @@ -28,6 +28,7 @@ import { JustaPlugin } from '../../../plugins'; import { PluginContext } from '../../../providers/PluginProvider'; import { ProfileSection } from '../ProfileSection'; import MetadataCard from '../../MetadataCard'; +import MembersSection from '../MembersSection'; export interface ContentProps { fullSubname?: string; @@ -72,6 +73,11 @@ const ContentSection: React.FC = ({ connectedWalletChainId, chainId, ]); + + const isProfileCommunity = useMemo(() => { + return fullSubname.split('.').length == 2 + }, [fullSubname]) + const { createPluginApi } = useContext(PluginContext); const { sanitizeEnsImage } = useEnsAvatar(); @@ -81,8 +87,8 @@ const ContentSection: React.FC = ({ }, [fullSubname, chainId]); const hasTabs = useMemo(() => { - return plugins.some((plugin) => plugin.components?.ProfileTab); - }, [plugins]); + return plugins.some((plugin) => plugin.components?.ProfileTab) || isProfileCommunity; + }, [plugins, isProfileCommunity]); const MainTab = (
= ({ > Main + {isProfileCommunity && ( + Members + )} {plugins.map((plugin) => { const component = plugin.components?.ProfileTab; if (!component) { @@ -401,6 +410,11 @@ const ContentSection: React.FC = ({ {React.cloneElement(MainTab)} + {isProfileCommunity && ( + + + + )} {plugins.map((plugin) => { const component = plugin.components?.ProfileTab; if (!component) { diff --git a/packages/@justweb3/widget/src/lib/components/Profile/MembersSection/MembersSection.module.css b/packages/@justweb3/widget/src/lib/components/Profile/MembersSection/MembersSection.module.css new file mode 100644 index 00000000..7eb1003d --- /dev/null +++ b/packages/@justweb3/widget/src/lib/components/Profile/MembersSection/MembersSection.module.css @@ -0,0 +1,40 @@ +.container { + display: flex; + flex-direction: column; + width: 100%; + max-height: 100%; + padding-top: 5px; + padding-bottom: 24px; +} + +.grid { + display: grid; + grid-template-columns: repeat(1, 1fr); + gap: 10px; + overflow-y: scroll; + overflow-x: hidden; +} + +@media (min-width: 640px) { + .grid { + grid-template-columns: repeat(2, 1fr); + } +} + +@media (min-width: 768px) { + .grid { + grid-template-columns: repeat(3, 1fr); + } +} + +@media (min-width: 1024px) { + .grid { + grid-template-columns: repeat(4, 1fr); + } +} + +.loadingContainer { + position: relative; + display: flex; + height: 100px; +} diff --git a/packages/@justweb3/widget/src/lib/components/Profile/MembersSection/index.tsx b/packages/@justweb3/widget/src/lib/components/Profile/MembersSection/index.tsx new file mode 100644 index 00000000..fce169e6 --- /dev/null +++ b/packages/@justweb3/widget/src/lib/components/Profile/MembersSection/index.tsx @@ -0,0 +1,77 @@ +import { useEnsSubnames } from '@justaname.id/react'; +import { ChainId } from '@justaname.id/sdk'; +import { LoadingSpinner } from '@justweb3/ui'; +import React, { useEffect, useRef } from 'react'; +import JustEnsCard from '../../JustEnsCard'; +import styles from './MembersSection.module.css'; +; + +export interface MembersSectionProps { + fullSubname: string; + chainId: 1 | 11155111 | undefined; +} + +const MembersSection: React.FC = ({ + fullSubname, + chainId = 1, +}) => { + + const scrollContainerRef = useRef(null); // Add a ref for the scrollable container + + const { + data, + hasNextPage, + fetchNextPage, + isLoading + } = useEnsSubnames({ + ensDomain: decodeURIComponent(fullSubname), + chainId: chainId as ChainId, + isClaimed: true, + limit: 15, + }); + + + useEffect(() => { + const container = scrollContainerRef.current; + if (!container) return; + console.log("container", container.scrollTop, container.scrollHeight, container.clientHeight) + + const handleScroll = () => { + if ( + container.scrollTop + container.clientHeight >= + container.scrollHeight - 200 + ) { + if (!isLoading && hasNextPage) { + fetchNextPage(); + } + } + }; + + container.addEventListener('scroll', handleScroll); + return () => container.removeEventListener('scroll', handleScroll); + }, [isLoading, hasNextPage]); + + return ( +
+
+ {data?.pages + .flatMap((subnameData) => subnameData.data).flatMap((sub) => sub.ens) + .map((subname) => ( +
+ +
+ ))} +
+ {isLoading &&
+ +
+ } +
+ ); +}; + +export default MembersSection; diff --git a/packages/@justweb3/widget/src/lib/dialogs/SignInDialog/index.tsx b/packages/@justweb3/widget/src/lib/dialogs/SignInDialog/index.tsx index 90465466..484abef9 100644 --- a/packages/@justweb3/widget/src/lib/dialogs/SignInDialog/index.tsx +++ b/packages/@justweb3/widget/src/lib/dialogs/SignInDialog/index.tsx @@ -265,8 +265,8 @@ export const SignInDialog: FC = ({ {isAccountSubnamesPending || - isAccountEnsNamesPending || - isOffchainResolversPending ? ( + isAccountEnsNamesPending || + isOffchainResolversPending ? (
@@ -304,7 +304,8 @@ export const SignInDialog: FC = ({ + maxheight="100px" + > @@ -353,7 +354,9 @@ export const SignInDialog: FC = ({ }).then(() => { setSubnameSigningIn(username + '.' + claimableEns); signIn({ ens: username + '.' + claimableEns }) - .then(() => handleOpenDialog(false)) + .then(() => { + handleOpenDialog(false); + }) .finally(() => { setSubnameSigningIn(''); }); diff --git a/packages/@justweb3/widget/src/lib/icons/records-icons/index.tsx b/packages/@justweb3/widget/src/lib/icons/records-icons/index.tsx index 3565cd96..d9532257 100644 --- a/packages/@justweb3/widget/src/lib/icons/records-icons/index.tsx +++ b/packages/@justweb3/widget/src/lib/icons/records-icons/index.tsx @@ -1,27 +1,29 @@ import { + AvatarIcon, + BannerIcon, + DiscordIcon, EditIcon, EmailIcon, FacebookIcon, - DiscordIcon, GithubIcon, InstagramIcon, LocationIcon, - ProfileEditIcon, + NicknameIcon, RedditIcon, TelegramIcon, TwitterIcon, WebsiteIcon, - XIcon, + XIcon } from '@justweb3/ui'; export const getTextRecordIcon = (key: string) => { switch (key) { case 'avatar': - return ; + return ; case 'header': - return ; + return ; case 'display': - return ; + return ; case 'description': return ; case 'url': diff --git a/packages/@justweb3/widget/src/lib/providers/JustWeb3Provider/index.tsx b/packages/@justweb3/widget/src/lib/providers/JustWeb3Provider/index.tsx index 29168bb5..4529a9c5 100644 --- a/packages/@justweb3/widget/src/lib/providers/JustWeb3Provider/index.tsx +++ b/packages/@justweb3/widget/src/lib/providers/JustWeb3Provider/index.tsx @@ -363,12 +363,16 @@ const CheckSession: FC<{ const { signOut } = useEnsSignOut(); const { address, - isConnected, + isConnected: isConnectedAccount, isDisconnected, isConnecting, isReconnecting, chainId, } = useMountedAccount(); + const isConnected = useMemo( + () => isConnectedAccount && address, + [isConnectedAccount, address] + ); const isConnectedPrevious = usePreviousState(isConnected, [isConnected]); useEffect(() => { diff --git a/packages/@justweb3/widget/src/stories/signin2.stories.tsx b/packages/@justweb3/widget/src/stories/signin2.stories.tsx index c66d9eec..89abf7b2 100644 --- a/packages/@justweb3/widget/src/stories/signin2.stories.tsx +++ b/packages/@justweb3/widget/src/stories/signin2.stories.tsx @@ -37,7 +37,8 @@ const JustWeb3Config: JustWeb3ProviderConfig = { providerUrl: import.meta.env.STORYBOOK_APP_SEPOLIA_PROVIDER_URL, }, ], - openOnWalletConnect: false, + openOnWalletConnect: true, + dev: true, allowedEns: 'all', }; @@ -102,6 +103,8 @@ export const Example = () => { + +