Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: open walletconnect modal if reload happens, preloader when selecting mobile app #82

Merged
merged 4 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
"@testing-library/user-event": "^12.1.10",
"@types/jest": "^26.0.15",
"@types/node": "^12.0.0",
"@web3modal/standalone": "^2.4.3",
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.0",
"@web3modal/standalone": "^2.4.3",
"axios": "^1.6.7",
"bignumber.js": "^9.0.2",
"boostrap": "^2.0.0",
Expand Down
76 changes: 37 additions & 39 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
import { MetaMaskProvider } from './context/MetamaskContext';
import { SNAP_URL } from './urls';
import { connectWc } from './utils/walletConnect';
import useConnectedWallet from './hooks/useConnectedWallet';
import useWcPreloader from './hooks/useWcPreloader';
import WcPreloader from './common/WcPreloader';

const { WalletSelector, walletSelectorOptions } = Components;

Expand All @@ -28,17 +31,35 @@
// walletSelectorOptions[reefExt.REEF_EASY_WALLET_IDENT],
walletSelectorOptions[reefExt.REEF_WALLET_CONNECT_IDENT]
];

Check warning on line 34 in src/App.tsx

View workflow job for this annotation

GitHub Actions / unit-lint

Missing return type on function

Check failure on line 34 in src/App.tsx

View workflow job for this annotation

GitHub Actions / unit-lint

Missing return type on function

Check warning on line 34 in src/App.tsx

View workflow job for this annotation

GitHub Actions / unit-lint

Argument 'setSelExtensionName' should be typed with a non-any type

Check failure on line 34 in src/App.tsx

View workflow job for this annotation

GitHub Actions / unit-lint

Unexpected any. Specify a different type

Check warning on line 34 in src/App.tsx

View workflow job for this annotation

GitHub Actions / unit-lint

Argument 'setWcPreloader' should be typed with a non-any type

Check failure on line 34 in src/App.tsx

View workflow job for this annotation

GitHub Actions / unit-lint

Unexpected any. Specify a different type
const App = (): JSX.Element => {
let selectedWallet: string | null = null;
try {
selectedWallet = localStorage.getItem(reefExt.SELECTED_EXTENSION_IDENT);
} catch (e) {
// when cookies disabled localStorage can throw
}
export const connectWalletConnect = async(ident:string,setSelExtensionName:any,setWcPreloader:any)=>{
setWcPreloader({
value:true,
message:"initializing mobile app connection"
});
setSelExtensionName(undefined); //force setting this to different value from the ident initially or else it doesn't call useInitReefState hook

const response:reefExt.WcConnection | undefined = await connectWc(setWcPreloader)
console.log('connectWalletConnect',response);
if (response) {
reefExt.injectWcAsExtension(response, { name: reefExt.REEF_WALLET_CONNECT_IDENT, version: "1.0.0" });
setSelExtensionName(ident);
// display preloader
setWcPreloader({
value:true,
message:"wait while we are establishing a connection"
});
} else {
// if proposal expired, recursively call
Uik.notify.danger("Connection QR expired, reloading")
await connectWalletConnect(ident,setSelExtensionName,setWcPreloader);
}
}

const [selExtensionName, setSelExtensionName] = useState<string | undefined>(selectedWallet || undefined);
const [wcPreloader,setWcPreloader] = useState<boolean>(false);
const App = (): JSX.Element => {
const {selExtensionName,setSelExtensionName} = useConnectedWallet();
// const [selExtensionName, setSelExtensionName] = useState<string | undefined>(selectedWallet || undefined);
const {loading:wcPreloader,setLoading:setWcPreloader} = useWcPreloader()
const {
loading, error, signers, selectedReefSigner, network, provider, reefState, extension
} = hooks.useInitReefStateExtension(
Expand Down Expand Up @@ -66,7 +87,7 @@
useEffect(() => {
if (selExtensionName === reefExt.REEF_SNAP_IDENT && error?.code === 2) {
history.push(SNAP_URL);
}

Check warning on line 90 in src/App.tsx

View workflow job for this annotation

GitHub Actions / unit-lint

React Hook useEffect has missing dependencies: 'history' and 'selExtensionName'. Either include them or remove the dependency array
}, [extension, error]);

const[errorToast,setErrorToast] = useState<{
Expand All @@ -75,7 +96,7 @@
}|undefined>();

useEffect(()=>{
if(errorToast){

Check failure on line 99 in src/App.tsx

View workflow job for this annotation

GitHub Actions / unit-lint

Expected '===' and instead saw '=='
if(errorToast.type == "danger"){
Uik.notify.danger(errorToast.message.toString());
}else{
Expand All @@ -87,7 +108,7 @@
text='Reconnect'
fill
onClick={() => window.location.reload()}
/>

Check failure on line 111 in src/App.tsx

View workflow job for this annotation

GitHub Actions / unit-lint

Expected indentation of 10 space characters but found 20
</>
})
}
Expand Down Expand Up @@ -117,35 +138,23 @@
//handle preloader
useEffect(()=>{
// preloader active
if(wcPreloader && signers.length){
if(wcPreloader.value && signers.length){
// if account connected , hide preloader
setWcPreloader(false)
setWcPreloader({
value:false,
message:""
})
}

Check warning on line 147 in src/App.tsx

View workflow job for this annotation

GitHub Actions / unit-lint

React Hook useEffect has missing dependencies: 'setWcPreloader' and 'wcPreloader.value'. Either include them or remove the dependency array
},[signers])

Check failure on line 149 in src/App.tsx

View workflow job for this annotation

GitHub Actions / unit-lint

Missing return type on function
const connectWalletConnect = async(ident:string)=>{
const response:reefExt.WcConnection | undefined = await connectWc()
console.log('connectWalletConnect',response);
if (response) {
reefExt.injectWcAsExtension(response, { name: reefExt.REEF_WALLET_CONNECT_IDENT, version: "1.0.0" });
setSelExtensionName(ident);
// display preloader
setWcPreloader(true);
} else {
// if proposal expired, recursively call
Uik.notify.danger("Connection QR expired, reloading")
await connectWalletConnect(ident);
}
}



const onExtensionSelected = async(ident: string) => {
console.log('onExtensionSelected', ident);
try {
if (ident === reefExt.REEF_WALLET_CONNECT_IDENT) {
await connectWalletConnect(ident);
await connectWalletConnect(ident,setSelExtensionName,setWcPreloader);
} else {

Check failure on line 157 in src/App.tsx

View workflow job for this annotation

GitHub Actions / unit-lint

'error' is already declared in the upper scope
setSelExtensionName(ident);
}
} catch (error) {
Expand Down Expand Up @@ -203,18 +212,7 @@
accountSelectorOpen={history.location.pathname !== SNAP_URL} />
<ContentRouter />
<NetworkSwitching isOpen={isNetworkSwitching} />
<Uik.Modal title="Connecting to Mobile App"
isOpen={wcPreloader}>
<div>
<div className='wc-preloader'>
<div className='wc-loader'></div>
<img src="/img/wallets/walletconnect.svg" alt="" className='wc-icon-preloader' />
</div>
<div className='wc-loader-label' >
<Uik.Text type="mini" text="wait while we are establishing a connection"/>
</div>
</div>
</Uik.Modal>
<WcPreloader wcPreloader={wcPreloader} />

<ToastContainer
draggable
Expand Down
9 changes: 8 additions & 1 deletion src/common/Nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
import ReefSigners from '../context/ReefSigners';
import { sendToSnap } from '../utils/snap';
import { getMetadata } from '../utils/metadata';
import { availableWalletOptions } from '../App';
import { availableWalletOptions, connectWalletConnect } from '../App';
import useConnectedWallet from '../hooks/useConnectedWallet';
import useWcPreloader from '../hooks/useWcPreloader';

export interface Nav {
selectExtension: (name: string) => void;
Expand All @@ -31,6 +33,8 @@
const [showMetadataUpdate, setShowMetadataUpdate] = useState(false);
const [availableExtensions, setAvailableExtensions] = useState(availableWalletOptions);

const {setSelExtensionName} = useConnectedWallet();

useEffect(() => {
if (provider && extension?.name === reefExt.REEF_SNAP_IDENT) {
const metadata = getMetadata(provider.api);
Expand All @@ -45,14 +49,14 @@
availableExtensions.forEach((ext: Extension) => {
ext.installed = ext.name === extension?.name;
});
setAvailableExtensions(availableExtensions);

Check warning on line 52 in src/common/Nav.tsx

View workflow job for this annotation

GitHub Actions / unit-lint

React Hook useEffect has a missing dependency: 'extension?.name'. Either include it or remove the dependency array
}, [extension, selExtName]);

let menuItems = [
{ title: localizedStrings.dashboard, url: DASHBOARD_URL },

Check failure on line 56 in src/common/Nav.tsx

View workflow job for this annotation

GitHub Actions / unit-lint

Assignment to property of function parameter 'ext'
{ title: localizedStrings.bonds, url: BONDS_URL },
];
if (isReefswapUI) {

Check warning on line 59 in src/common/Nav.tsx

View workflow job for this annotation

GitHub Actions / unit-lint

React Hook useEffect has a missing dependency: 'availableExtensions'. Either include it or remove the dependency array. You can also do a functional update 'setAvailableExtensions(a => ...)' if you only need 'availableExtensions' in the 'setAvailableExtensions' call
menuItems = [
{ title: localizedStrings.tokens_pill, url: DASHBOARD_URL },
{ title: localizedStrings.pools, url: POOLS_URL },
Expand Down Expand Up @@ -145,7 +149,7 @@

const updateMetadata = async (): Promise<void> => {
if (!provider) return;
const metadata = getMetadata(provider.api);

Check warning on line 152 in src/common/Nav.tsx

View workflow job for this annotation

GitHub Actions / unit-lint

Forbidden non-null assertion
const updated = await sendToSnap('provideMetadata', metadata);
if (updated) setShowMetadataUpdate(false);
}
Expand All @@ -158,7 +162,9 @@
await sendToSnap('createAccountWithSeed', { seed, name });
window.location.reload();
}

Check failure on line 165 in src/common/Nav.tsx

View workflow job for this annotation

GitHub Actions / unit-lint

Redundant use of `await` on a return value
const {setLoading:setWcPreloader}=useWcPreloader();

return (
<div className="nav-content navigation d-flex d-flex-space-between">
<div className="navigation__wrapper">
Expand Down Expand Up @@ -194,6 +200,7 @@
onStartAccountCreation={generateSeed}
onConfirmAccountCreation={createAccount}
open={accountSelectorOpen}
handleWalletConnect={()=>connectWalletConnect(reefExt.REEF_WALLET_CONNECT_IDENT,setSelExtensionName,setWcPreloader)}
/>
</nav>
</div>
Expand Down
28 changes: 28 additions & 0 deletions src/common/WcPreloader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react'
import Uik from '@reef-chain/ui-kit'

interface Props{
wcPreloader:{
message:string;
value:boolean;
};
}

function WcPreloader({wcPreloader}:Props) {

Check failure on line 11 in src/common/WcPreloader.tsx

View workflow job for this annotation

GitHub Actions / unit-lint

Missing return type on function

Check warning on line 11 in src/common/WcPreloader.tsx

View workflow job for this annotation

GitHub Actions / unit-lint

Missing return type on function
return (
<Uik.Modal title="Connecting to Mobile App"
isOpen={wcPreloader.value}>
<div>
<div className='wc-preloader'>
<div className='wc-loader'></div>
<img src="/img/wallets/walletconnect.svg" alt="" className='wc-icon-preloader' />
</div>
<div className='wc-loader-label' >
<Uik.Text type="mini" text={wcPreloader.message}/>
</div>
</div>
</Uik.Modal>
)
}

export default WcPreloader
32 changes: 32 additions & 0 deletions src/context/ConnectedWalletContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React, { createContext, useState, useContext, ReactNode } from 'react';
import { extension as reefExt } from '@reef-chain/util-lib';

interface ConnectedWalletContextProps {
selExtensionName: string|undefined;
setSelExtensionName: (_ident: string) => void;
}

const ConnectedWalletContext = createContext<ConnectedWalletContextProps | undefined>(undefined);

export const ConnectedWalletProvider = ({ children }: { children: ReactNode }) => {
let selectedWallet: string | null = null;
try {

Check warning on line 13 in src/context/ConnectedWalletContext.tsx

View workflow job for this annotation

GitHub Actions / unit-lint

Missing return type on function
selectedWallet = localStorage.getItem(reefExt.SELECTED_EXTENSION_IDENT);
} catch (e) {
// when cookies disabled localStorage can throw
}

const [ident, setIdent] = useState<string|undefined>(selectedWallet||undefined);

const setSelExtensionName = (_ident: string) => {
setIdent(_ident);
};

return (
<ConnectedWalletContext.Provider value={{ selExtensionName:ident, setSelExtensionName }}>
{children}
</ConnectedWalletContext.Provider>
);
};

export default ConnectedWalletContext;
40 changes: 40 additions & 0 deletions src/context/WcPreloaderContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React, { createContext, useState, ReactNode } from 'react';


interface WcPreloaderProps {
loading: {
value:boolean;
message:string;
};
setLoading: (_loading:{
value:boolean;
message:string;
}) => void;
}

const WcPreloaderContext = createContext<WcPreloaderProps | undefined>(undefined);

export const WcPreloaderProvider = ({ children }: { children: ReactNode }) => {
const [loading, setIsLoading] = useState<{
value:boolean;
message:string;
}>({
value:false,
message:""
});

const setLoading = (_loading:{
value:boolean;
message:string;
}) => {
setIsLoading(_loading);
};

return (
<WcPreloaderContext.Provider value={{ loading, setLoading }}>
{children}
</WcPreloaderContext.Provider>
);
};

export default WcPreloaderContext;
12 changes: 12 additions & 0 deletions src/hooks/useConnectedWallet.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useContext } from "react";
import ConnectedWalletContext from "../context/ConnectedWalletContext";

const useConnectedWallet = () => {
const context = useContext(ConnectedWalletContext);
if (!context) {
throw new Error('useConnectedWallet must be used within a ConnectedWalletProvider');
}
return context;
};

export default useConnectedWallet;
12 changes: 12 additions & 0 deletions src/hooks/useWcPreloader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useContext } from "react";
import WcPreloaderContext from "../context/WcPreloaderContext";

const useWcPreloader = () => {
const context = useContext(WcPreloaderContext);
if (!context) {
throw new Error('useWcPreloader must be used within a WcPreloaderProvider');
}
return context;
};

export default useWcPreloader;
10 changes: 9 additions & 1 deletion src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,17 @@ import { createRoot } from 'react-dom/client';
import reportWebVitals from './reportWebVitals';
import App from './App';
import { version } from '../package.json';
import { ConnectedWalletProvider } from './context/ConnectedWalletContext';
import { WcPreloaderProvider } from './context/WcPreloaderContext';

console.log(`Reef-app version: ${version}`);

createRoot(document.getElementById('root')!).render(<React.StrictMode><Router><App /></Router></React.StrictMode>);
createRoot(document.getElementById('root')!).render(<React.StrictMode><Router>
<ConnectedWalletProvider>
<WcPreloaderProvider>
<App />
</WcPreloaderProvider>
</ConnectedWalletProvider>
</Router></React.StrictMode>);

reportWebVitals();
7 changes: 5 additions & 2 deletions src/utils/walletConnect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const appMetadata: CoreTypes.Metadata = {
icons: [window.location.origin + '/favicon.ico'],
};

export const connectWc = async (): Promise<reefExt.WcConnection | undefined> => {
export const connectWc = async (setWcPreloader:any): Promise<reefExt.WcConnection | undefined> => {
try {
const client = await reefExt.initWcClient(appMetadata);

Expand All @@ -34,7 +34,10 @@ export const connectWc = async (): Promise<reefExt.WcConnection | undefined> =>

if (uri) {
web3Modal.openModal({ uri });

setWcPreloader({
value:false,
message:""
});
} else {
throw new Error("_noUriFoundWC");
}
Expand Down
Loading