I'm trying to get Ledger hardware wallet to connect in remix.run. I'm following this instruction
https://developers.ledger.com/docs/transport/web-hid-usb/ and I'm using remix-utils so I can use ClientOnly Component.
How do I connect to ledger hardware wallet when I Click on "Connect Ledger" button? I can't get my head around it. What I have so far is below.
ledger.client.tsx component
import "core-js/actual";
import { listen } from "#ledgerhq/logs";
import AppBtc from "#ledgerhq/hw-app-btc";
// Keep this import if you want to use a Ledger Nano S/X/S Plus with the USB protocol and delete the #ledgerhq/hw-transport-webhid import
import TransportWebUSB from "#ledgerhq/hw-transport-webusb";
export function ConnectLedgerHardWare() {
async function handleButtonClicked() {
const transport = await TransportWebUSB.create();
//listen to the events which are sent by the Ledger packages in order to debug the app
listen((log) => console.log(log));
//When the Ledger device connected it is trying to display the bitcoin address
const appBtc = new AppBtc(transport);
const { bitcoinAddress } = await appBtc.getWalletPublicKey(
"44'/0'/0'/0/0",
{ verify: false, format: "legacy" }
);
console.log(bitcoinAddress);
await appBtc.getWalletPublicKey("44'/0'/0'/0/0", {
format: "legacy",
verify: true,
});
return bitcoinAddress;
}
return (
<>
<button onClick={handleButtonClicked}>Connect ledger</button>
</>
);
}
index.tsx
import { useEffect } from "react";
import { ClientOnly, useHydrated } from "remix-utils";
import { ConnectLedgerHardWare } from "~/components/ledger.client";
export default function Index() {
const hydrated = useHydrated();
useEffect(() => {});
return (
<div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.4" }}>
<ClientOnly fallback={<p>Loading...</p>}>
{() => <ConnectLedgerHardWare />}
</ClientOnly>
</div>
);
}
My code above is giving me this error:
Error: Cannot initialize 'routeModules'. This normally occurs when you have server code in your client modules.
Related
I am developing using react.
It is in the process of fetching the information contained in the db and displaying it on the web page through the map method.
If you delete one piece of information using onclick or the onClose method provided by antd, the info is also deleted from the db.
in the db, the function worked successfully. but the information at the bottom is deleted, not the deleted information in the web page.
If I refresh website, it is displayed normally, but I don't want to use the window reload function.
I wonder why this is happening and what is the solution.
thank you!
AlertPage
import React, { useState } from "react";
import useSWR from "swr";
import axios from "axios";
import AlertComponent from "./Sections/AlertComponent";
const fetcher = async (url) =>
await axios.get(url).then((response) => JSON.parse(response.data.alerts));
function AlertPage() {
const { data = [], error } = useSWR("/api/streaming/getAlerts", fetcher, {
refreshInterval: 1000,
});
const onClose = (data) => {
axios.post(`/api/streaming/removeAlerts/${data._id.$oid}`).then(() => {
console.log(`${data._id.$oid} deleted`);
});
};
const renderAlerts = data.map((alert, index) => {
return (
<div key={index}>
<AlertComponent alert={alert} index={index} onClose={onClose} />
</div>
);
});
if (error) return <div>failed to load</div>;
if (data === []) return <div>loading...</div>;
return <div>{renderAlerts}</div>;
}
export default AlertPage;
AlertComponent
import React, { useState } from "react";
import { Alert } from "antd";
import Marquee from "react-fast-marquee";
function AlertComponent(props) {
const [alert, setalert] = useState(props.alert);
const [index, setindex] = useState(props.index);
return (
<div
className="alert"
key={index}
style={{ display: "flex" }}
onClick={() => {
props.onClose(alert);
}}
>
<Alert
message={`${alert.data.timestamp.$date.substr(0, 19)}`}
description={
<Marquee pauseOnHover speed={40} gradient={false}>
{`<${alert.data.location}> <${alert.data.name}> <${alert.data.contents}> detected`}
</Marquee>
}
banner
/>
</div>
);
}
export default AlertComponent;
This could be happening due the local cache maintained by swr and since you're not refetching the data after the deletion the changes are not reflected in the DOM.
One options is to trigger a manual refetch to retrieve the most up-to-date data. We could achieve that by changing the following lines:
const { data = [], error, mutate } = useSWR("/api/streaming/getAlerts", fetcher, {
refreshInterval: 1000
});
...
axios.post(`/api/streaming/removeAlerts/${data._id.$oid}`).then(() => {
mutate("/api/streaming/getAlerts");
});
another approach would be to rely on the optimistic update strategy from swr, there is an example here
I've searched on here already but it seems all the answers are very outdated or they are questions that haven't been answered.
I've got an expo app SDK 43 and I'm using their auth library to authorize a reddit login. I've followed the example here https://docs.expo.dev/guides/authentication/#reddit to produce this code
import React from 'react';
import * as WebBrowser from 'expo-web-browser';
import { makeRedirectUri, ResponseType, useAuthRequest } from 'expo-auth-session';
import { Button } from 'react-native-paper';
import { useAppDispatch } from '../../common/hooks/redux';
import { setAuthCode } from '../../common/state/authSlice';
WebBrowser.maybeCompleteAuthSession();
// Endpoint
const discovery = {
authorizationEndpoint: 'https://www.reddit.com/api/v1/authorize.compact',
tokenEndpoint: 'https://www.reddit.com/api/v1/access_token',
};
const LoginScreen = () => {
const dispatch = useAppDispatch();
const [request, response, promptAsync] = useAuthRequest(
{
responseType: ResponseType.Token,
clientId: 'MY_CLIENT_ID',
scopes: ['identity'],
redirectUri: makeRedirectUri({
scheme: undefined,
}),
},
discovery
);
React.useEffect(() => {
console.log(`response is ${response}`);
if (response?.type === 'success') {
const { access_token } = response.params;
dispatch(setAuthCode(access_token));
console.log(access_token);
} else {
console.log(response);
}
}, [response]);
return (
<Button
disabled={!request}
onPress={() => {
promptAsync();
}}
>
Login
</Button>
);
};
export default LoginScreen;
But despite the fact that the login button correctly takes me to the login screen, I successfully log in and allow the app (and if I go onto the web separately I can see in my account that the app is there under the authorized apps.)
At this point on my device one of two things happens: 1. something causes the app to disconnect from metro and it hangs on a loading wheel belonging to the greater expo stuff, or 2. It successfully gets back to the app but it redownloads the bundle and the response is null.
What is screwing up here?
I have a Next.js app, I'm using getInitialProps in my _app.js in order to be able to have persistent header and footer. However, I'm also needing to set data in a Context, and I need to be able to fetch the data based off of a cookie value. I've got the basics working just fine, however my _app sets the cookie on the first load, and then when I refresh the page it pulls in the appropriate data. I'm wondering if there's a way to be able to set the cookie first before fetching the data, ensuring that, if there's a cookie present, it will always pull in that data on the first load? Here is my _app.js, and, while I'm still working on the dynamic cookie value in my cookies.set method, I'm able to fetch the right data from my Prismic repo by hard-coding sacramento-ca for now, as you'll see. All I'm really needing is the logic to ensure that the cookie sets, and then the data fetches.
_app.js
import React from 'react';
import { AppLayout } from 'components/app-layout/AppLayout';
import { Footer } from 'components/footer/Footer';
import { Header } from 'components/header/Header';
import { LocationContext } from 'contexts/Contexts';
import Cookies from 'cookies';
import { Client } from 'lib/prismic';
import NextApp, { AppProps } from 'next/app';
import 'styles/base.scss';
import { AppProvider } from 'providers/app-provider/AppProvider';
interface WithNavProps extends AppProps {
navigation: any;
location: string;
dealer?: any;
cookie: string;
}
const App = ({ Component, pageProps, navigation, dealer }: WithNavProps) => {
const { Provider: LocationProvider } = LocationContext;
const locationData = dealer ? dealer : null;
return (
<LocationProvider value={{ locationData }}>
<AppProvider>
<AppLayout>
<Header navigation={navigation} location={dealer} />
<Component {...pageProps} />
<Footer navigation={navigation} />
</AppLayout>
</AppProvider>
</LocationProvider>
);
};
export default App;
App.getInitialProps = async (appContext: any) => {
const appProps = await NextApp.getInitialProps(appContext);
const cookies = new Cookies(appContext.ctx.req, appContext.ctx.res);
try {
cookies.set('dealerLocation', 'sacramento-ca', {
httpOnly: true,
});
const { data: navigation } = await Client.getByUID('navigation', 'main-navigation', {
lang: 'en-us',
});
const results = await Client.getByUID('dealer', cookies.get('dealerLocation'), {
lang: 'en-us',
});
return {
...appProps,
navigation,
dealer: results,
};
} catch {
const { data: navigation } = await Client.getByUID('navigation', 'main-navigation', {
lang: 'en-us',
});
return {
...appProps,
navigation,
};
}
};
I am building a web application in which i need to verify the user's email sent via the client side (React.js and Next.js) and i'm following this youtube tutorial. However, the mentor is using create-react-app CLI and React-Router-Dom for the routing system which doesn't really go with my current needs.
Moreover, I found this method online using HOC :
import React from 'react';
import Router from 'next/router';
const login = '/register?redirected=true'; // Define your login route address.
const checkUserAuthentication = () => {
return { auth: null }; // change null to { isAdmin: true } for test it.
};
export default WrappedComponent => {
const hocComponent = ({ ...props }) => <WrappedComponent {...props} />;
hocComponent.getInitialProps = async (context) => {
const userAuth = await checkUserAuthentication();
// Are you an authorized user or not?
if (!userAuth?.auth) {
// Handle server-side and client-side rendering.
if (context.res) {
context.res?.writeHead(302, {
Location: login,
});
context.res?.end();
} else {
Router.replace(login);
}
} else if (WrappedComponent.getInitialProps) {
const wrappedProps = await WrappedComponent.getInitialProps({...context, auth: userAuth});
return { ...wrappedProps, userAuth };
}
return { userAuth };
};
return hocComponent;
};
The code above helps me to have a private route that the user cannot access unless he's authenticated (currently no programming included), but on the other hand i still need a page in the following route :
'pages/user/activate/[token].js' // the link sent via email from express back end.
What i need now is to create this page using Next routing system in order to get the token and decode it to move forward with the back end and save the user into MongoDB, and in order to accomplish that, i have created my [token].js page with the following code :
import React, {useState, useEffect} from 'react'
import { ToastContainer, toast } from 'react-toastify';
import axios from 'axios';
import jwt from 'jsonwebtoken';
import { authenticate, isAuth } from '../helpers/auth';
import { Link, Redirect } from 'react-router-dom';
const Activate = ({ match }) => {
const [formData, setFormData] = useState({
email: '',
token: '',
show: true
});
const { email, token, show } = formData;
useEffect(() => {
let token = match.params.token;
let { email } = jwt.decode(token);
if (token) {
setFormData({ ...formData, email, token });
}
console.log(token, email);
}, [match.params.token]);
return (
<>
{isAuth() ? <Redirect to="/" /> : null}
<p>Account activated, please log in</p>
</>
)
};
export default Activate;
However, i keep getting this error :
TypeError: Cannot read property 'params' of undefined
at Activate (C:\Users\Hp\Desktop\SMP\client\.next\server\pages\user\activate\[token].js:245:13)
at processChild (C:\Users\Hp\Desktop\SMP\client\node_modules\react-dom\cjs\react-dom-
server.node.development.js:3353:14)
at resolve (C:\Users\Hp\Desktop\SMP\client\node_modules\react-dom\cjs\react-dom-
server.node.development.js:3270:5)
at ReactDOMServerRenderer.render (C:\Users\Hp\Desktop\SMP\client\node_modules\react-dom\cjs\react-
dom-server.node.development.js:3753:22)
at ReactDOMServerRenderer.read (C:\Users\Hp\Desktop\SMP\client\node_modules\react-dom\cjs\react-dom-
server.node.development.js:3690:29)
at renderToString (C:\Users\Hp\Desktop\SMP\client\node_modules\react-dom\cjs\react-dom-
server.node.development.js:4298:27)
at Object.renderPage (C:\Users\Hp\Desktop\SMP\client\node_modules\next\dist\next-
server\server\render.js:53:851)
at Function.getInitialProps (C:\Users\Hp\Desktop\SMP\client\.next\server\pages\_document.js:293:19)
at loadGetInitialProps (C:\Users\Hp\Desktop\SMP\client\node_modules\next\dist\next-
server\lib\utils.js:5:101)
at renderToHTML (C:\Users\Hp\Desktop\SMP\client\node_modules\next\dist\next-
server\server\render.js:53:1142)
I couldn't find a solution because i believe that i'm doing something wrong whether in my code or in the logic implemented.
Is there any way that i can do this properly ?
Thank you in advance !
Best wishes, while I was using the local yoga server, and local docker container as a database, things worked very smoothly because data was loaded in split second, and thus... if someone was signed in, the name of the signed in person immediately appeared on client and server side as well.
Now that I deployed frontend, backend, and database on remote servers, it takes time to load the data. Due to this, The Sign In button stays for 3-4 seconds even if we were already signed in. And late the frontend realizes, that we were signed in and then shows our name.
This happens because we render the data only after we get the data. But when data comes late, the server-side code becomes outdated. Late updating client makes web app feel very lagging.
I am using Next.js
withData.js 👇
import withApollo from 'next-with-apollo'
import ApolloClient from 'apollo-boost'
function createClient({ headers }) {
return new ApolloClient({
uri: `${process.env.ENDPOINT}/graphql`,
request: operation => {
operation.setContext({
fetchOptions: {
credentials: 'include',
},
headers
})
}
})
}
export default withApollo(createClient);
User.js 👇
import { Query } from 'react-apollo'
import gql from 'graphql-tag'
import PropTypes from 'prop-types'
import { client } from '../lib/withData'
export const CURRENT_USER_QUERY = gql`
query {
me {
id
name
fname
lname
email
phone
bio
previledge
gender
username
birthday
profilePicture
signUpMethod
}
}
`
const User = props => (
<Query {...props} query={CURRENT_USER_QUERY}>
{payload => {
return props.children(payload)
}}
</Query>
)
export default User
SignInButton.js 👇
<User>
{({data: {me}}) => (
{ me ? <ProfileButton me={me} /> : <li style={{backgroundColor: '#ffffff', color: '#000000', borderRadius: '5px', padding: '5px 10px', zoom: '80%'}}><a href={`${meta.domain}/signin?intent=${this.props.router.asPath}`} style={{color: '#000000'}}>⚡️🚦 {this.signInText}</a></li> }
)}
</User>
pages/_app.js 👇
import App, { Container } from 'next/app'
import { ApolloProvider } from 'react-apollo'
import withData from '../src/lib/withData'
import Page from '../src/components/Page'
class Wrapper extends App {
static getInitialProps({Component, ctx}){
let pageProps = {}
if(Component.getInitialProps){
pageProps = Component.getInitialProps(ctx)
}
// This exposes query to the user
pageProps.query = ctx.query
return { pageProps }
}
render() {
const { Component, apollo, pageProps } = this.props
return (
<Container>
<ApolloProvider client={apollo}>
<Page>
<div className="super_container"><Component {...pageProps} /></div>
</Page>
</ApolloProvider>
</Container>
)
}
}
export default withData(Wrapper)
How do I render the data from react-apollo on the server side?
Found these resources but difficult to implement with the stack I use.
https://bessey.dev/blog/2019/01/02/apollo-graphql-hypernova/
https://github.com/i18next/react-i18next/issues/593
https://shaleenjain.com/blog/nextjs-apollo-prefetch/
If you want SSR by query so you can populate head and other stuff directly in serverSide, you need to make the query directly in
You need to create the query inside the GetInitialProps function like this :
Page.getInitialProps = async ({
apolloClient, query, children, router, href
}) => {
const { data, error, loading } = await apolloClient.query({ query: LIVRE_QUERY, variables: { slug: query.titre } })
if (error) {
return <div>Erreur</div>
}
return { data, error, loading }
}