Skip to content

Commit

Permalink
feat: link mode (#158)
Browse files Browse the repository at this point in the history
* feat: link-mode

* chore: added socket connection listeners + toasts

* feat: added logs screen

* feat: added logs to wallet settings

* fix: added wc: old links to listener

* chore: added new loaders + moved deeplink logic to root App file

* chore: removed extra gradle cache from action

* chore: added minimizer to go back to browsers in android

* chore: show unsupported chain modal
  • Loading branch information
ignaciosantise authored Sep 6, 2024
1 parent c6520a0 commit fbde29c
Show file tree
Hide file tree
Showing 61 changed files with 3,048 additions and 2,175 deletions.
10 changes: 0 additions & 10 deletions .github/workflows/release-android-base.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,6 @@ jobs:
architecture: x86_64
cache: 'gradle'

- name: Cache Gradle
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Create env file
run: touch ${{ inputs.root-path }}/.env.${{ inputs.release-type }} && echo -e "ENV_PROJECT_ID=${{ secrets.project-id }}\nENV_RELAY_URL=${{ secrets.relay-url }}\nENV_SENTRY_DSN=${{ secrets.sentry-dsn }}\nENV_SENTRY_TAG=${{ inputs.release-type }}" >> ${{ inputs.root-path }}/.env.${{ inputs.release-type }}

Expand Down
2 changes: 1 addition & 1 deletion dapps/W3MWagmi/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Web3Modal + Wagmi example
# AppKit + Wagmi example

## Getting Started

Expand Down
2 changes: 1 addition & 1 deletion dapps/W3MWagmi/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ android {
applicationId "com.walletconnect.web3modal.rnsample"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 34
versionCode 57
versionName "1.1"
resValue "string", "build_config_package", "com.w3mwagmi"
}
Expand Down
8 changes: 8 additions & 0 deletions dapps/W3MWagmi/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
<intent-filter android:autoVerify="true">
<data android:scheme="https"/>
<data android:host="lab.web3modal.com"/>
<data android:pathPrefix="/rn_appkit"/>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
</application>
</manifest>
1 change: 1 addition & 0 deletions dapps/W3MWagmi/babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module.exports = {
'@/screens': './src/screens',
'@/types': './src/types',
'@/utils': './src/utils',
'@/stores': './src/stores',
},
},
],
Expand Down
4 changes: 2 additions & 2 deletions dapps/W3MWagmi/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -979,7 +979,7 @@ PODS:
- React-Mapbuffer (0.74.3):
- glog
- React-debug
- react-native-compat (2.15.2):
- react-native-compat (2.16.0):
- DoubleConversion
- glog
- hermes-engine
Expand Down Expand Up @@ -1611,7 +1611,7 @@ SPEC CHECKSUMS:
React-jsitracing: 6b3c8c98313642140530f93c46f5a6ca4530b446
React-logger: fa92ba4d3a5d39ac450f59be2a3cec7b099f0304
React-Mapbuffer: 9f68550e7c6839d01411ac8896aea5c868eff63a
react-native-compat: 480399574fd82075838ab3da5ed7cfdc31574dad
react-native-compat: 389cd76a1c6ce2a6d5fd868f2c76056cff403db8
react-native-config: d7d8a0c65f7fa523197879f6b777997abbfc987e
react-native-get-random-values: 21325b2244dfa6b58878f51f9aa42821e7ba3d06
react-native-mmkv: 8c9a677e64a1ac89b0c6cf240feea528318b3074
Expand Down
284 changes: 143 additions & 141 deletions dapps/W3MWagmi/ios/W3MWagmi.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion dapps/W3MWagmi/ios/W3MWagmi/W3MWagmi.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:lab.web3modal.com</string>
<string>applinks:dev.lab.web3modal.com</string>
</array>
</dict>
</plist>
3 changes: 2 additions & 1 deletion dapps/W3MWagmi/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"@react-navigation/native-stack": "6.10.1",
"@sentry/react-native": "5.20.0",
"@tanstack/react-query": "5.51.1",
"@walletconnect/react-native-compat": "2.15.2",
"@walletconnect/react-native-compat": "2.16.0",
"@web3modal/coinbase-wagmi-react-native": "2.0.3",
"@web3modal/email-wagmi-react-native": "2.0.3",
"@web3modal/wagmi-react-native": "2.0.3",
Expand All @@ -38,6 +38,7 @@
"react-native-safe-area-context": "4.10.8",
"react-native-screens": "3.32.0",
"react-native-svg": "15.4.0",
"react-native-toast-message": "2.2.0",
"react-native-webview": "13.10.5",
"viem": "2.21.2",
"wagmi": "2.12.8"
Expand Down
28 changes: 23 additions & 5 deletions dapps/W3MWagmi/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,18 @@ import {coinbaseConnector} from '@web3modal/coinbase-wagmi-react-native';
import {emailConnector} from '@web3modal/email-wagmi-react-native';
import {WagmiProvider} from 'wagmi';
import {handleResponse} from '@coinbase/wallet-mobile-sdk';

import Toast from 'react-native-toast-message';
import Config from 'react-native-config';
import Clipboard from '@react-native-clipboard/clipboard';
import * as Sentry from '@sentry/react-native';
import {NavigationContainer} from '@react-navigation/native';
import {QueryClient, QueryClientProvider} from '@tanstack/react-query';

import {getCustomWallets} from './utils/misc';
import {RootStackNavigator} from './navigators/RootStackNavigator';
import {siweConfig} from './utils/SiweUtils';
import {chains} from './utils/WagmiUtils';
import {getCustomWallets} from '@/utils/misc';
import {RootStackNavigator} from '@/navigators/RootStackNavigator';
import {siweConfig} from '@/utils/SiweUtils';
import {chains} from '@/utils/WagmiUtils';
import SettingsStore from '@/stores/SettingsStore';

if (!__DEV__ && Config.ENV_SENTRY_DSN) {
Sentry.init({
Expand All @@ -42,6 +43,8 @@ const metadata = {
icons: ['https://avatars.githubusercontent.com/u/37784886'],
redirect: {
native: 'w3mwagmisample://',
universal: 'https://lab.web3modal.com/rn_appkit',
linkMode: true,
},
};

Expand Down Expand Up @@ -89,21 +92,36 @@ function App(): JSX.Element {
const handledBySdk = handleResponse(new URL(url));
if (!handledBySdk) {
// Handle other deeplinks
if (url.includes('wc_ev')) {
SettingsStore.setCurrentRequestLinkMode(true);
}
}
});

return () => sub.remove();
}, []);

useEffect(() => {
// Hide splashscreen
BootSplash.hide({fade: true});

// Check if app was opened from a link-mode response
async function checkInitialUrl() {
const initialUrl = await Linking.getInitialURL();
if (initialUrl) {
SettingsStore.setCurrentRequestLinkMode(initialUrl.includes('wc_ev'));
}
}

checkInitialUrl();
}, []);

return (
<NavigationContainer>
<WagmiProvider config={wagmiConfig}>
<QueryClientProvider client={queryClient}>
<RootStackNavigator />
<Toast />
<Web3Modal />
</QueryClientProvider>
</WagmiProvider>
Expand Down
33 changes: 26 additions & 7 deletions dapps/W3MWagmi/src/components/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,40 @@
import React from 'react';
import {Text, StyleSheet, TouchableOpacity} from 'react-native';
import {
Text,
StyleSheet,
TouchableOpacity,
StyleProp,
ViewStyle,
View,
} from 'react-native';
import {Icon, IconProps} from '@web3modal/ui-react-native';

import {useTheme} from '@/hooks/useTheme';

export interface CardProps {
title: string;
value: string;
value?: string;
onPress?: () => void;
icon?: IconProps['name'];
style?: StyleProp<ViewStyle>;
}

export function Card({title, value, onPress}: CardProps) {
export function Card({title, value, onPress, icon, style}: CardProps) {
const Theme = useTheme();
const backgroundColor = Theme['bg-175'];

return (
<TouchableOpacity
disabled={!onPress}
style={[styles.container, {backgroundColor}]}
style={[styles.container, {backgroundColor}, style]}
onPress={onPress}>
<Text style={[styles.title, {color: Theme['fg-100']}]}>{title}</Text>
<Text style={[styles.value, {color: Theme['fg-150']}]}>{value}</Text>
<View>
<Text style={[styles.title, {color: Theme['fg-100']}]}>{title}</Text>
{value && (
<Text style={[styles.value, {color: Theme['fg-150']}]}>{value}</Text>
)}
</View>
{icon && <Icon name={icon} size="sm" color={'fg-100'} />}
</TouchableOpacity>
);
}
Expand All @@ -27,8 +43,11 @@ const styles = StyleSheet.create({
container: {
borderRadius: 16,
paddingVertical: 16,
paddingHorizontal: 10,
paddingHorizontal: 16,
rowGap: 4,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
},
title: {
fontSize: 14,
Expand Down
57 changes: 46 additions & 11 deletions dapps/W3MWagmi/src/components/RequestModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import {
View,
} from 'react-native';
import Modal from 'react-native-modal';
import {useSnapshot} from 'valtio';
import SettingsStore from '@/stores/SettingsStore';
import {useTheme} from '@/hooks/useTheme';

interface Props {
isVisible: boolean;
Expand All @@ -23,32 +26,56 @@ export function RequestModal({
rpcResponse,
rpcError,
}: Props) {
const Theme = useTheme();
const {isCurrentRequestLinkMode} = useSnapshot(SettingsStore.state);

const handleClose = () => {
SettingsStore.setCurrentRequestLinkMode(false);
onClose();
};

return (
<Modal isVisible={isVisible} onBackdropPress={onClose}>
<TouchableOpacity onPress={onClose} style={styles.closeButton}>
<Modal isVisible={isVisible} onBackdropPress={handleClose}>
<TouchableOpacity onPress={handleClose} style={styles.closeButton}>
<Text>X</Text>
</TouchableOpacity>
<View style={styles.innerContainer}>
{isLoading && (
<>
<Text style={styles.title}>Pending Request</Text>
<ActivityIndicator color="#3396FF" style={styles.loader} />
<ActivityIndicator
color={Theme['accent-100']}
style={styles.loader}
/>
<Text style={styles.center}>
Approve or reject request using your wallet if needed
</Text>
</>
)}
{isCurrentRequestLinkMode && (
<View
style={[
styles.linkModeContainer,
{
backgroundColor: Theme['accent-100'],
},
]}>
<Text style={[styles.linkMode, {color: Theme['inverse-100']}]}>
LINK MODE
</Text>
</View>
)}
{rpcResponse && (
<>
<Text style={[styles.title, styles.successText]}>
<Text style={[styles.title, {color: Theme['success-100']}]}>
Request Response
</Text>
<Text style={styles.responseText}>{rpcResponse}</Text>
</>
)}
{rpcError && (
<>
<Text style={[styles.title, styles.failureText]}>
<Text style={[styles.title, {color: Theme['error-100']}]}>
Request Failure
</Text>
<Text style={styles.subtitle}>
Expand Down Expand Up @@ -90,12 +117,6 @@ const styles = StyleSheet.create({
textAlign: 'center',
marginBottom: 8,
},
successText: {
color: '#3396FF',
},
failureText: {
color: '#F05142',
},
subtitle: {
fontWeight: 'bold',
marginVertical: 4,
Expand All @@ -106,4 +127,18 @@ const styles = StyleSheet.create({
responseText: {
fontWeight: '300',
},
linkModeContainer: {
borderRadius: 20,
height: 25,
width: 100,
alignItems: 'center',
justifyContent: 'center',
alignSelf: 'center',
marginBottom: 12,
},
linkMode: {
fontSize: 12,
textAlign: 'center',
fontWeight: '500',
},
});
35 changes: 35 additions & 0 deletions dapps/W3MWagmi/src/hooks/useLogs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {useCallback, useEffect, useState} from 'react';
import {useAccount} from 'wagmi';
import SettingsStore from '@/stores/SettingsStore';

export function useLogs() {
const {connector} = useAccount();
const [provider, setProvider] = useState<any>(null);

const getLogs = useCallback(async () => {
if (provider?.signer?.client?.core) {
const _logs =
await provider.signer?.client.core.logChunkController?.getLogArray();
SettingsStore.setLogs(_logs ? _logs.reverse() : []);
}
}, [provider]);

useEffect(() => {
const getProvider = async () => {
if (connector && connector?.getProvider) {
const _provider = await connector?.getProvider();
setProvider(_provider);
}
};

getProvider();
}, [connector]);

useEffect(() => {
const interval = setInterval(() => {
getLogs();
}, 1000);

return () => clearTimeout(interval);
}, [getLogs]);
}
Loading

0 comments on commit fbde29c

Please sign in to comment.