/* eslint-disable prettier/prettier */ import { NativeModules, Platform } from 'react-native' import AsyncStorage from '@react-native-async-storage/async-storage' import storage from './Storage' const LINKING_ERROR = `The package 'readyio-rn-wallet' doesn't seem to be linked. Make sure: \n\n` + Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) + '- You rebuilt the app after installing the package\n' + '- You are not using Expo Go\n' const ReadyWallet = NativeModules.ReadyWallet ? NativeModules.ReadyWallet : new Proxy( {}, { get() { throw new Error(LINKING_ERROR) }, } ) export interface DeepLinkDataType { deepLinkUrl: string } export interface PushNotiDataType { event: string destination: string data: string } export type UserInfo = { avatar?: string name?: string } export type Currency = 'vnd' | 'usd' export interface MiniAppProps { language?: 'vi' | 'en' deepLinkUrl?: string walletId?: string isCreateNewWallet?: boolean userInfo?: UserInfo currency?: Currency isOnlyReady?: boolean userId: string } export type WalletDataType = { id: string userId: string name: string icon: string background: string totalAmount: { vnd: string; usd: string } } export enum SupportedNativeEvent { PUSH_EVENT = 'ReadyWallet_FOREGROUND_PUSH_EVENT', DEEPLINK_EVENT = 'ReadyWallet_FOREGROUND_DEEPLINK_EVENT', } export type CustomColorToken = { primary?: string primaryOnPress?: string link?: string success?: string warning?: string error?: string disable?: string text?: string label?: string border?: string borderLight?: string background?: string backgroundSecondary?: string block?: string } export class ReadyWalletClass { // key string of push data saved in async storage private readonly AS_READY_PUSH_DATA_KEY = '@readyio_push_noti_data' private readonly AS_READY_PUSH_TOKEN_KEY = '@readyio_push_noti_key' private readonly AS_READY_COLOR_TOKEN = '@readyio_color_token' private readonly AS_READY_WALLET = '@readyio_ready_wallet' // Event name of push notification data from ready // private readonly READY_PUSH_EVENT_TYPE: PushEventType = PushEventType.WALLET_TRANSFER private readonly READY_PUSH_ORIGIN = 'readyio' /** * Get data from mini wallet app push notifications saved from async-storage * @returns {Promise} A promise to array of data or null */ private async getPushData(): Promise { try { const data = await AsyncStorage.getItem(this.AS_READY_PUSH_DATA_KEY) return data ? JSON.parse(data) : null } catch { return null } } /** * Save data from mini wallet app push notifications saved to async-storage * @returns {Promise} The promise indicates whether the process was successful or not */ private async savePushData(value: PushNotiDataType): Promise { if (await ReadyWallet.getIsLaunch()) { return true } try { let savedData = await this.getPushData() if (!savedData) { await AsyncStorage.setItem(this.AS_READY_PUSH_DATA_KEY, JSON.stringify([value])) } else { savedData.unshift(value) await AsyncStorage.setItem(this.AS_READY_PUSH_DATA_KEY, JSON.stringify(savedData)) } return true } catch { return false } } private async clearPushData(): Promise { await AsyncStorage.removeItem(this.AS_READY_PUSH_DATA_KEY) } private async getDeviceToken(): Promise { return await AsyncStorage.getItem(this.AS_READY_PUSH_TOKEN_KEY) } // -------------------------PUBLIC------------------------- public async getColor(): Promise { try { const data = await AsyncStorage.getItem(this.AS_READY_PUSH_DATA_KEY) return data ? JSON.parse(data) : {} } catch { return {} } } public async getReadyWallets(userId: string): Promise { const savedData = await storage.getItem(this.AS_READY_WALLET) const savedReadyWalletData = savedData ? JSON.parse(savedData) : {} const values: WalletDataType[] = Object.values(savedReadyWalletData) return values.filter((v) => v.userId === userId) } /** * When the mini app is being launched. * If it receives a push notification from the supper application, * it will send an event to the mini app to process the notification data. */ public async sendPushDataEvent(value: PushNotiDataType): Promise { await ReadyWallet.sendPushDataEvent(value) } /** * On Android devide * The wallet miniapp activity is run on difirrent taskAffinity with your main activity * Once mini wallet app is opended, your main activity will handle the wallet connect deep link to connect Dapps. * @note Android Supported Only */ public async sendDeeplinkDataEvent(value: DeepLinkDataType): Promise { await ReadyWallet.sendDeeplinkDataEvent(value) } /** * Set up miniapp Push notification service * @param token {string) A FCM token */ public async setDeviceToken(token: string): Promise { await AsyncStorage.setItem(this.AS_READY_PUSH_TOKEN_KEY, token) } /** * Handle an push notification payload sent by Ready. * @param data FirebaseMessagingTypes.RemoteMessage.data Remote messages sent from Firebase or OSNotification.additionalData sent from OneSignal * @returns A Boolean value indicating this Push notification is from Ready * @note It checks the data attribute type of the message received from Server. Validate origin is "readyio" and have destination, data properties */ public isReadyPush(data: { [key: string]: string | object } | object | undefined): boolean { if (!data) return false if ("origin" in data) { if (data.origin === this.READY_PUSH_ORIGIN) { if (!data.event || !data.data) return false const value: PushNotiDataType = { event: data.event as string, destination: data.destination as string, data: data.data as string, } this.sendPushDataEvent(value) this.savePushData(value) return true } } return false } public async loadColor(color: CustomColorToken) { await AsyncStorage.setItem(this.AS_READY_COLOR_TOKEN, JSON.stringify(color)) } /** * Present ReadyWallet as a modal overlay in your app. * @param initProps Init object pass to mini app. Includes app language and deep link url. * @note The mini app only supports English (en) and Vietnamese (vi) */ public async openApp(initProps?: MiniAppProps) { const pushData = await this.getPushData() if (pushData) { this.clearPushData() } if (await ReadyWallet.getIsLaunch()) { this.sendDeeplinkDataEvent({ deepLinkUrl: initProps?.deepLinkUrl || '', }) } const colorToken = await this.getColor() const pushToken = await this.getDeviceToken() return ReadyWallet.openApp({ ...(initProps || {}), pushData, pushToken, colors: colorToken, }) } /** * Close ReadyWallet mini app. */ public closeApp() { return ReadyWallet.closeApp() } }