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/ConnectButton without Moralis Server #143

Merged
merged 12 commits into from
Feb 15, 2022
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ const App = () => (
- [💿 Installation](#-installation)
- [🧰 Usage](#-usage)
- [🧭 Table of contents](#-table-of-contents)
- [⛓ Web3 Components](#-web3-components)
- [`<ConnectButton />`](#connectbutton-)
- [📖 UI Components](#-ui-components)
- [`<Avatar />`](#avatar-)
- [`<BannerStrip />`](#bannerstrip-)
Expand All @@ -79,6 +81,22 @@ const App = () => (
- [`<Modal />`](#modal-)
- [`<Tooltip />`](#tooltip-)


# ⛓ `Web3 Components`

### `<ConnectButton />`

![ConnectBtnNew](https://user-images.githubusercontent.com/78314301/154008380-9f49c070-7886-4b76-ad83-4222b2a78c99.gif)

The `<ConnectButton />` component allows you to make [web3 authenticating](https://github.com/MoralisWeb3/react-moralis#authenticate-web3) users in case your server is initialized. When the server is not initialized, or for example, you have `<MoralisProvider initializeOnMount={false} >` and you don't want to connect your Moralis server to the frontend the smart component will call [enableWeb3()](https://github.com/MoralisWeb3/react-moralis#enable-web3-via-metamask)

If you want to use this component with the connected server but without adding a user to Moralis Database you can add the `moralisAuth` prop <ConnectButton moralisAuth={false} />

The ConnectButton component automatically adds to the local storage info about the connector user used and will automatically call enableWeb3() after rereshing the page. So if user was connected once it will automatically initialize web3 connection(No need anymore to add UseEffect hook for enableWeb3() after refrshing the page)

Try the `<ConnectButton />` component in the [interactive documentation](https://web3ui.github.io/web3uikit/?path=/docs/web3-connectbutton--default)


# 📖 `UI Components`

### `<Avatar />`
Expand Down
10 changes: 9 additions & 1 deletion src/components/ConnectButton/ConnectButton.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,15 @@ export default {
} as ComponentMeta<typeof ConnectButton>;

const Template: ComponentStory<typeof ConnectButton> = (args) => (
<ConnectButton {...args} />
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
<ConnectButton {...args} />
</div>
);

export const Default = Template.bind({});
8 changes: 4 additions & 4 deletions src/components/ConnectButton/ConnectButton.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ const flexBox = css`
`;

const WrapperStyled = styled.div`
${flexBox}
${flexBox};
height: 40px;
margin: 0px 16px;
margin: 0 16px;
white-space: nowrap;
`;

const AccountInfoStyled = styled.div`
${flexBox}
${flexBox};
background-color: ${color.blueLight};
border-radius: 16px;
flex-direction: row;
Expand Down Expand Up @@ -45,7 +45,7 @@ const ConnectButtonStyled = styled.button`
`;

const AddressStyled = styled.div`
${flexBox}
${flexBox};
background: ${color.white};
border-radius: 12px;
border: 1px solid transparent;
Expand Down
70 changes: 61 additions & 9 deletions src/components/ConnectButton/ConnectButton.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { default as MoralisType } from 'moralis/types';
import React, { useEffect, useState } from 'react';
import { useMoralis } from 'react-moralis';
import { getEllipsisTxt } from '../../web3utils';
import { Blockie } from '../Blockie';
import { NativeBalance } from '../NativeBalance';
import { WalletModal } from '../WalletModal';
import ConnectButtonStyles from './ConnectButton.styles';
import { ConnectButtonProps } from './types';

const {
WrapperStyled,
Expand All @@ -15,7 +17,11 @@ const {
BalanceBlockStyled,
} = ConnectButtonStyles;

const ConnectButton: React.FC = () => {
type web3StatusType = 'disconnected' | 'pending' | 'only_web3';

const ConnectButton: React.FC<ConnectButtonProps> = ({
moralisAuth = true,
}) => {
const {
account,
isAuthenticated,
Expand All @@ -25,28 +31,74 @@ const ConnectButton: React.FC = () => {
isWeb3Enabled,
isInitialized,
isWeb3EnableLoading,
isAuthenticating,
authenticate,
Moralis,
} = useMoralis();

const [isConnectModalOpen, setIsConnectModalOpen] = useState(false);
const [web3Status, setWeb3Status] =
useState<web3StatusType>('disconnected');

useEffect(() => {
if (!isInitialized) return;
const connectorId = window.localStorage.getItem('connectorId');
if (isAuthenticated && !isWeb3Enabled && !isWeb3EnableLoading) {
// to avoid problems in Next.JS apps because of window object
if (typeof window == 'undefined') return;

const connectorId = window.localStorage.getItem(
'connectorId',
) as MoralisType.Web3ProviderType;
if (
!isWeb3Enabled &&
!isWeb3EnableLoading &&
connectorId &&
web3Status === 'disconnected'
) {
// @ts-ignore
enableWeb3({ provider: connectorId });
setWeb3Status('pending');
enableWeb3({
provider: connectorId,
onSuccess: () => setWeb3Status('only_web3'),
});
}
}, [isAuthenticated, isWeb3Enabled, isInitialized]);
}, [isWeb3Enabled, isWeb3EnableLoading, web3Status]);

useEffect(() => {
// to avoid problems in Next.JS apps because of window object
if (typeof window == 'undefined') return;

function disconnectWallet() {
const connectorId = window.localStorage.getItem(
'connectorId',
) as MoralisType.Web3ProviderType;
if (
isInitialized &&
!isAuthenticated &&
!isAuthenticating &&
isWeb3Enabled &&
moralisAuth &&
web3Status === 'only_web3'
) {
authenticate({ provider: connectorId });
}
}, [isAuthenticated, isInitialized, isWeb3Enabled, isAuthenticating]);

useEffect(() => {
Moralis.onAccountChanged((address) => {
if (!address) disconnectWallet();
});
}, []);

async function disconnectWallet() {
// to avoid problems in Next.JS apps because of localStorage
if (typeof window == 'undefined') return;

logout();
window.localStorage.removeItem('connectorId');
setWeb3Status('disconnected');

deactivateWeb3();
if (isInitialized) logout();
}

if (!account || !isAuthenticated) {
if (!account || (isInitialized && !isAuthenticated)) {
return (
<WrapperStyled>
<ConnectButtonStyled
Expand Down
7 changes: 6 additions & 1 deletion src/components/ConnectButton/types.ts
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
export interface ConnectButtonProps {}
export interface ConnectButtonProps {
/**
* if true & server is connected & web3 is enabled will automatically try to connect user to the server
*/
moralisAuth?: boolean;
}
16 changes: 12 additions & 4 deletions src/components/NativeBalance/NativeBalance.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { useNativeBalance } from 'react-moralis';
import React, { useEffect } from 'react';
import { useNativeBalance, useMoralis } from 'react-moralis';
import NativeBalanceStyles from './NativeBalance.styles';
import { NativeBalanceProps } from './types';

Expand All @@ -10,9 +10,17 @@ const NativeBalance: React.FC<NativeBalanceProps> = ({
options,
style,
}) => {
const { data: balance } = useNativeBalance(params, options);
const { account, chainId } = useMoralis();
const { data: balance, getBalances } = useNativeBalance(params, {
autoFetch: false,
...options,
});

if (!balance?.formatted) return null;
useEffect(() => {
if (account && chainId) getBalances();
}, [account, chainId]);

if (!balance?.formatted || !account) return null;

return <BalanceStyled style={style}>{balance.formatted}</BalanceStyled>;
};
Expand Down
52 changes: 26 additions & 26 deletions src/components/WalletModal/WalletModal.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
import WalletModal from '../../components/WalletModal/WalletModal';
import { moralisContext } from '../../decorators';
import { useArgs } from '@storybook/addons';
export default {
title: 'Web3/WalletModal',
component: WalletModal,
decorators: [moralisContext],
} as ComponentMeta<typeof WalletModal>;
const Template: ComponentStory<typeof WalletModal> = (args) => {
const [{}, updateArgs] = useArgs();
return (
<WalletModal
{...args}
setIsOpened={() => updateArgs({ isOpened: false })}
/>
);
};
export const DefaultWalletModal = Template.bind({});
DefaultWalletModal.args = {
isOpened: true,
};
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
import WalletModal from '../../components/WalletModal/WalletModal';
import { moralisContext } from '../../decorators';
import { useArgs } from '@storybook/addons';

export default {
title: 'Web3/WalletModal',
component: WalletModal,
decorators: [moralisContext],
} as ComponentMeta<typeof WalletModal>;

const Template: ComponentStory<typeof WalletModal> = (args) => {
const [{}, updateArgs] = useArgs();
return (
<WalletModal
{...args}
setIsOpened={() => updateArgs({ isOpened: false })}
/>
);
};

export const DefaultWalletModal = Template.bind({});
DefaultWalletModal.args = {
isOpened: true,
};
5 changes: 2 additions & 3 deletions src/components/WalletModal/WalletModal.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const WrapperStyled = styled.div`
const ModalStyled = styled.div`
background-color: ${color.white};
border-radius: 20px;
box-shadow: 0px 4px 10px rgba(48, 71, 105, 0.1);
box-shadow: 0 4px 10px rgba(48, 71, 105, 0.1);
display: flex;
flex-direction: column;
margin: 10px;
Expand All @@ -38,8 +38,7 @@ const HeaderStyled = styled.div`
align-items: center;
display: flex;
justify-content: space-between;
padding: 20px;
padding-bottom: 12px;
padding: 20px 20px 12px;
`;

const GridStyled = styled.div`
Expand Down
Loading