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

features & improvements #186

Merged
merged 19 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .changeset/selfish-buses-compete.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
'@web3modal/coinbase-wagmi-react-native': major
'@web3modal/scaffold-utils-react-native': major
'@web3modal/email-wagmi-react-native': major
'@web3modal/scaffold-react-native': major
'@web3modal/ethers5-react-native': major
'@web3modal/common-react-native': major
'@web3modal/ethers-react-native': major
'@web3modal/email-react-native': major
'@web3modal/wagmi-react-native': major
'@web3modal/core-react-native': major
'@web3modal/siwe-react-native': major
'@web3modal/ui-react-native': major
'@web3modal/coinbase-ethers-react-native': major
'@web3modal/email-ethers-react-native': major
---

Migration to Wagmi 2, implemented SIWE + One-Click Auth, general improvements
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,7 @@ android.iml
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
!.yarn/versions

# vscode
.vscode/launch.json
2 changes: 1 addition & 1 deletion apps/gallery/stories/composites/WalletImage.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const meta: Meta<typeof WalletImage> = {
control: { type: 'text' }
},
size: {
options: ['sm', 'md', 'lg'],
options: ['sm', 'md', 'lg', 'xl'],
control: { type: 'select' }
}
},
Expand Down
2 changes: 1 addition & 1 deletion apps/gallery/utils/PresetUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const walletImageSrc =
'https://explorer-api.walletconnect.com/w3m/v1/getWalletImage/7a33d7f1-3d12-4b5c-f3ee-5cd83cb1b500?projectId=90369b5c91c6f7fffe308df2b30f3ace';

export const networkImageSrc =
'https://explorer-api.walletconnect.com/w3m/v1/getAssetImage/692ed6ba-e569-459a-556a-776476829e00?projectId=90369b5c91c6f7fffe308df2b30f3ace';
'https://explorer-api.walletconnect.com/w3m/v1/getAssetImage/ba0ba0cd-17c6-4806-ad93-f9d174f17900?projectId=90369b5c91c6f7fffe308df2b30f3ace';

export const avatarImageSrc =
'https://i.seadn.io/gcs/files/007a5af0d93d561f87c8d026ddd5179e.png?auto=format&dpr=1&w=1000';
Expand Down
7 changes: 4 additions & 3 deletions apps/native-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,16 @@
"@react-native-async-storage/async-storage": "1.18.2",
"@react-native-clipboard/clipboard": "1.13.0",
"@react-native-community/netinfo": "9.3.10",
"@walletconnect/react-native-compat": "2.10.5",
"@tanstack/react-query": "5.37.1",
"@walletconnect/react-native-compat": "2.13.1",
"@web3modal/wagmi-react-native": "1.4.4",
"react": "18.2.0",
"react-native": "0.72.6",
"react-native-get-random-values": "~1.9.0",
"react-native-modal": "13.0.1",
"react-native-svg": "13.9.0",
"viem": "1.19.3",
"wagmi": "1.4.7"
"viem": "2.13.1",
"wagmi": "2.9.7"
},
"devDependencies": {
"@babel/core": "^7.20.0",
Expand Down
84 changes: 32 additions & 52 deletions apps/native/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { StyleSheet, View, useColorScheme } from 'react-native';
import { StatusBar } from 'expo-status-bar';
import * as Clipboard from 'expo-clipboard';
import '@walletconnect/react-native-compat';
import { WagmiConfig } from 'wagmi';
import { WagmiProvider } from 'wagmi';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

import {
Web3Modal,
Expand All @@ -11,46 +12,21 @@ import {
createWeb3Modal,
defaultWagmiConfig
} from '@web3modal/wagmi-react-native';
import { EmailConnector } from '@web3modal/email-wagmi-react-native';

import {
arbitrum,
mainnet,
polygon,
avalanche,
bsc,
optimism,
gnosis,
zkSync,
zora,
base,
celo,
aurora
} from 'wagmi/chains';
import { emailConnector } from '@web3modal/email-wagmi-react-native';

import { siweConfig } from './src/utils/SiweUtils';

import { AccountView } from './src/views/AccountView';
import { ActionsView } from './src/views/ActionsView';
import { getCustomWallets } from './src/utils/misc';
import { chains } from './src/utils/WagmiUtils';

const projectId = process.env.EXPO_PUBLIC_PROJECT_ID ?? '';

const chains = [
mainnet,
polygon,
arbitrum,
avalanche,
bsc,
optimism,
gnosis,
zkSync,
zora,
base,
celo,
aurora
];

const metadata = {
name: 'Web3Modal v3',
description: 'Web3Modal v3 by WalletConnect',
name: 'Web3Modal RN',
description: 'Web3Modal RN by WalletConnect',
url: 'https://walletconnect.com/',
icons: ['https://avatars.githubusercontent.com/u/37784886'],
redirect: {
Expand All @@ -64,21 +40,23 @@ const clipboardClient = {
}
};

const emailConnector = new EmailConnector({ chains, options: { projectId, metadata } });
const emailConn = emailConnector({ projectId, metadata });

const wagmiConfig = defaultWagmiConfig({
chains,
projectId,
metadata,
extraConnectors: [emailConnector]
extraConnectors: [emailConn]
});

const queryClient = new QueryClient();

const customWallets = getCustomWallets();

createWeb3Modal({
projectId,
chains,
wagmiConfig,
siweConfig,
clipboardClient,
customWallets,
enableAnalytics: true,
Expand All @@ -89,22 +67,24 @@ export default function Native() {
const isDarkMode = useColorScheme() === 'dark';

return (
<WagmiConfig config={wagmiConfig}>
<View style={[styles.container, isDarkMode && styles.dark]}>
<StatusBar style="auto" />
<W3mButton
connectStyle={styles.button}
accountStyle={styles.button}
label="Connect"
loadingLabel="Connecting..."
balance="show"
/>
<W3mNetworkButton />
<AccountView />
<ActionsView />
<Web3Modal />
</View>
</WagmiConfig>
<WagmiProvider config={wagmiConfig}>
<QueryClientProvider client={queryClient}>
<View style={[styles.container, isDarkMode && styles.dark]}>
<StatusBar style="auto" />
<W3mButton
connectStyle={styles.button}
accountStyle={styles.button}
label="Connect"
loadingLabel="Connecting..."
balance="show"
/>
<W3mNetworkButton />
<AccountView />
<ActionsView />
<Web3Modal />
</View>
</QueryClientProvider>
</WagmiProvider>
);
}

Expand Down
9 changes: 6 additions & 3 deletions apps/native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
"dependencies": {
"@react-native-async-storage/async-storage": "1.21.0",
"@react-native-community/netinfo": "11.1.0",
"@walletconnect/react-native-compat": "2.10.5",
"@tanstack/query-async-storage-persister": "^5.40.0",
"@tanstack/react-query": "5.37.1",
"@tanstack/react-query-persist-client": "^5.40.0",
"@walletconnect/react-native-compat": "2.13.1",
"@web3modal/email-wagmi-react-native": "1.4.4",
"@web3modal/wagmi-react-native": "1.4.4",
"expo": "^50.0.14",
Expand All @@ -34,8 +37,8 @@
"react-native-web": "~0.19.6",
"react-native-webview": "13.6.4",
"uuid": "3.4.0",
"viem": "1.19.3",
"wagmi": "1.4.7"
"viem": "2.13.1",
"wagmi": "2.9.7"
},
"devDependencies": {
"@babel/core": "^7.20.0",
Expand Down
78 changes: 78 additions & 0 deletions apps/native/src/utils/SiweUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/* eslint-disable @typescript-eslint/no-unused-vars */

import { generateRandomBytes32 } from '@walletconnect/utils';
import {
createSIWEConfig,
formatMessage,
type SIWEVerifyMessageArgs,
type SIWECreateMessageArgs
} from '@web3modal/siwe-react-native';
import { chains } from './WagmiUtils';
import AsyncStorage from '@react-native-async-storage/async-storage';

const LOGGED_IN_KEY = '@w3mwagmi/logged_in';

export const siweConfig = createSIWEConfig({
signOutOnAccountChange: false,
signOutOnNetworkChange: false,
// We don't require any async action to populate params but other apps might

getMessageParams: async () => {
// Parameters to create the SIWE message internally.
// More info in https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-222.method

return {
domain: 'com.walletconnect.web3modal.rnsample', //your bundle id or app id
uri: 'redirect://', // your redirect uri
chains: chains.map(chain => chain.id),
statement: 'Please sign with your account',
iat: new Date().toISOString()
};
},
createMessage: ({ address, ...args }: SIWECreateMessageArgs): string => {
// Method for generating an EIP-4361-compatible message.
return formatMessage(args, address);
},
getNonce: async (): Promise<string> => {
// The getNonce method functions as a safeguard
// against spoofing, akin to a CSRF token.

const nonce = generateRandomBytes32();

return nonce;
},
getSession: async () => {
// The backend session should store the associated address and chainId
// and return it via the `getSession` method.

const logged = await AsyncStorage.getItem(LOGGED_IN_KEY);
if (logged === 'true') {
return {
address: '0x',
chainId: 1
};
}

return null;
},

verifyMessage: async ({ message, signature, cacao }: SIWEVerifyMessageArgs): Promise<boolean> => {
// This function ensures the message is valid,
// has not been tampered with, and has been appropriately
// signed by the wallet address.

// Call your sign-in backend function here and save the session
// api.signIn({ message, signature, cacao });

// Just a mock. You should save a token or whatever your backend needs
await AsyncStorage.setItem(LOGGED_IN_KEY, 'true');

return true;
},
signOut: async (): Promise<boolean> => {
// The users session must be destroyed when calling `signOut`.
await AsyncStorage.removeItem(LOGGED_IN_KEY);

return true;
}
});
33 changes: 33 additions & 0 deletions apps/native/src/utils/WagmiUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { CreateConfigParameters } from 'wagmi';

import {
arbitrum,
mainnet,
polygon,
avalanche,
bsc,
optimism,
gnosis,
zkSync,
zora,
base,
celo,
aurora,
sepolia
} from '@wagmi/core/chains';

export const chains: CreateConfigParameters['chains'] = [
mainnet,
polygon,
avalanche,
arbitrum,
bsc,
optimism,
gnosis,
zkSync,
zora,
base,
celo,
aurora,
sepolia
];
27 changes: 14 additions & 13 deletions apps/native/src/views/ActionsView.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,35 @@
import { Button, Text } from '@web3modal/ui-react-native';
import { View } from 'react-native';
import { useSignMessage, useAccount, useSendTransaction } from 'wagmi';
import { parseEther } from 'viem';
import { useSignMessage, useAccount, useSendTransaction, useEstimateGas } from 'wagmi';
import { Hex, parseEther } from 'viem';

export function ActionsView() {
const { isConnected } = useAccount();
const { data, isError, isLoading, isSuccess, signMessage } = useSignMessage({
message: 'Hello Web3Modal!'
});
const { data, isError, isPending, isSuccess, signMessage } = useSignMessage();
const TX = {
to: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045' as Hex, // vitalik.eth
value: parseEther('0.001'),
data: '0x' as Hex
};
const { data: gas, isError: isGasError } = useEstimateGas(TX);

const {
data: sendData,
isLoading: isSending,
isPending: isSending,
isSuccess: isSendSuccess,
sendTransaction
} = useSendTransaction({
to: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', //vitalik.etch
value: parseEther('0.01'),
data: '0x'
});
} = useSendTransaction();

return isConnected ? (
<View>
<Text variant="large-600">Wagmi Actions</Text>
<Button disabled={isLoading} onPress={() => signMessage()}>
<Button disabled={isPending} onPress={() => signMessage({ message: 'Hello Web3Modal!' })}>
Sign
</Button>
{isSuccess && <Text>Signature: {data}</Text>}
{isGasError && <Text>Error estimating gas</Text>}
{isError && <Text>Error signing message</Text>}
<Button disabled={isSending} onPress={() => sendTransaction()}>
<Button disabled={isSending} onPress={() => sendTransaction({ ...TX, gas })}>
Send
</Button>
{isSending && <Text>Check Wallet</Text>}
Expand Down
3 changes: 1 addition & 2 deletions jest.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
module.exports = {
preset: 'react-native',
modulePathIgnorePatterns: ['<rootDir>/node_modules', '<rootDir>/packages/*/lib/'],
coverageReporters: ['lcovonly']
modulePathIgnorePatterns: ['<rootDir>/node_modules', '<rootDir>/lib/']
};
Loading
Loading