Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: cleanup demo application
Browse files Browse the repository at this point in the history
PhearZero committed Apr 12, 2024
1 parent 1515c14 commit 9799efb
Showing 20 changed files with 419 additions and 472 deletions.
40 changes: 25 additions & 15 deletions services/liquid-auth-api-js/src/connect/connect.gateway.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import type { Handshake, Server, Socket } from 'socket.io';
import type { Server, Socket } from 'socket.io';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import {
ConnectedSocket,
MessageBody,
OnGatewayConnection, OnGatewayDisconnect,
OnGatewayConnection,
OnGatewayDisconnect,
OnGatewayInit,
SubscribeMessage,
WebSocketGateway,
@@ -18,7 +19,9 @@ import { RedisIoAdapter } from '../adapters/redis-io.adapter.js';
origin: '*',
},
})
export class ConnectGateway implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect {
export class ConnectGateway
implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect
{
private timers = new Map<string, NodeJS.Timeout>();
private ioAdapter: RedisIoAdapter;
private readonly logger = new Logger(ConnectGateway.name);
@@ -54,12 +57,20 @@ export class ConnectGateway implements OnGatewayInit, OnGatewayConnection, OnGat
socket.conn.close();
// you can also use socket.disconnect(), but in that case the client
// will not try to reconnect
} else {
if (
typeof session.wallet === 'string' &&
socket.rooms.has(session.wallet) === false
) {
this.logger.debug(`(*) Client Joining Room ${session.wallet}`);
socket.join(session.wallet);
}
}
});
}, 200);

if(this.timers.has(request.sessionID)) {
clearInterval(this.timers.get(request.sessionID));
if (this.timers.has(request.sessionID)) {
clearInterval(this.timers.get(request.sessionID));
}

this.timers.set(request.sessionID, timer);
@@ -77,9 +88,11 @@ export class ConnectGateway implements OnGatewayInit, OnGatewayConnection, OnGat

handleDisconnect(socket: Socket) {
const request = socket.request as Record<string, any>;
this.logger.debug(`(*) Client Disconnected with Session: ${request.sessionID}`);
if(this.timers.has(request.sessionID)) {
clearInterval(this.timers.get(request.sessionID));
this.logger.debug(
`(*) Client Disconnected with Session: ${request.sessionID}`,
);
if (this.timers.has(request.sessionID)) {
clearInterval(this.timers.get(request.sessionID));
}
}
/**
@@ -103,12 +116,12 @@ export class ConnectGateway implements OnGatewayInit, OnGatewayConnection, OnGat
const session = await this.authService.findSession(request.sessionID);
console.log('Session', session);
if (session) {
console.log('Listening to auth messages')
console.log('Listening to auth messages');
await this.ioAdapter.subClient.subscribe('auth');

// Handle messages
const obs$: Observable<any> = new Observable((observer) => {
const handleAuthMessage = async (channel, eventMessage)=> {
const handleAuthMessage = async (channel, eventMessage) => {
console.log('Link->Message', channel, eventMessage);
const { data } = JSON.parse(eventMessage);
console.log(body.requestId, data.requestId, data, body);
@@ -123,12 +136,9 @@ export class ConnectGateway implements OnGatewayInit, OnGatewayConnection, OnGat
this.ioAdapter.subClient.off('message', handleAuthMessage);
observer.complete();
}
}
};

this.ioAdapter.subClient.on(
'message',
handleAuthMessage,
);
this.ioAdapter.subClient.on('message', handleAuthMessage);
});
return obs$.pipe(
map((obs$) => ({
78 changes: 42 additions & 36 deletions sites/dapp-ui/src/App.tsx
Original file line number Diff line number Diff line change
@@ -9,19 +9,25 @@ import {
} from './Contexts';
import Layout from './Layout';

import { GetStartedCard } from './pages/home/GetStarted';
import { RegisteredCard } from './pages/dashboard/Registered';
import { HomePage } from './pages/home.tsx';
import { createTheme, CssBaseline } from '@mui/material';
import { DEFAULT_THEME } from './theme.tsx';
import { QueryClientProvider, QueryClient } from '@tanstack/react-query';
import { ThemeProvider } from '@emotion/react';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';

import { createHashRouter, RouterProvider } from 'react-router-dom';
import { WaitForPeersCard } from './pages/peering/WaitForPeers.tsx';
import { PeeringPage } from './pages/peering.tsx';
import ConnectedPage from './pages/connected.tsx';
import { Algodv2 } from 'algosdk';
import { AlgodContext } from './hooks/useAlgod.ts';
const queryClient = new QueryClient();

const algod = new Algodv2(
process.env.VITE_ALGOD_TOKEN || '',
process.env.VITE_ALGOD_SERVER || 'https://testnet-api.algonode.cloud',
process.env.VITE_ALGOD_PORT || 443,
);
const DEFAULT_CONFIG: RTCConfiguration = {
iceServers: [
{
@@ -40,15 +46,15 @@ const router = createHashRouter([
path: '/',
element: (
<Layout>
<GetStartedCard />
<HomePage />
</Layout>
),
},
{
path: '/peering',
element: (
<Layout>
<WaitForPeersCard />
<PeeringPage />
</Layout>
),
},
@@ -60,14 +66,6 @@ const router = createHashRouter([
</Layout>
),
},
{
path: '/registered',
element: (
<Layout>
<RegisteredCard />
</Layout>
),
},
]);
export default function ProviderApp() {
const [open, setOpen] = useState(false);
@@ -97,32 +95,40 @@ export default function ProviderApp() {
() =>
createTheme({
...DEFAULT_THEME,
palette: {
...DEFAULT_THEME.palette,
mode,
},
palette:
mode === 'dark'
? {
primary: { main: '#9966ff' },
mode: 'dark',
}
: { ...DEFAULT_THEME.palette },
}),
[mode],
);
console.log(theme, DEFAULT_THEME.palette);
return (
<QueryClientProvider client={queryClient}>
<SnackbarContext.Provider value={{ open, setOpen, message, setMessage }}>
<StateContext.Provider value={{ state, setState }}>
<ColorModeContext.Provider value={colorMode}>
<ThemeProvider theme={theme}>
<CssBaseline />
<PeerConnectionContext.Provider value={{ peerConnection }}>
<DataChannelContext.Provider
value={{ dataChannel, setDataChannel }}
>
<RouterProvider router={router} />
</DataChannelContext.Provider>
</PeerConnectionContext.Provider>
<ReactQueryDevtools initialIsOpen={false} />
</ThemeProvider>
</ColorModeContext.Provider>
</StateContext.Provider>
</SnackbarContext.Provider>
</QueryClientProvider>
<AlgodContext.Provider value={{ algod }}>
<QueryClientProvider client={queryClient}>
<SnackbarContext.Provider
value={{ open, setOpen, message, setMessage }}
>
<StateContext.Provider value={{ state, setState }}>
<ColorModeContext.Provider value={colorMode}>
<ThemeProvider theme={theme}>
<CssBaseline />
<PeerConnectionContext.Provider value={{ peerConnection }}>
<DataChannelContext.Provider
value={{ dataChannel, setDataChannel }}
>
<RouterProvider router={router} />
</DataChannelContext.Provider>
</PeerConnectionContext.Provider>
<ReactQueryDevtools initialIsOpen={false} />
</ThemeProvider>
</ColorModeContext.Provider>
</StateContext.Provider>
</SnackbarContext.Provider>
</QueryClientProvider>
</AlgodContext.Provider>
);
}
89 changes: 0 additions & 89 deletions sites/dapp-ui/src/components/Chat.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -7,9 +7,9 @@ import { Message } from '@liquid/auth-client/connect';
import QRCodeStyling, { Options } from 'qr-code-styling';
import { useEffect, useState } from 'react';
import { Fade } from '@mui/material';
import { useSocket } from '../../hooks/useSocket';
import { useSocket } from '../hooks/useSocket';
import nacl from 'tweetnacl';
import { useCredentialStore, Credential } from '../../store';
import { useCredentialStore, Credential } from '../store';
import { useNavigate } from 'react-router-dom';
const style = {
position: 'absolute' as const,
7 changes: 0 additions & 7 deletions sites/dapp-ui/src/components/user/Credential.tsx

This file was deleted.

4 changes: 2 additions & 2 deletions sites/dapp-ui/src/components/user/SessionMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Avatar, Badge, CircularProgress, Menu } from '@mui/material';
import IconButton from '@mui/material/IconButton';
import React, { useState } from 'react';
import { useSocket } from '../../hooks/useSocket.ts';
import { useUserState } from './useUserState.ts';
import { useSocket } from '@/hooks/useSocket.ts';
import { useUserState } from '@/hooks/useUserState.ts';
import { StatusCard } from './StatusCard.tsx';

export function SessionMenu() {
7 changes: 7 additions & 0 deletions sites/dapp-ui/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export * from './useAccountInfo';
export * from './useAddress';
export * from './useAlgod';
export * from './useDataChannel';
export * from './usePeerConnection';
export * from './useSocket';
export * from './useUserState';
18 changes: 18 additions & 0 deletions sites/dapp-ui/src/hooks/useAccountInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useQuery } from '@tanstack/react-query';
import { useAlgod } from './useAlgod.ts';

export function useAccountInfo(
address: string | null,
refetchInterval?: number,
) {
const algod = useAlgod();
return useQuery({
refetchInterval,
queryKey: ['accountInfo', address],
queryFn: async () => {
if (!algod || !address) return;
return await algod.accountInformation(address).do();
},
enabled: !!algod && !!address,
});
}
16 changes: 16 additions & 0 deletions sites/dapp-ui/src/hooks/useAlgod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { createContext, useContext } from 'react';
import { Algodv2 } from 'algosdk';

type AlgodState = { algod: Algodv2 | null };
export const AlgodContext = createContext({
algod: null,
} as AlgodState);

export function useAlgod() {
const { algod } = useContext(AlgodContext);
if (!algod)
throw new Error(
'Algod not found, make sure it is provided in the context.',
);
return algod;
}
14 changes: 5 additions & 9 deletions sites/dapp-ui/src/hooks/usePeerConnection.ts
Original file line number Diff line number Diff line change
@@ -37,14 +37,16 @@ export function usePeerConnection(
onIceCandidate: (event: RTCPeerConnectionIceEvent) => void,
) {
const { peerConnection } = useContext(PeerConnectionContext);
window.peerConnection = peerConnection;

useEffect(() => {
if (!peerConnection) return;
function handleICEGatheringStateChange() {
console.log(`ICE gathering state: ${peerConnection?.iceGatheringState}`);
}
function handleConnectionStateChange() {
console.log(`Connection state change: ${peerConnection.connectionState}`);
console.log(
`Connection state change: ${peerConnection?.connectionState}`,
);
}

function handleSignalingStateChange() {
@@ -57,9 +59,6 @@ export function usePeerConnection(
);
}

function handleICECandidateError(event) {
console.error('ICE Candidate Error', event);
}
peerConnection.addEventListener(
'icegatheringstatechange',
handleICEGatheringStateChange,
@@ -77,10 +76,7 @@ export function usePeerConnection(
handleICEConnectionStateChange,
);
peerConnection.addEventListener('icecandidate', onIceCandidate);
peerConnection.addEventListener(
'icecandidateerror',
handleICECandidateError,
);

return () => {
peerConnection.removeEventListener(
'icegatheringstatechange',
File renamed without changes.
152 changes: 126 additions & 26 deletions sites/dapp-ui/src/pages/connected.tsx
Original file line number Diff line number Diff line change
@@ -5,64 +5,164 @@ import {
import { PeerConnectionContext } from '../hooks/usePeerConnection.ts';
import { useContext, useEffect, useState } from 'react';
import Button from '@mui/material/Button';
import algosdk from 'algosdk';
import {
Transaction,
encodeUnsignedTransaction,
waitForConfirmation,
makePaymentTxnWithSuggestedParamsFromObject,
} from 'algosdk';
import { toBase64URL, fromBase64Url } from '@liquid/core/encoding';

const algodClient = new algosdk.Algodv2(
'',
'https://testnet-api.algonode.cloud',
443,
);
import { useAlgod } from '../hooks/useAlgod.ts';
import { useAccountInfo } from '../hooks/useAccountInfo.ts';
import FormControl from '@mui/material/FormControl';
import { Box, CircularProgress, Input, Slider } from '@mui/material';
import Typography from '@mui/material/Typography';
import { useMessageStore } from '../store.ts';

export default function ConnectedPage() {
const algod = useAlgod();
const walletStr = window.localStorage.getItem('wallet');
const wallet = walletStr ? JSON.parse(walletStr) : null;
const [txn, setTxn] = useState<algosdk.Transaction | null>(null);
const [txn, setTxn] = useState<Transaction | null>(null);
const { peerConnection } = useContext(PeerConnectionContext);
const datachannel = useDataChannel('remote', peerConnection);
const accountInfo = useAccountInfo(wallet, 3000);
const [from, setFrom] = useState<string>(wallet);
const [to, setTo] = useState<string>(wallet);
const [amount, setAmount] = useState<number>(0);

const [isWaitingForSignature, setIsWaitingForSignature] = useState(false);
const [isWaitingForConfirmation, setIsWaitingForConfirmation] =
useState(false);
const addMessage = useMessageStore((state) => state.addMessage);
const messages = useMessageStore((state) => state.messages);
// Receive response
useDataChannelMessages((event) => {
addMessage({
type: 'remote',
data: JSON.parse(event.data),
timestamp: Date.now(),
});
if (!txn) return;
async function handleMessage() {
if (!txn) return;
console.log(event);
const sig = fromBase64Url(event.data);
const message = JSON.parse(event.data);
if (message.type !== 'transaction-signature') return;

if (txn.txID() !== message.txId) throw new Error('Invalid txId');

const sig = fromBase64Url(message.sig);
const signedTxn = txn.attachSignature(wallet, sig);

const { txId } = await algodClient.sendRawTransaction(signedTxn).do();
const result = await algosdk.waitForConfirmation(algodClient, txId, 4);
console.log(result);
setIsWaitingForSignature(false);
setIsWaitingForConfirmation(true);
const { txId } = await algod.sendRawTransaction(signedTxn).do();
await waitForConfirmation(algod, txId, 4);
setIsWaitingForConfirmation(false);
}
handleMessage();
});

// Send Transaction
useEffect(() => {
if (!txn || !datachannel) return;
datachannel?.send(toBase64URL(txn.bytesToSign()));
}, [txn, datachannel]);
if (
!txn ||
!datachannel ||
isWaitingForSignature ||
isWaitingForConfirmation
)
return;
const txnMessage = {
type: 'transaction',
txn: toBase64URL(encodeUnsignedTransaction(txn)),
};
addMessage({ type: 'local', data: txnMessage, timestamp: Date.now() });
datachannel?.send(JSON.stringify(txnMessage));
setIsWaitingForSignature(true);
}, [txn, datachannel, isWaitingForSignature]);

if (accountInfo.data && accountInfo.data.amount === 0) {
return (
<Box>
<h1>Account has no funds</h1>
<h2>{accountInfo.data.address}</h2>
<pre>{JSON.stringify(accountInfo.data, null, 2)}</pre>
</Box>
);
}
if (isWaitingForSignature || isWaitingForConfirmation) {
return (
<Box>
<h1>
Waiting for {isWaitingForConfirmation ? 'Confirmation' : 'Signature'}
</h1>
<CircularProgress size={40} />
</Box>
);
}
return (
<div>
Connected
<Box sx={{ overflow: 'hidden' }}>
<Box component="form" sx={{ display: 'flex', flexDirection: 'column' }}>
<Typography variant="h4">Send Payment Transaction</Typography>
<FormControl sx={{ margin: 2 }}>
<Typography gutterBottom>From</Typography>
<Input
id="from"
aria-label="send from address"
value={from}
onChange={(e) => setFrom(e.target.value)}
/>
</FormControl>
<FormControl sx={{ margin: 2 }}>
<Typography gutterBottom>To</Typography>
<Input
id="to"
aria-label="send to address"
value={to}
onChange={(e) => setTo(e.target.value)}
/>
</FormControl>
<Box sx={{ margin: 2 }}>
<Typography gutterBottom sx={{ margin: '0px 0px 1em' }}>
Amount (in microalgos)
</Typography>
<Slider
valueLabelDisplay="on"
defaultValue={30}
max={accountInfo?.data?.amount || 0}
aria-label="Amount"
value={amount}
onChange={(_, value) => setAmount(value as number)}
/>
</Box>
</Box>

<Button
sx={{ float: 'right' }}
variant="contained"
disabled={!datachannel || accountInfo.isLoading}
onClick={async () => {
console.log(datachannel);

const suggestedParams = await algodClient.getTransactionParams().do();
const suggestedParams = await algod.getTransactionParams().do();
setTxn(
algosdk.makePaymentTxnWithSuggestedParamsFromObject({
from: wallet,
makePaymentTxnWithSuggestedParamsFromObject({
from,
suggestedParams,
to: wallet,
amount: 0,
to,
amount,
}),
);
}}
>
Send Transaction
</Button>
</div>
<Typography variant="h6" sx={{ marginTop: '20px' }}>
Messages
</Typography>
{messages.map((message, i) => (
<Box key={i} sx={{ maxWidth: 852, overflow: 'auto' }}>
<pre>{JSON.stringify(message, null, 2)}</pre>
</Box>
))}
</Box>
);
}
77 changes: 0 additions & 77 deletions sites/dapp-ui/src/pages/dashboard/Registered.tsx

This file was deleted.

83 changes: 0 additions & 83 deletions sites/dapp-ui/src/pages/dashboard/WaitForRegistration.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -3,9 +3,13 @@ import CardContent from '@mui/material/CardContent';
import Typography from '@mui/material/Typography';
import CardActions from '@mui/material/CardActions';
import Card from '@mui/material/Card';
import { ConnectModal } from './ConnectModal';
import { ConnectModal } from '@/components/ConnectModal';
import Button from '@mui/material/Button';
export function GetStartedCard() {
import { assertion } from '@liquid/auth-client';
import { useNavigate } from 'react-router-dom';
export function HomePage() {
const credId = window.localStorage.getItem('credId');
const navigate = useNavigate();
return (
<Card>
<CardMedia
@@ -25,7 +29,7 @@ export function GetStartedCard() {
/>
<CardContent>
<Typography gutterBottom variant="h5" component="div">
Get Started (1 of 3)
Get Started (1 of 2)
</Typography>
<Typography variant="body1" color="text.secondary">
Start by connecting a valid wallet, this is the first step in a three
@@ -35,7 +39,16 @@ export function GetStartedCard() {
</CardContent>
<CardActions>
<ConnectModal color="secondary" />
<Button>Set Wallet</Button>
{credId && (
<Button
onClick={async () => {
await assertion(credId);
navigate('/peering');
}}
>
Login
</Button>
)}
</CardActions>
</Card>
);
3 changes: 3 additions & 0 deletions sites/dapp-ui/src/pages/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './connected.tsx';
export * from './home.tsx';
export * from './peering.tsx';
Original file line number Diff line number Diff line change
@@ -3,20 +3,19 @@ import CardContent from '@mui/material/CardContent';
import Typography from '@mui/material/Typography';
import Card from '@mui/material/Card';
import { CircularProgress } from '@mui/material';
import { useEffect } from 'react';
import { useSocket } from '../../hooks/useSocket';
import { useEffect, useState } from 'react';
import { useSocket } from '@/hooks/useSocket';
import { useNavigate } from 'react-router-dom';
import { usePeerConnection } from '../../hooks/usePeerConnection.ts';
import {
useDataChannel,
useDataChannelMessages,
} from '../../hooks/useDataChannel.ts';
import { usePeerConnection } from '@/hooks/usePeerConnection';
import { useDataChannel, useDataChannelMessages } from '@/hooks/useDataChannel';
import { useMessageStore } from '@/store';

export function WaitForPeersCard() {
export function PeeringPage() {
const navigate = useNavigate();
const walletStr = window.localStorage.getItem('wallet');
const addMessage = useMessageStore((state) => state.addMessage);
const wallet = walletStr ? JSON.parse(walletStr) : null;

const [credentialId, setCredentialId] = useState<string | null>(null);
const { socket } = useSocket();
// const address = useAddressQuery(wallet);
const peerConnection = usePeerConnection((event) => {
@@ -31,14 +30,25 @@ export function WaitForPeersCard() {
});
const datachannel = useDataChannel('remote', peerConnection);
useDataChannelMessages((event) => {
console.log(event);
addMessage({
type: 'remote',
data: JSON.parse(event.data),
timestamp: Date.now(),
});
const data = JSON.parse(event.data);
if (data?.type === 'credential') {
window.localStorage.setItem('credId', data.id);
setCredentialId(data.id);
}
});

// Once we have a valid credential, continue to the connected page
useEffect(() => {
if (!datachannel) return;
if (!datachannel || !credentialId) return;

// datachannel.send('Hello World')
navigate('/connected');
}, [datachannel]);
}, [datachannel, credentialId, navigate]);

useEffect(() => {
if (!peerConnection) return;
@@ -88,10 +98,10 @@ export function WaitForPeersCard() {
/>
<CardContent>
<Typography gutterBottom variant="h5" component="div">
Waiting for Peer Connection (2 of 3)
Waiting for Peer Confirmation (2 of 2)
</Typography>
<Typography variant="body1" color="text.secondary">
<CircularProgress size={15} /> Waiting for Passkey registration for
<CircularProgress size={15} /> Waiting for message from peer for
address:
</Typography>
<Typography variant="body2" color="text.secondary">
2 changes: 1 addition & 1 deletion sites/dapp-ui/src/store.ts
Original file line number Diff line number Diff line change
@@ -60,7 +60,7 @@ export const usePeerStore = create<PeerStore>((set) => ({
}));

export type Message = {
text: string;
data: any;
type: 'local' | 'remote';
timestamp: number;
};
6 changes: 5 additions & 1 deletion sites/dapp-ui/tsconfig.json
Original file line number Diff line number Diff line change
@@ -18,7 +18,11 @@
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
"noFallthroughCasesInSwitch": true,

"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
232 changes: 126 additions & 106 deletions sites/dapp-ui/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,111 +1,131 @@
import {defineConfig, splitVendorChunkPlugin} from 'vite'
import { VitePWA } from 'vite-plugin-pwa'
import { defineConfig, splitVendorChunkPlugin } from 'vite';
import { VitePWA } from 'vite-plugin-pwa';
import { ViteImageOptimizer } from 'vite-plugin-image-optimizer';
import react from '@vitejs/plugin-react-swc'
import {rename} from 'node:fs/promises'
import {resolve} from 'node:path'
import {mkdirp} from 'mkdirp';
import react from '@vitejs/plugin-react-swc';
import { rename } from 'node:fs/promises';
import { resolve } from 'node:path';
import { mkdirp } from 'mkdirp';

const API_DIR = resolve(__dirname, '..', '..', 'services', 'liquid-auth-api-js')
const PUBLIC_DIR = resolve(API_DIR, 'public')
const VIEW_DIR = resolve(API_DIR, 'views')
console.log(API_DIR)
const API_DIR = resolve(
__dirname,
'..',
'..',
'services',
'liquid-auth-api-js',
);
const PUBLIC_DIR = resolve(API_DIR, 'public');
const VIEW_DIR = resolve(API_DIR, 'views');
console.log(API_DIR);
export default defineConfig({
// base: '/app',
server: {
hmr: {
port: 8000,
host: 'localhost'
}
// proxy: {
// '^/auth/.*': 'http://localhost:3000',
// '^/connect/.*': 'http://localhost:3000',
// '^/attestation/.*': 'http://localhost:3000',
// '^/assertion/.*': 'http://localhost:3000',
// '/socket.io': {
// target: 'ws://localhost:3000',
// ws: true,
// },
// }
// base: '/app',
server: {
hmr: {
port: 8000,
host: 'localhost',
},
build: {
// rollupOptions: {
// output: {
// manualChunks: {
// // 'algorand': ['tweetnacl', 'algosdk'],
// 'socket.io': ['socket.io-client'],
// 'react': ['react', 'react-dom', '@tanstack/react-query'],
// 'material': ['@mui/material', '@mui/icons-material']
// }
// }
// },
outDir: PUBLIC_DIR,
// proxy: {
// '^/auth/.*': 'http://localhost:3000',
// '^/connect/.*': 'http://localhost:3000',
// '^/attestation/.*': 'http://localhost:3000',
// '^/assertion/.*': 'http://localhost:3000',
// '/socket.io': {
// target: 'ws://localhost:3000',
// ws: true,
// },
// }
},
build: {
// rollupOptions: {
// output: {
// manualChunks: {
// // 'algorand': ['tweetnacl', 'algosdk'],
// 'socket.io': ['socket.io-client'],
// 'react': ['react', 'react-dom', '@tanstack/react-query'],
// 'material': ['@mui/material', '@mui/icons-material']
// }
// }
// },
outDir: PUBLIC_DIR,
},
resolve: {
alias: {
'@/components': resolve(__dirname, 'src', 'components'),
'@/hooks': resolve(__dirname, 'src', 'hooks'),
'@/pages': resolve(__dirname, 'src', 'pages'),
'@/store': resolve(__dirname, 'src', 'store'),
},
plugins: [
VitePWA({
includeAssets: ['logo-background.svg', 'apple-touch-icon.png', 'maskable-icon.png'],
workbox: {
navigateFallback: null,
},
manifest: {
name: 'Liquid dApp',
short_name: 'Liquid',
description: 'FIDO2/Passkey Authentication',
theme_color: '#121212',
icons: [
{
src: 'icons/48x48.png',
sizes: '48x48',
type: 'image/png'
},
{
src: 'icons/72x72.png',
sizes: '72x72',
type: 'image/png'
},
{
src: 'icons/96x96.png',
sizes: '96x96',
type: 'image/png'
},
{
src: 'icons/144x144.png',
sizes: '144x144',
type: 'image/png'
},
{
src: 'icons/192x192.png',
sizes: '192x192',
type: 'image/png'
},
{
src: 'icons/512x512.png',
sizes: '512x512',
type: 'image/png'
},
{
src: 'maskable-icon.png',
sizes: '512x512',
type: 'image/png',
purpose: "maskable"
}
]
}
}),
splitVendorChunkPlugin(),
ViteImageOptimizer(),
react(),
{
name: 'move-index-file',
closeBundle: async () => {
await mkdirp(VIEW_DIR)
try {
await rename(resolve(PUBLIC_DIR, 'index.html'), resolve(VIEW_DIR, 'index.html'))
} catch (e) {
console.log('Skipping')
}

}
},
],
})
},
plugins: [
VitePWA({
includeAssets: [
'logo-background.svg',
'apple-touch-icon.png',
'maskable-icon.png',
],
workbox: {
navigateFallback: null,
},
manifest: {
name: 'Liquid dApp',
short_name: 'Liquid',
description: 'FIDO2/Passkey Authentication',
theme_color: '#121212',
icons: [
{
src: 'icons/48x48.png',
sizes: '48x48',
type: 'image/png',
},
{
src: 'icons/72x72.png',
sizes: '72x72',
type: 'image/png',
},
{
src: 'icons/96x96.png',
sizes: '96x96',
type: 'image/png',
},
{
src: 'icons/144x144.png',
sizes: '144x144',
type: 'image/png',
},
{
src: 'icons/192x192.png',
sizes: '192x192',
type: 'image/png',
},
{
src: 'icons/512x512.png',
sizes: '512x512',
type: 'image/png',
},
{
src: 'maskable-icon.png',
sizes: '512x512',
type: 'image/png',
purpose: 'maskable',
},
],
},
}),
splitVendorChunkPlugin(),
ViteImageOptimizer(),
react(),
{
name: 'move-index-file',
closeBundle: async () => {
await mkdirp(VIEW_DIR);
try {
await rename(
resolve(PUBLIC_DIR, 'index.html'),
resolve(VIEW_DIR, 'index.html'),
);
} catch (e) {
console.log('Skipping');
}
},
},
],
});

0 comments on commit 9799efb

Please sign in to comment.