React native ready wallet sdk for integrate with react native apps
npm install @readyio/react-native-wallet
OR
yarn add @readyio/react-native-wallet
{
"peerDependencies": {
"@gorhom/bottom-sheet": "^4",
"@nozbe/watermelondb": "^0.27.1",
"@react-native-async-storage/async-storage": "^1.17.10",
"@react-native-camera-roll/camera-roll": "5.2.0",
"@react-native-clipboard/clipboard": "^1.13.1",
"@react-native-community/blur": "^3.6.0",
"@react-native-community/checkbox": "^0.5.16",
"@react-native-community/datetimepicker": "^7.6.4",
"@react-native-community/netinfo": "6.0.0",
"@react-native-masked-view/masked-view": "^0.3.1",
"@react-native-firebase/analytics": "^20.1.0",
"@react-native-firebase/app": "^20.1.0",
"@react-navigation/bottom-tabs": "^6.5.12",
"@react-navigation/material-top-tabs": "^6.6.10",
"@react-navigation/native": "^6.1.7",
"@react-navigation/native-stack": "6.9.13",
"@readyio/ready-native": "1.0.0",
"@sentry/react-native": "^5.33.0",
"@walletconnect/react-native-compat": "^2.11.0",
"@walletconnect/web3wallet": "^1.10.0",
"apisauce": "^1.1.1",
"deprecated-react-native-prop-types": "^4.1.0",
"i18n-js": "3.8.0",
"lodash": "^4.17.21",
"lottie-react-native": "^6.3.1",
"mobx": "6.10.2",
"mobx-react-lite": "4.0.5",
"mobx-state-tree": "5.3.0",
"moment": "^2.24.0",
"react": "*",
"react-native": "*",
"react-native-biometrics": "^3.0.1",
"react-native-camera": "^3.18.0",
"react-native-collapsible-tab-view": "^8.0.0",
"react-native-countdown-circle-timer": "^3.2.1",
"react-native-get-random-values": "^1.10.0",
"react-native-device-info": "^5.5.3",
"react-native-event-listeners": "^1.0.7",
"react-native-fast-image": "^8.6.3",
"react-native-fast-pbkdf2": "^0.3.1",
"react-native-fs": "^2.16.6",
"react-native-gesture-handler": "~2.12.0",
"react-native-hash": "^3.0.3",
"react-native-image-picker": "^5.6.1",
"react-native-keychain": "~8.1.2",
"react-native-linear-gradient": "^2.8.3",
"react-native-modal": "^13.0.1",
"react-native-pager-view": "7.0.0-rc.0",
"react-native-permissions": "^2.1.3",
"react-native-pie-chart": "^3.0.2",
"react-native-qr-decode-image-camera": "^1.1.3",
"react-native-qrcode-scanner": "^1.5.5",
"react-native-qrcode-svg": "^6.0.3",
"react-native-reanimated": "3.5.4",
"react-native-rsa-native": "^2.0.5",
"react-native-safe-area-context": "^4.7.1",
"react-native-screens": "3.25.0",
"react-native-share": "^7.6.6",
"react-native-skeleton-placeholder": "^5.2.4",
"react-native-svg": "^13.14.0",
"react-native-tab-view": "^3.5.2",
"react-native-toast-message": "^2.2.0",
"react-native-randombytes": "^3.6.1",
"react-native-uuid": "1.4.9",
"react-native-view-shot": "^3.8.0",
"react-native-webview": "^13.8.1",
"react-native-gzip": "^1.1.0"
},
}
-
Setting up Deeplink for connecting to Dapps by WalletConnect and TonConnect
Step 1: Configuration
Linking
- If
Linking
is not installed in your React Native project, consult the documentation; otherwise, no additional configuration is required.
Step 2: Here is the command line to add data scheme in
Info.plist
in iOSnpx uri-scheme add readywallet --ios && npx uri-scheme add tc --ios
- If
-
WatermelonDB dependency
use_modular_headers! .... #comment this line # :flipper_configuration => flipper_config, .... pod 'simdjson', path: '../node_modules/@nozbe/simdjson'
-
react-native-permissions@2.1.3
The Ready Wallet SDK requires access to the camera, photo and Face-ID on iOS. So, let's set up the pod file by following this documentation
Podfile
permissions_path = '../node_modules/react-native-permissions/ios' pod 'Permission-Camera', :path => "#{permissions_path}/Camera.podspec" pod 'Permission-FaceID', :path => "#{permissions_path}/FaceID.podspec"
Info.plist
<key>NSCameraUsageDescription</key> <string>Our app uses the camera to scan crypto wallet or account QR code and capture photos for sharing in chat or used as avatar</string> <key>NSFaceIDUsageDescription</key> <string>Authentication</string> <key>NSPhotoLibraryUsageDescription</key> <string>Access to the photo library is used for media sharing in chat or setting profile picture</string>
-
Run IOS
cd ios && pod install yarn ios
-
Add in
android/build.gradle
buildscript{ ... kotlinVersion = '1.7.20' minSdkVersion = 23 ... } dependencies { ... classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" }
-
Add this code to android/app/build.gradle
defaultConfig { ... missingDimensionStrategy 'react-native-camera', 'general' } ... configurations { all*.exclude module: 'bcprov-jdk15to18' } dependencies { ... implementation project(':react-native-fs') implementation 'me.leolin:ShortcutBadger:1.1.21@aar' implementation project(':react-native-camera') implementation('org.bitcoinj:bitcoinj-core:0.16.1') { exclude group: 'net.jcip', module: 'jcip-annotations' } implementation 'org.whispersystems:curve25519-android:0.2.5' implementation ('org.web3j:core:4.8.7-android') ... }
-
Require permissions on AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.CAMERA" />
-
Deeplink for connecting to Dapps by WalletConnect and TonConnect
npx uri-scheme add readywallet --android && npx uri-scheme add wc --android && npx uri-scheme add tc --android
-
Add the following code to AndroidManifest.xml in Android
<activity android:name="com.readyio.readywallet.ReadyWalletActivity" android:windowSoftInputMode="adjustResize" android:taskAffinity="com.readyio.readywallet.miniapp" android:launchMode="singleTop" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode" />
-
If you encounter
error: resource android:attr/lStar not found
during release build, add the following code at the end ofandroid/build.gradle
subprojects {
afterEvaluate { project ->
if (project.hasProperty('android')) {
project.android { compileSdkVersion 34 }
}
}
}
import ready from '@readyio/react-native-wallet';
ready.openApp({
/* Configuration */
})
Available configuration:
Key | Description | Value Type | Default | Required |
---|---|---|---|---|
language | miniapp language | "en", "vi" | "vi" | NO |
deepLinkUrl | used to forward deeplink from superapp to miniapp | string | undefined | NO |
walletId | used to indicate which wallet a user has open | string | undefined | NO |
userId | current userId of supper app | string | '' | YES |
isCreateNewWallet | used to indicate the user to open the mini app to create a wallet | bool | false | NO |
userInfo | Send supper app user infomation to miniapp | UserInfo | false | NO |
import ready, { WalletDataType, Icon3D } from '@readyio/react-native-wallet';
const data: WalletDataType[] = await ready.getReadyWallets(userId)
// render wallet icon
<Icon3D icon={data[0].icon} />
To handle deep links for using WalletConnect to connect with a DApp in MiniApp, here are the examples:
-
You can handle these events with
Linking.addEventListener('url', callback)
- it callscallback({url})
with the linked URLE.g
import ready from '@readyio/react-native-wallet'; useEffect(() => { const handleUrl = (event) => { const url = event.url; // Forward deeplink to Ready if (url.startsWith('wc:') || url.startsWith('tc:') || url.startsWith('readywallet:')) { ready.openApp({ deepLinkUrl: url, userId: "userId" }) } }; Linking.addEventListener('url', handleUrl); return () => { Linking.removeEventListener('url', handleUrl); }; }, []);
-
Background (SuperApp is running in the background)
import ready from '@readyio/react-native-wallet'; useEffect(() => { const handleUrl = async (url) => { // Forward deeplink to Ready if (url.startsWith('wc:') || url.startsWith('tc:') || url.startsWith('readywallet:')) { ready.openApp({ deepLinkUrl: url, userId: "userId" }) } }; const getUrlAsync = async () => { const initialUrl = await Linking.getInitialURL(); if (initialUrl) { handleUrl(initialUrl); } }; const handleAppStateChange = (nextAppState) => { if (nextAppState === 'active') { getUrlAsync(); } }; AppState.addEventListener('change', handleAppStateChange); return () => { AppState.removeEventListener('change', handleAppStateChange); }; }, []);
-
App is completely closed
import ready from '@readyio/react-native-wallet'; useEffect(() => { const getUrlAsync = async () => { const url = await Linking.getInitialURL(); if (url) { // Forward deeplink to Ready if (url.startsWith('wc:') || url.startsWith('tc:') || url.startsWith('readywallet:')) { ready.openApp({ deepLinkUrl: url, userId: "userId" }) } } }; getUrlAsync(); }, []);
Please contact Ready team to set up push notification key on server side
-
Setup device token
import ready from '@readyio/react-native-wallet'; import messaging from '@react-native-firebase/messaging' // Setup FCM token messaging().getToken().then((token) => { ready.setDeviceToken(token) // Do logic here })
-
Setup handler
import ready from '@readyio/react-native-wallet'; import messaging from '@react-native-firebase/messaging' // Forground handler messaging().onMessage((message: FirebaseMessagingTypes.RemoteMessage) => { if (ready.isReadyPush(message.data)) return // Handle non-ready message }) // Background handler messaging().setBackgroundMessageHandler(async (message: FirebaseMessagingTypes.RemoteMessage) => { if (ready.isReadyPush(message.data)) return // Handle non-ready message })
- Init appid and add listener event
import { LogLevel, OneSignal } from 'react-native-onesignal' useEffect(() => { // Remove this method to stop OneSignal Debugging OneSignal.Debug.setLogLevel(LogLevel.Verbose) // OneSignal Initialization OneSignal.initialize('OneSignal App ID') OneSignal.login('externalId') // requestPermission will show the native iOS or Android notification permission prompt. // We recommend removing the following code and instead using an In-App Message to prompt for notification permission OneSignal.Notifications.requestPermission(true) // Method for listening for notification clicks OneSignal.Notifications.addEventListener('click', (event) => { if (ready.isReadyPush(event.notification.additionalData)) { console.log('Ready Push: clicked:', event.notification.additionalData) return } // Handle non-ready event }) OneSignal.Notifications.addEventListener('foregroundWillDisplay', (event) => { if (ready.isReadyPush(event.notification.additionalData)) { console.log('Ready Push: foregroundWillDisplay:', event.notification.additionalData) return } // Handle non-ready event }) }, [])
MainApplication.java
// Add imports
import android.content.Context;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import org.jetbrains.annotations.Nullable;
// ...
// Put this above "public void onCreate()":
@Override
public Intent registerReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter) {
if (Build.VERSION.SDK_INT >= 34 && getApplicationInfo().targetSdkVersion >= 34) {
return super.registerReceiver(receiver, filter, Context.RECEIVER_EXPORTED);
} else {
return super.registerReceiver(receiver, filter);
}
}
// ....
app/build.gradle
dependencies {
// ...
implementation 'org.jetbrains:annotations:16.0.2'
// ...
}
The library version is stable and works without issues when using React Native version 0.71.8. If you encounter any errors during the installation process, please contact the Ready Team for support.
See the contributing guide to learn how to contribute to the repository and the development workflow.
MIT