Skip to content

Commit 0f8518c

Browse files
authored
Merge pull request #72 from input-output-hk/PLT-4591
PLT-4591 [FE] - Add support for auth proof from the client of the private signature from the wallet
2 parents a841af3 + 5001155 commit 0f8518c

File tree

3 files changed

+58
-19
lines changed

3 files changed

+58
-19
lines changed

react-web/src/api/onRequest.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import { AxiosError, AxiosRequestConfig } from "axios";
22

33
// Add a request interceptor
44
export function onRequest(config: AxiosRequestConfig) {
5-
const address: any = localStorage.getItem('address');
6-
const TokenAuth = address;
5+
const address: any = localStorage.getItem('authToken');
6+
const TokenAuth = 'Bearer ' + address;
77

88
if (address) {
99
config.headers = {

react-web/src/components/ConnectWallet/ConnectWallet.tsx

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
import React, { useEffect, useState, useCallback } from "react";
1+
import { useEffect, useState, useCallback } from "react";
22
import { Address } from "@emurgo/cardano-serialization-lib-browser";
33
import { useAppDispatch } from "store/store";
4-
import { getProfileDetails, setNetwork } from "store/slices/auth.slice";
4+
import { getProfileDetails, logout, setNetwork } from "store/slices/auth.slice";
55

66
import Modal from "components/Modal/Modal";
77
import Button from "components/Button/Button";
88
import Loader from "components/Loader/Loader";
9-
import Toast from "components/Toast/Toast";
109

1110
import './ConnectWallet.scss';
11+
import { fetchData } from "api/api";
12+
import { AxiosResponse } from "axios";
1213

1314
const wallets: Array<string> = ['lace', 'nami', 'yoroi']
1415

@@ -25,10 +26,14 @@ const ConnectWallet = () => {
2526
const [walletName, setWalletName] = useState("")
2627
const [address, setAddress] = useState("")
2728
const [isOpen, setIsOpen] = useState(false)
28-
const [errorToast, setErrorToast] = useState<{display: boolean; statusText?: string; message?: string;}>({display: false});
29+
const [errorToast, setErrorToast] = useState<{display: boolean; statusText?: string; message?: string; showRetry?: boolean}>({display: false});
2930
const [walletLoading, setWalletLoading] = useState(false)
3031

31-
const openConnectWalletModal = useCallback(() => setIsOpen(true),[])
32+
const openConnectWalletModal = useCallback(() => {
33+
setErrorToast({display: false})
34+
setWallet(null)
35+
setIsOpen(true)
36+
},[])
3237

3338
const onCloseModal = useCallback(() => setIsOpen(false),[])
3439

@@ -42,28 +47,63 @@ const ConnectWallet = () => {
4247
setWalletName(walletName)
4348
if (enabledWallet) {
4449
const response = await enabledWallet.getChangeAddress()
45-
setAddress(Address.from_bytes(Buffer.from(response, "hex")).to_bech32())
50+
const walletAddr = Address.from_bytes(Buffer.from(response, "hex")).to_bech32()
51+
initiatePrivateWalletSignature(enabledWallet, walletAddr, response)
4652
}
4753
})
4854
} catch (e) { handleError(e); }
4955
}
5056

5157
const handleError = (error: any) => {
5258
if (error.info) {
53-
setErrorToast({display: true, message: error.info})
59+
setErrorToast({
60+
display: true,
61+
message: error.info,
62+
showRetry: error.code === 3})
5463
} else if (error.response) {
55-
setErrorToast({display: true, statusText: error.response.statusText, message: error.response.data || undefined})
64+
setErrorToast({
65+
display: true,
66+
statusText: error.response.statusText,
67+
message: error.response.data || undefined,
68+
showRetry: error.status === 403
69+
})
5670
} else {
5771
setErrorToast({display: true})
5872
}
59-
setTimeout(() => { setErrorToast({display: false}) }, 3000)
73+
}
74+
75+
const catchError = (err: any) => {
76+
handleError(err)
77+
setWalletLoading(false)
78+
dispatch(logout())
79+
}
80+
81+
const initiatePrivateWalletSignature = async (currentWallet: any, walletAddr_bech32: any, walletAddr: string) => {
82+
const timestamp = (await fetchData.get<any,AxiosResponse<number>,any>('/server-timestamp')).data;
83+
const msgToBeSigned = `Sign this message if you are the owner of the ${walletAddr_bech32} address. \n Timestamp: <<${timestamp}>> \n Expiry: 60 seconds`;
84+
try {
85+
const {key, signature} = await currentWallet.signData(walletAddr, Buffer.from(msgToBeSigned, 'utf8').toString('hex'))
86+
if (key && signature) {
87+
const token = (await fetchData.post<any,AxiosResponse<string>,any>('/login', {
88+
address: walletAddr_bech32,
89+
key: key,
90+
signature: signature
91+
})).data;
92+
localStorage.setItem('authToken', token)
93+
setAddress(walletAddr_bech32)
94+
} else {
95+
catchError({ message: "Could not obtain the proper key and signature for the wallet. Please try connecting again." })
96+
}
97+
} catch (err) {
98+
catchError(err)
99+
}
60100
}
61101

62102
useEffect(() => {
63103
if (address) {
64104
(async () => {
65105
try {
66-
const response: any = await dispatch(getProfileDetails({"address": address, "wallet": wallet, "walletName": walletName})).catch(handleError)
106+
await dispatch(getProfileDetails({"address": address, "wallet": wallet, "walletName": walletName})).catch(handleError)
67107
setWalletLoading(false)
68108
} catch(error) {
69109
setWalletLoading(false)
@@ -101,15 +141,13 @@ const ConnectWallet = () => {
101141
}
102142
{ walletLoading ? <Loader /> : null}
103143
{
104-
(errorToast && errorToast.display) ? (<span className="error">{errorToast.message}</span>): null
144+
(errorToast?.display) ? (<>
145+
<span className="error">{errorToast.message}</span>
146+
<span className="link" style={{marginLeft: '5px'}} onClick={openConnectWalletModal}>Retry</span>
147+
</>): null
105148
}
106149
</div>
107150
</Modal>
108-
{/* {(errorToast && errorToast.display) ? (
109-
((errorToast.message && errorToast.statusText) ?
110-
<Toast message={errorToast.message} title={errorToast.statusText}/> :
111-
<Toast />))
112-
: null} */}
113151
</>
114152
)
115153
}

react-web/src/components/Header/Header.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ const Header = () => {
2222
// check if address, walletName is in localStorage - login user without having to connect to wallet again
2323
const addressCache = localStorage.getItem('address')
2424
const walletNameCache = localStorage.getItem('walletName')
25-
if (addressCache?.length && walletNameCache?.length) {
25+
const authToken = localStorage.getItem('authToken')
26+
if (addressCache?.length && walletNameCache?.length && authToken?.length) {
2627
(async () => {
2728
try {
2829
const enabledWallet = await window.cardano[walletNameCache].enable()

0 commit comments

Comments
 (0)