Skip to content

Commit

Permalink
feat: allow custom button for connecting (#74)
Browse files Browse the repository at this point in the history
* feat: allow custom button for connecting

* fix: private constructors

* fix: theme types

* fix: linting typescript

* fix: merge main

* fix: connect wallet not working

* fix: fix ts issues
  • Loading branch information
darrenvechain authored Nov 13, 2023
1 parent adcacc0 commit dbe61c2
Show file tree
Hide file tree
Showing 34 changed files with 336 additions and 161 deletions.
22 changes: 19 additions & 3 deletions apps/sample-react-app/src/Components/SwitchWalletButton.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import type { HTMLChakraProps } from '@chakra-ui/react';
import { useDisclosure } from '@chakra-ui/react';
import { Button, Icon, useDisclosure } from '@chakra-ui/react';
import React from 'react';
import {
ConnectWalletButton,
ConnectWalletModal,
useWallet,
useWalletModal,
} from '@vechainfoundation/react-wallet-kit';
import { WalletIcon } from '@heroicons/react/24/solid';
import { AccountDetailModal } from './AccountDetailModal';
import { AddressButton } from './AddressButton';

Expand All @@ -19,6 +21,8 @@ export const SwitchWalletButton: React.FC<SwitchWalletButtonProps> = ({

const { account, source } = useWallet();

const { open } = useWalletModal();

if (account && source)
return (
<>
Expand All @@ -37,5 +41,17 @@ export const SwitchWalletButton: React.FC<SwitchWalletButtonProps> = ({
</>
);

return <ConnectWalletButton buttonProps={buttonProps} />;
return (
<>
<ConnectWalletModal />

<Button
{...buttonProps}
leftIcon={<Icon as={WalletIcon} />}
onClick={open}
>
Connect Wallet
</Button>
</>
);
};
57 changes: 55 additions & 2 deletions packages/react-wallet-kit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ yarn build
yarn add @vechainfoundation/react-wallet-kit
```

- Create the node options

```typescript
import type { Options } from '@vechain/connex';

Expand Down Expand Up @@ -89,3 +87,58 @@ const { account } = await connect();
//Start using Connex thor/ vendor
const { vendor, thor } = useConnex();
```

### UI Option 1: Modal + Button

- Use the `ConnectWalletButton` component to display a modal with the available wallets

```typescript jsx
import { ConnectWalletButton } from '@vechainfoundation/react-wallet-kit';
import { useWallet } from '@vechainfoundation/react-wallet-kit';

const MyComponent = (): JSX.Element => {
const { account } = useWallet();

useEffect(() => {
if (account) {
// account connected!!
}
}, [account]);

return (
<>
<ConnectWalletButton />
</>
);
};
```

### Option 2: Modal + Custom Button

- Use the `ConnectWalletModal` component to display a modal with the available wallets

```typescript jsx
import {
ConnectWalletModal,
useWallet,
useWalletModal,
} from '@vechainfoundation/react-wallet-kit';

export const MyComponent = (): JSX.Element => {
const { account } = useWallet();
const { open, close } = useWalletModal();

useEffect(() => {
if (account) {
// account connected!!
}
}, [account]);

return (
<>
<button onClick={open}>Connect Wallet</button>
<ConnectWalletModal />
</>
);
};
```
2 changes: 1 addition & 1 deletion packages/react-wallet-kit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"build": "tsup src/index.tsx --format cjs --dts --external react",
"clean": "rm -rf dist .turbo",
"dev": "tsup src/index.tsx --format cjs --watch --dts --external react",
"lint": "eslint src --ext .js,.jsx,.ts,.tsx",
"lint": "tsc --noEmit && eslint src --ext .js,.jsx,.ts,.tsx",
"purge": "yarn clean && rm -rf node_modules"
},
"dependencies": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import type { ReactNode } from 'react';
import { useCallback, useContext, useState } from 'react';
import type { WalletSource } from '@vechainfoundation/wallet-kit';
import type { SourceInfo } from '@vechainfoundation/vanilla-wallet-kit';
import { ThemeContext } from '../../provider/ThemeProvider';
import { useWallet } from '../../ConnexProvider';
import { ThemeContext } from '../../../provider/ThemeProvider';
import { useWallet } from '../../../ConnexProvider';
import { ConnectModalWithButtonWrapped } from './Wrapped/ConnectModalWithButtonWrapped';

interface ConnectButtonWithModalProps {
Expand All @@ -12,10 +11,12 @@ interface ConnectButtonWithModalProps {

export const ConnectButtonWithModal = ({

Check warning on line 12 in packages/react-wallet-kit/src/Components/ConnectWalletButtonWithModal/Components/ConnectButtonWithModal.tsx

View workflow job for this annotation

GitHub Actions / Lint, Build & Test

Missing return type on function
onClose,
}: ConnectButtonWithModalProps): ReactNode => {
}: ConnectButtonWithModalProps) => {
const { theme } = useContext(ThemeContext);

const handleSourceClick = (e: SourceInfo): void => {
const handleSourceClick = (e: SourceInfo | undefined): void => {
if (!e) return;

_connect(e.id);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import type { HTMLChakraProps } from '@chakra-ui/react';
import React from 'react';
import GlobalFonts from '../../assets/fonts/fonts';
import { ThemeProvider } from '../provider/ThemeProvider';
import { ThemeSelector } from './Components/ThemeSelector';
import GlobalFonts from '../../../assets/fonts/fonts';
import { ThemeProvider } from '../../provider/ThemeProvider';
import { ThemeSelector } from '../ThemeSelector';
import { ConnectButtonWithModal } from './Components/ConnectButtonWithModal';

interface ConnectWalletButtonProps {
buttonProps?: HTMLChakraProps<'button'>;
}

export const ConnectWalletButton: React.FC<
export const ConnectWalletButtonWithModal: React.FC<
ConnectWalletButtonProps
> = (): React.ReactElement => {
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React, { useCallback } from 'react';
import type { WalletSource } from '@vechainfoundation/wallet-kit';
import type { SourceInfo } from '@vechainfoundation/vanilla-wallet-kit';
import { ConnectModal } from '@vechainfoundation/vanilla-wallet-kit';
import { createComponent } from '@lit/react';
import GlobalFonts from '../../../assets/fonts/fonts';
import { ThemeProvider } from '../../provider/ThemeProvider';
import { ThemeSelector } from '../ThemeSelector';
import { useWallet } from '../../ConnexProvider';

export const ConnectModalWrapped = createComponent({
tagName: 'vwk-connect-modal',
elementClass: ConnectModal,
react: React,
});

export const ConnectWalletModal: React.FC = (): React.ReactElement => {
const { setSource, connect, setAccount } = useWallet();

const connectHandler = useCallback(
async (source: WalletSource) => {
setSource(source);

const { account } = await connect();

setAccount(account);
},
[connect, setAccount, setSource],
);

const _connect = useCallback(
(source?: SourceInfo) => {
if (source) {
connectHandler(source.id).catch(() => {
// do nothing
});
}
},
[connectHandler],
);

return (
<ThemeProvider>
<GlobalFonts />
<ConnectModalWrapped onSourceClick={_connect} open={false} />
<ThemeSelector />
</ThemeProvider>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './ConnectWalletModal';
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
// ThemeSelector.js

import type { ReactNode } from 'react';
import React, { useContext } from 'react';
// eslint-disable-next-line import/no-named-as-default
import styled from 'styled-components';
import { ThemeContext } from '../../provider/ThemeProvider';
import { ThemeContext } from '../provider/ThemeProvider';

const Button = styled.button``;

const ThemeSelector = (): ReactNode => {
const ThemeSelector = () => {

Check warning on line 10 in packages/react-wallet-kit/src/Components/ThemeSelector.tsx

View workflow job for this annotation

GitHub Actions / Lint, Build & Test

Missing return type on function
const { toggleTheme } = useContext(ThemeContext);

return <Button onClick={toggleTheme}>Toggle Theme</Button>;
Expand Down
2 changes: 2 additions & 0 deletions packages/react-wallet-kit/src/Components/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './ConnectWalletModal';
export * from './ConnectWalletButtonWithModal';

This file was deleted.

This file was deleted.

53 changes: 47 additions & 6 deletions packages/react-wallet-kit/src/ConnexProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import React, {
useState,
} from 'react';
import type { WalletSource } from '@vechainfoundation/wallet-kit';
import { MultiWalletConnex } from '@vechainfoundation/wallet-kit';
import { DAppKit } from '@vechainfoundation/vanilla-wallet-kit';
import type { ConnexContext, ConnexProviderOptions } from './types';

const STORAGE_PREFIX = '@vechainfoundation/wallet-kit';
Expand All @@ -26,7 +26,9 @@ const remove = (key: 'source' | 'account'): void => {
/**
* Context
*/
const Context = createContext<ConnexContext>({} as ConnexContext);
const ConnexProviderContext = createContext<ConnexContext | undefined>(
undefined,
);

export const ConnexProvider: React.FC<ConnexProviderOptions> = ({
children,
Expand All @@ -43,7 +45,7 @@ export const ConnexProvider: React.FC<ConnexProviderOptions> = ({

const connex = useMemo(
() =>
new MultiWalletConnex({
DAppKit.configure({
nodeUrl: nodeOptions.node,
genesis: nodeOptions.network,
walletConnectOptions,
Expand Down Expand Up @@ -137,6 +139,14 @@ export const ConnexProvider: React.FC<ConnexProviderOptions> = ({
[persistState],
);

const openModal = useCallback(() => {
DAppKit.modal.open();
}, []);

const closeModal = useCallback(() => {
DAppKit.modal.close();
}, []);

const context: ConnexContext = useMemo(() => {
return {
connex: {
Expand All @@ -152,6 +162,10 @@ export const ConnexProvider: React.FC<ConnexProviderOptions> = ({
account,
source,
},
modal: {
open: openModal,
close: closeModal,
},
};
}, [
connex.thor,
Expand All @@ -163,17 +177,44 @@ export const ConnexProvider: React.FC<ConnexProviderOptions> = ({
availableWallets,
account,
source,
closeModal,
openModal,
]);

return <Context.Provider value={context}>{children}</Context.Provider>;
return (
<ConnexProviderContext.Provider value={context}>
{children}
</ConnexProviderContext.Provider>
);
};

export const useConnex = (): ConnexContext['connex'] => {
const context = useContext(Context);
const context = useContext(ConnexProviderContext);

if (!context) {
throw new Error('"useConnex" must be used within a ConnexProvider');
}

return context.connex;
};

export const useWallet = (): ConnexContext['wallet'] => {
const context = useContext(Context);
const context = useContext(ConnexProviderContext);

if (!context) {
throw new Error('"useWallet" must be used within a ConnexProvider');
}

return context.wallet;
};

export const useWalletModal = (): ConnexContext['modal'] => {
const context = useContext(ConnexProviderContext);

if (!context) {
throw new Error(
'"useWalletModal" must be used within a ConnexProvider',
);
}
return context.modal;
};
2 changes: 1 addition & 1 deletion packages/react-wallet-kit/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ import * as React from 'react';

export * from './ConnexProvider';
export * from './types';
export * from './ConnectWalletButton';
export * from './Components';
Loading

0 comments on commit dbe61c2

Please sign in to comment.