11import styles from '@pages/app.module.scss' ;
22
3+ import * as C from '@common/constants' ;
34import * as Crypto from '@common/crypto' ;
45import * as R from '@common/requests' ;
56import * as U from '@common/utilities' ;
@@ -15,9 +16,11 @@ import Page from '@components/Page';
1516import SingleColumnLayout from '@components/SingleColumnLayout' ;
1617
1718import { H2 , H3 , H4 , P } from '@components/Typography' ;
19+ import Modal from '@components/Modal' ;
1820
1921export async function getServerSideProps ( context ) {
2022 const viewer = await U . getViewerFromHeader ( context . req . headers ) ;
23+ const wallet = await U . getAuthAddress ( context . req . headers ) ;
2124 const host = context . req . headers . host ;
2225 const protocol = host . split ( ':' ) [ 0 ] === 'localhost' ? 'http' : 'https' ;
2326
@@ -30,6 +33,8 @@ export async function getServerSideProps(context) {
3033 } ;
3134 }
3235
36+ viewer . wallet = wallet ;
37+
3338 return {
3439 props : { host, protocol, viewer, api : process . env . NEXT_PUBLIC_ESTUARY_API , hostname : `https://${ context . req . headers . host } ` } ,
3540 } ;
@@ -80,12 +85,83 @@ const onSubmit = async (event, state, setState, host) => {
8085 return setState ( { ...state , new : '' , confirm : '' , loading : false } ) ;
8186} ;
8287
88+ const connectWallet = async ( e , metamask , setMetamask ) => {
89+ setMetamask ( { ...metamask , loading : true } ) ;
90+ if ( ! window . ethereum ) {
91+ alert ( "You must have MetaMask installed!" ) ;
92+ return ;
93+ }
94+
95+ const accounts = await window . ethereum . request ( { method : "eth_requestAccounts" } ) ;
96+
97+ if ( window . ethereum . networkVersion !== C . network . chainId ) {
98+ try {
99+ await window . ethereum . request ( {
100+ method : 'wallet_switchEthereumChain' ,
101+ params : [ { chainId : C . network . chainId } ]
102+ } ) ;
103+ } catch ( err ) {
104+ // This error code indicates that the chain has not been added to MetaMask
105+ if ( err . code === 4902 ) {
106+ await window . ethereum . request ( {
107+ method : 'wallet_addEthereumChain' ,
108+ params : [ C . network ]
109+ } ) ;
110+ }
111+ }
112+ }
113+
114+ return addAuthAddress ( accounts [ 0 ] , metamask , setMetamask )
115+ }
116+
117+ async function addAuthAddress ( address , metamask , setMetamask ) {
118+ setMetamask ( { ...metamask , loading : true } ) ;
119+ let response ;
120+ try {
121+ response = await R . post ( '/user/auth-address' , { address } , C . api . authSvcHost ) ;
122+ await U . delay ( 1000 ) ;
123+
124+ if ( ! response . success ) {
125+ alert ( response . details ) ;
126+ return setMetamask ( { ...metamask , loading : false } ) ;
127+ }
128+ } catch ( e ) {
129+ console . log ( e ) ;
130+ alert ( 'Something went wrong' ) ;
131+ return setMetamask ( { ...metamask , loading : false } ) ;
132+ }
133+
134+ return setMetamask ( { ...metamask , address, loading : false } ) ;
135+ }
136+
137+ async function removeAuthAddress ( metamask , setMetamask ) {
138+ setMetamask ( { ...metamask , loading : true } ) ;
139+ let response ;
140+ try {
141+ response = await R . del ( '/user/auth-address' , { address : metamask . address } , C . api . authSvcHost ) ;
142+ await U . delay ( 1000 ) ;
143+
144+ if ( ! response . success ) {
145+ alert ( response . details ) ;
146+ return setMetamask ( { ...metamask , loading : false } ) ;
147+ }
148+ } catch ( e ) {
149+ console . log ( e ) ;
150+ alert ( 'Something went wrong' ) ;
151+ return setMetamask ( { ...metamask , loading : false } ) ;
152+ }
153+
154+ return setMetamask ( { ...metamask , address : "" , loading : false } ) ;
155+ }
156+
83157function SettingsPage ( props : any ) {
84158 const { viewer } = props ;
85159 const [ fissionUser , setFissionUser ] = React . useState ( null ) ;
86160 const [ state , setState ] = React . useState ( { loading : false , old : '' , new : '' , confirm : '' } ) ;
87161 const [ address , setAddress ] = React . useState ( '' ) ;
88162 const [ balance , setBalance ] = React . useState ( 0 ) ;
163+ const [ metamask , setMetamask ] = React . useState ( { address : viewer . wallet ? viewer . wallet . address : null , loading : false } ) ;
164+ const [ showUnlinkAddressModal , setShowUnlinkAddressModal ] = React . useState ( false ) ;
89165
90166 const sidebarElement = < AuthenticatedSidebar active = "SETTINGS" viewer = { viewer } /> ;
91167
@@ -141,6 +217,45 @@ function SettingsPage(props: any) {
141217 </ Button >
142218 </ div >
143219
220+ < H3 style = { { marginTop : 64 } } > Link Metamask</ H3 >
221+ < P style = { { marginTop : 16 } } > Enable authenticating with your Metamask account.</ P >
222+
223+ { metamask . address ? (
224+ < div >
225+ < Input style = { { marginTop : 8 } } readOnly value = { metamask . address } />
226+ < Button style = { { marginTop : 14 , width : 175 } }
227+ loading = { metamask . loading }
228+ disabled = { metamask . address == viewer . username }
229+ onClick = { ( ) => setShowUnlinkAddressModal ( true ) } > Unlink Account</ Button >
230+ { showUnlinkAddressModal && (
231+ < Modal
232+ title = "Unlink Account"
233+ onClose = { ( ) => {
234+ setShowUnlinkAddressModal ( false ) ;
235+ } }
236+ show = { showUnlinkAddressModal }
237+ >
238+ < div className = { styles . group } style = { { paddingTop : '16px' } } >
239+ < P style = { { maxWidth : '620px' } } >
240+ By unlinking your metamask account, you will no longer be able to log into your account using this authentication method. Are you sure you want to unlink?
241+ </ P >
242+ < H4 style = { { marginTop : '16px' , width : '488px' , display : 'inline-block' } } > </ H4 >
243+ < Button style = { { marginTop : 14 , width : 175 } }
244+ loading = { metamask . loading }
245+ disabled = { metamask . address == viewer . username }
246+ onClick = { async ( ) => {
247+ setShowUnlinkAddressModal ( false ) ;
248+ await removeAuthAddress ( metamask , setMetamask )
249+ } } > Unlink Account</ Button >
250+ </ div >
251+ </ Modal >
252+ ) }
253+ </ div >
254+ ) : (
255+ < Button style = { { marginTop : 14 , width : 175 } }
256+ loading = { metamask . loading }
257+ onClick = { ( e ) => connectWallet ( e , metamask , setMetamask ) } > Connect Wallet</ Button >
258+ ) }
144259 < H3 style = { { marginTop : 64 } } > Default settings (read only)</ H3 >
145260 < P style = { { marginTop : 16 } } > Estuary is configured to default settings for deals. You can not change these values, yet.</ P >
146261
0 commit comments