style: initial dark mode

This commit is contained in:
Cody Bender 2024-08-09 00:59:27 -04:00
parent ba05a82406
commit e0632d1a50
5 changed files with 213 additions and 163 deletions

View File

@ -1,14 +1,12 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" /> <meta name="theme-color" content="#000000" />
<meta <meta name="description" content="Laconic Wallet Web App" />
name="description"
content="Laconic Wallet Web App"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!-- <!--
manifest.json provides metadata used when your web app is installed on a manifest.json provides metadata used when your web app is installed on a
@ -26,10 +24,15 @@
--> -->
<title>Laconic Wallet</title> <title>Laconic Wallet</title>
<style> <style>
#app {
background-color: #0f0f0f;
}
body { body {
margin: 0; margin: 0;
padding: 0; padding: 0;
height: 100%; height: 100%;
background-color: #0f0f0f;
} }
.loader-wrapper { .loader-wrapper {
@ -62,6 +65,7 @@
} }
</style> </style>
</head> </head>
<body> <body>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"> <div id="root">
@ -80,4 +84,5 @@
To create a production bundle, use `npm run build` or `yarn build`. To create a production bundle, use `npm run build` or `yarn build`.
--> -->
</body> </body>
</html> </html>

View File

@ -21,5 +21,5 @@
"start_url": ".", "start_url": ".",
"display": "standalone", "display": "standalone",
"theme_color": "#000000", "theme_color": "#000000",
"background_color": "#ffffff" "background_color": "#0f0f0f"
} }

View File

@ -1,43 +1,43 @@
import React, { useCallback, useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from "react";
import { Button, Snackbar, Text } from 'react-native-paper'; import { Button, Snackbar, Surface, Text } from "react-native-paper";
import { TxBody, AuthInfo } from 'cosmjs-types/cosmos/tx/v1beta1/tx'; import { TxBody, AuthInfo } from "cosmjs-types/cosmos/tx/v1beta1/tx";
import { SignClientTypes } from '@walletconnect/types'; import { SignClientTypes } from "@walletconnect/types";
import { useNavigation } from '@react-navigation/native'; import { useNavigation } from "@react-navigation/native";
import { import {
createStackNavigator, createStackNavigator,
StackNavigationProp, StackNavigationProp,
} from '@react-navigation/stack'; } from "@react-navigation/stack";
import { getSdkError } from '@walletconnect/utils'; import { getSdkError } from "@walletconnect/utils";
import { Web3WalletTypes } from '@walletconnect/web3wallet'; import { Web3WalletTypes } from "@walletconnect/web3wallet";
import { formatJsonRpcResult } from '@json-rpc-tools/utils'; import { formatJsonRpcResult } from "@json-rpc-tools/utils";
import PairingModal from './components/PairingModal'; import PairingModal from "./components/PairingModal";
import { useWalletConnect } from './context/WalletConnectContext'; import { useWalletConnect } from "./context/WalletConnectContext";
import { useAccounts } from './context/AccountsContext'; import { useAccounts } from "./context/AccountsContext";
import InvalidPath from './screens/InvalidPath'; import InvalidPath from "./screens/InvalidPath";
import SignMessage from './screens/SignMessage'; import SignMessage from "./screens/SignMessage";
import HomeScreen from './screens/HomeScreen'; import HomeScreen from "./screens/HomeScreen";
import SignRequest from './screens/SignRequest'; import SignRequest from "./screens/SignRequest";
import AddSession from './screens/AddSession'; import AddSession from "./screens/AddSession";
import WalletConnect from './screens/WalletConnect'; import WalletConnect from "./screens/WalletConnect";
import ApproveTransaction from './screens/ApproveTransaction'; import ApproveTransaction from "./screens/ApproveTransaction";
import { StackParamsList } from './types'; import { StackParamsList } from "./types";
import { EIP155_SIGNING_METHODS } from './utils/wallet-connect/EIP155Data'; import { EIP155_SIGNING_METHODS } from "./utils/wallet-connect/EIP155Data";
import { getSignParamsMessage } from './utils/wallet-connect/helpers'; import { getSignParamsMessage } from "./utils/wallet-connect/helpers";
import ApproveTransfer from './screens/ApproveTransfer'; import ApproveTransfer from "./screens/ApproveTransfer";
import AddNetwork from './screens/AddNetwork'; import AddNetwork from "./screens/AddNetwork";
import EditNetwork from './screens/EditNetwork'; import EditNetwork from "./screens/EditNetwork";
import { COSMOS, EIP155 } from './utils/constants'; import { COSMOS, EIP155 } from "./utils/constants";
import { useNetworks } from './context/NetworksContext'; import { useNetworks } from "./context/NetworksContext";
import { NETWORK_METHODS } from './utils/wallet-connect/common-data'; import { NETWORK_METHODS } from "./utils/wallet-connect/common-data";
import { COSMOS_METHODS } from './utils/wallet-connect/COSMOSData'; import { COSMOS_METHODS } from "./utils/wallet-connect/COSMOSData";
import styles from "./styles/stylesheet";
const Stack = createStackNavigator<StackParamsList>(); const Stack = createStackNavigator<StackParamsList>();
const App = (): React.JSX.Element => { const App = (): React.JSX.Element => {
const navigation = const navigation = useNavigation<StackNavigationProp<StackParamsList>>();
useNavigation<StackNavigationProp<StackParamsList>>();
const { web3wallet, setActiveSessions } = useWalletConnect(); const { web3wallet, setActiveSessions } = useWalletConnect();
const { accounts, setCurrentIndex } = useAccounts(); const { accounts, setCurrentIndex } = useAccounts();
@ -45,16 +45,16 @@ const App = (): React.JSX.Element => {
const [modalVisible, setModalVisible] = useState(false); const [modalVisible, setModalVisible] = useState(false);
const [toastVisible, setToastVisible] = useState(false); const [toastVisible, setToastVisible] = useState(false);
const [currentProposal, setCurrentProposal] = useState< const [currentProposal, setCurrentProposal] = useState<
SignClientTypes.EventArguments['session_proposal'] | undefined SignClientTypes.EventArguments["session_proposal"] | undefined
>(); >();
const onSessionProposal = useCallback( const onSessionProposal = useCallback(
async (proposal: SignClientTypes.EventArguments['session_proposal']) => { async (proposal: SignClientTypes.EventArguments["session_proposal"]) => {
if (!accounts.length || !accounts.length) { if (!accounts.length || !accounts.length) {
const { id } = proposal; const { id } = proposal;
await web3wallet!.rejectSession({ await web3wallet!.rejectSession({
id, id,
reason: getSdkError('UNSUPPORTED_ACCOUNTS'), reason: getSdkError("UNSUPPORTED_ACCOUNTS"),
}); });
return; return;
} }
@ -74,10 +74,11 @@ const App = (): React.JSX.Element => {
switch (request.method) { switch (request.method) {
case NETWORK_METHODS.GET_NETWORKS: case NETWORK_METHODS.GET_NETWORKS:
const currentNetworkId = networksData.find( const currentNetworkId = networksData.find(
networkData => networkData.networkId === selectedNetwork!.networkId, (networkData) =>
networkData.networkId === selectedNetwork!.networkId,
)?.networkId; )?.networkId;
const networkNamesData = networksData.map(networkData => { const networkNamesData = networksData.map((networkData) => {
return { return {
id: networkData.networkId, id: networkData.networkId,
name: networkData.networkName, name: networkData.networkName,
@ -98,13 +99,13 @@ const App = (): React.JSX.Element => {
case NETWORK_METHODS.CHANGE_NETWORK: case NETWORK_METHODS.CHANGE_NETWORK:
const networkNameData = request.params[0]; const networkNameData = request.params[0];
const network = networksData.find( const network = networksData.find(
networkData => networkData.networkId === networkNameData.id, (networkData) => networkData.networkId === networkNameData.id,
); );
setCurrentIndex(0); setCurrentIndex(0);
setSelectedNetwork(network); setSelectedNetwork(network);
const response = formatJsonRpcResult(id, { const response = formatJsonRpcResult(id, {
response: 'true', response: "true",
}); });
await web3wallet!.respondSessionRequest({ await web3wallet!.respondSessionRequest({
@ -114,7 +115,7 @@ const App = (): React.JSX.Element => {
break; break;
case EIP155_SIGNING_METHODS.ETH_SEND_TRANSACTION: case EIP155_SIGNING_METHODS.ETH_SEND_TRANSACTION:
navigation.navigate('ApproveTransfer', { navigation.navigate("ApproveTransfer", {
transaction: request.params[0], transaction: request.params[0],
requestEvent, requestEvent,
requestSessionData, requestSessionData,
@ -122,7 +123,7 @@ const App = (): React.JSX.Element => {
break; break;
case EIP155_SIGNING_METHODS.PERSONAL_SIGN: case EIP155_SIGNING_METHODS.PERSONAL_SIGN:
navigation.navigate('SignRequest', { navigation.navigate("SignRequest", {
namespace: EIP155, namespace: EIP155,
address: request.params[1], address: request.params[1],
message: getSignParamsMessage(request.params), message: getSignParamsMessage(request.params),
@ -136,19 +137,19 @@ const App = (): React.JSX.Element => {
txbody: TxBody.toJSON( txbody: TxBody.toJSON(
TxBody.decode( TxBody.decode(
Uint8Array.from( Uint8Array.from(
Buffer.from(request.params.signDoc.bodyBytes, 'hex'), Buffer.from(request.params.signDoc.bodyBytes, "hex"),
), ),
), ),
), ),
authInfo: AuthInfo.toJSON( authInfo: AuthInfo.toJSON(
AuthInfo.decode( AuthInfo.decode(
Uint8Array.from( Uint8Array.from(
Buffer.from(request.params.signDoc.authInfoBytes, 'hex'), Buffer.from(request.params.signDoc.authInfoBytes, "hex"),
), ),
), ),
), ),
}; };
navigation.navigate('SignRequest', { navigation.navigate("SignRequest", {
namespace: COSMOS, namespace: COSMOS,
address: request.params.signerAddress, address: request.params.signerAddress,
message: JSON.stringify(message, undefined, 2), message: JSON.stringify(message, undefined, 2),
@ -158,7 +159,7 @@ const App = (): React.JSX.Element => {
break; break;
case COSMOS_METHODS.COSMOS_SIGN_AMINO: case COSMOS_METHODS.COSMOS_SIGN_AMINO:
navigation.navigate('SignRequest', { navigation.navigate("SignRequest", {
namespace: COSMOS, namespace: COSMOS,
address: request.params.signerAddress, address: request.params.signerAddress,
message: request.params.signDoc.memo, message: request.params.signDoc.memo,
@ -168,7 +169,7 @@ const App = (): React.JSX.Element => {
break; break;
case COSMOS_METHODS.COSMOS_SEND_TOKENS: case COSMOS_METHODS.COSMOS_SEND_TOKENS:
navigation.navigate('ApproveTransfer', { navigation.navigate("ApproveTransfer", {
transaction: request.params[0], transaction: request.params[0],
requestEvent, requestEvent,
requestSessionData, requestSessionData,
@ -177,7 +178,7 @@ const App = (): React.JSX.Element => {
case COSMOS_METHODS.COSMOS_SEND_TRANSACTION: case COSMOS_METHODS.COSMOS_SEND_TRANSACTION:
const { transactionMessage, signer } = request.params; const { transactionMessage, signer } = request.params;
navigation.navigate('ApproveTransaction', { navigation.navigate("ApproveTransaction", {
transactionMessage, transactionMessage,
signer, signer,
requestEvent, requestEvent,
@ -186,7 +187,7 @@ const App = (): React.JSX.Element => {
break; break;
default: default:
throw new Error('Invalid method'); throw new Error("Invalid method");
} }
}, },
[ [
@ -195,7 +196,7 @@ const App = (): React.JSX.Element => {
setSelectedNetwork, setSelectedNetwork,
setCurrentIndex, setCurrentIndex,
selectedNetwork, selectedNetwork,
web3wallet web3wallet,
], ],
); );
@ -205,18 +206,18 @@ const App = (): React.JSX.Element => {
}, [setActiveSessions, web3wallet]); }, [setActiveSessions, web3wallet]);
useEffect(() => { useEffect(() => {
web3wallet?.on('session_proposal', onSessionProposal); web3wallet?.on("session_proposal", onSessionProposal);
web3wallet?.on('session_request', onSessionRequest); web3wallet?.on("session_request", onSessionRequest);
web3wallet?.on('session_delete', onSessionDelete); web3wallet?.on("session_delete", onSessionDelete);
return () => { return () => {
web3wallet?.off('session_proposal', onSessionProposal); web3wallet?.off("session_proposal", onSessionProposal);
web3wallet?.off('session_request', onSessionRequest); web3wallet?.off("session_request", onSessionRequest);
web3wallet?.off('session_delete', onSessionDelete); web3wallet?.off("session_delete", onSessionDelete);
}; };
}); });
return ( return (
<> <Surface id="surfface" style={styles.appSurface}>
<Stack.Navigator <Stack.Navigator
screenOptions={{ screenOptions={{
headerBackTitleVisible: true, headerBackTitleVisible: true,
@ -227,7 +228,19 @@ const App = (): React.JSX.Element => {
component={HomeScreen} component={HomeScreen}
options={{ options={{
// eslint-disable-next-line react/no-unstable-nested-components // eslint-disable-next-line react/no-unstable-nested-components
headerTitle: () => <Text variant="titleLarge">Laconic Wallet</Text>, header: () => (
<Text
variant="titleLarge"
style={{
paddingLeft: 24,
paddingVertical: 12,
width: "auto",
backgroundColor: "#18181A",
}}
>
Laconic Wallet
</Text>
),
}} }}
/> />
<Stack.Screen <Stack.Screen
@ -258,7 +271,7 @@ const App = (): React.JSX.Element => {
name="AddSession" name="AddSession"
component={AddSession} component={AddSession}
options={{ options={{
title: 'New session', title: "New session",
}} }}
/> />
<Stack.Screen <Stack.Screen
@ -271,8 +284,9 @@ const App = (): React.JSX.Element => {
headerRight: () => ( headerRight: () => (
<Button <Button
onPress={() => { onPress={() => {
navigation.navigate('AddSession'); navigation.navigate("AddSession");
}}> }}
>
{<Text>PAIR</Text>} {<Text>PAIR</Text>}
</Button> </Button>
), ),
@ -282,28 +296,28 @@ const App = (): React.JSX.Element => {
name="ApproveTransfer" name="ApproveTransfer"
component={ApproveTransfer} component={ApproveTransfer}
options={{ options={{
title: 'Approve transfer', title: "Approve transfer",
}} }}
/> />
<Stack.Screen <Stack.Screen
name="AddNetwork" name="AddNetwork"
component={AddNetwork} component={AddNetwork}
options={{ options={{
title: 'Add Network', title: "Add Network",
}} }}
/> />
<Stack.Screen <Stack.Screen
name="EditNetwork" name="EditNetwork"
component={EditNetwork} component={EditNetwork}
options={{ options={{
title: 'Edit Network', title: "Edit Network",
}} }}
/> />
<Stack.Screen <Stack.Screen
name="ApproveTransaction" name="ApproveTransaction"
component={ApproveTransaction} component={ApproveTransaction}
options={{ options={{
title: 'Approve Transaction', title: "Approve Transaction",
}} }}
/> />
</Stack.Navigator> </Stack.Navigator>
@ -317,10 +331,11 @@ const App = (): React.JSX.Element => {
<Snackbar <Snackbar
visible={toastVisible} visible={toastVisible}
onDismiss={() => setToastVisible(false)} onDismiss={() => setToastVisible(false)}
duration={3000}> duration={3000}
>
Session approved Session approved
</Snackbar> </Snackbar>
</> </Surface>
); );
}; };

View File

@ -1,32 +1,55 @@
import React from 'react'; import React from "react";
import ReactDOM from 'react-dom/client'; import ReactDOM from "react-dom/client";
import { PaperProvider, MD3LightTheme as DefaultTheme, } from 'react-native-paper'; import {
import { NavigationContainer } from '@react-navigation/native'; PaperProvider,
import { Platform } from 'react-native'; MD3DarkTheme as DefaultTheme,
import { Buffer } from 'buffer'; } from "react-native-paper";
import { NavigationContainer, DarkTheme } from "@react-navigation/native";
import { Platform } from "react-native";
import { Buffer } from "buffer";
import './index.css'; import "./index.css";
import App from './App'; import App from "./App";
import { AccountsProvider } from './context/AccountsContext'; import { AccountsProvider } from "./context/AccountsContext";
import { NetworksProvider } from './context/NetworksContext'; import { NetworksProvider } from "./context/NetworksContext";
import reportWebVitals from './reportWebVitals'; import reportWebVitals from "./reportWebVitals";
import { WalletConnectProvider } from './context/WalletConnectContext'; import { WalletConnectProvider } from "./context/WalletConnectContext";
import { createTheme, ThemeProvider } from "@mui/material";
globalThis.Buffer = Buffer; globalThis.Buffer = Buffer;
const linking = { const linking = {
prefixes: ['https://wallet.laconic.com'] prefixes: ["https://wallet.laconic.com"],
}; };
const theme = { const theme = {
...DefaultTheme, ...DefaultTheme,
dark: false, dark: true,
}; };
const navigationTheme: typeof DarkTheme = {
...DarkTheme,
colors: {
...DarkTheme.colors,
primary: "#0000F4",
background: "#0F0F0F",
card: "#18181A",
},
};
const muiTheme = createTheme({
palette: {
mode: "dark",
primary: {
main: "#0000F4",
},
},
});
const root = ReactDOM.createRoot( const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement document.getElementById("root") as HTMLElement,
); );
root.render( root.render(
<div id="app">
<PaperProvider theme={theme}> <PaperProvider theme={theme}>
<NetworksProvider> <NetworksProvider>
<AccountsProvider> <AccountsProvider>
@ -34,26 +57,29 @@ root.render(
<NavigationContainer <NavigationContainer
linking={linking} linking={linking}
documentTitle={{ documentTitle={{
formatter: () => formatter: () => `Laconic Wallet`,
`Laconic Wallet`,
}} }}
theme={navigationTheme}
> >
<React.Fragment> <React.Fragment>
{Platform.OS === 'web' ? ( {Platform.OS === "web" ? (
<style type="text/css">{` <style type="text/css">{`
@font-face { @font-face {
font-family: 'MaterialCommunityIcons'; font-family: 'MaterialCommunityIcons';
src: url(${require('react-native-vector-icons/Fonts/MaterialCommunityIcons.ttf')}) format('truetype'); src: url(${require("react-native-vector-icons/Fonts/MaterialCommunityIcons.ttf")}) format('truetype');
} }
`}</style> `}</style>
) : null} ) : null}
<ThemeProvider theme={muiTheme}>
<App /> <App />
</ThemeProvider>
</React.Fragment> </React.Fragment>
</NavigationContainer> </NavigationContainer>
</WalletConnectProvider> </WalletConnectProvider>
</AccountsProvider> </AccountsProvider>
</NetworksProvider> </NetworksProvider>
</PaperProvider> </PaperProvider>
</div>,
); );
// If you want to start measuring performance in your app, pass a function // If you want to start measuring performance in your app, pass a function

View File

@ -29,10 +29,14 @@ const styles = StyleSheet.create({
accountComponent: { accountComponent: {
flex: 4, flex: 4,
}, },
appSurface: {
backgroundColor: '#0f0f0f',
},
appContainer: { appContainer: {
flexGrow: 1, flexGrow: 1,
marginTop: 24, marginTop: 24,
paddingHorizontal: 24, paddingHorizontal: 24,
backgroundColor: '#0f0f0f',
}, },
resetContainer: { resetContainer: {
flex: 1, flex: 1,
@ -178,7 +182,7 @@ const styles = StyleSheet.create({
width: '100%', width: '100%',
height: '50%', height: '50%',
position: 'absolute', position: 'absolute',
backgroundColor: 'white', backgroundColor: '#0f0f0f',
bottom: 0, bottom: 0,
}, },
modalOuterContainer: { flex: 1 }, modalOuterContainer: { flex: 1 },