React native ready wallet sdk for integrate with react native app
React native ready wallet sdk for integrate with react native apps
``sh`
npm install @readyio/react-native-wallet`
ORsh`
yarn add @readyio/react-native-wallet
`json`
{
"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": "^7.3.4",
"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"
},
}
1. 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 iOS`
sh`
npx uri-scheme add readywallet --ios && npx uri-scheme add tc --ios
2. WatermelonDB dependency
`pod`
use_modular_headers!
....
#comment this line
# :flipper_configuration => flipper_config,
....
pod 'simdjson', path: '../node_modules/@nozbe/simdjson'
3. 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
`pod`
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
``
4. Run IOS
`sh`
cd ios && pod install
yarn ios
1. Add in android/build.gradle
`jsx
buildscript{
...
kotlinVersion = '1.7.20'
minSdkVersion = 23
...
}
dependencies {
...
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
}
`
2. Add this code to android/app/build.gradle
`jsx
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')
...
}
`
3. Require permissions on AndroidManifest.xml
``
4. Deeplink for connecting to Dapps by WalletConnect and TonConnect
`jsx`
npx uri-scheme add readywallet --android && npx uri-scheme add wc --android && npx uri-scheme add tc --android
5. Add the following code to AndroidManifest.xml in Android
``
android:windowSoftInputMode="adjustResize"
android:taskAffinity="com.readyio.readywallet.miniapp"
android:launchMode="singleTop"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
/>
error: resource android:attr/lStar not found
6. If you encounter during release build, add the following code at the end of android/build.gradle`
`
subprojects {
afterEvaluate { project ->
if (project.hasProperty('android')) {
project.android { compileSdkVersion 34 }
}
}
}
`js
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 |
| isOnlyReady | Act as a seperate app | bool | false | NO |
`js
import ready, { WalletDataType, Icon3D } from '@readyio/react-native-wallet';
const data: WalletDataType[] = await ready.getReadyWallets(userId)
// render wallet icon
`
To handle deep links for using WalletConnect to connect with a DApp in MiniApp, here are the examples:
1. Foreground (SuperApp is open)[](https://reactnative.dev/docs/linking?syntax=ios#1-if-the-app-is-already-open-the-app-is-foregrounded-and-a-linking-url-event-is-fired)
You can handle these events with Linking.addEventListener('url', callback) - it calls callback({url}) with the linked URL
E.g
`jsx
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);
};
}, []);
`
2. Background (SuperApp is running in the background)[](https://reactnative.dev/docs/linking?syntax=ios#2-if-the-app-is-not-already-open-it-is-opened-and-the-url-is-passed-in-as-the-initialurl)
`jsx
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);
};
}, []);
`
3. App is completely closed
`jsx
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
#### An example of setting up ready push notification using @react-native-firebase/messaging
1. Setup device token
`js
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
})
`
2. Setup handler
`js
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
})
`
#### An example of setting up ready push notification using react-native-onesignal
1. Init appid and add listener event
`js
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
`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