diff --git a/__tests__/App.snapshot.tsx b/__tests__/App.snapshot.tsx index 093edb9c7..1554e3b49 100644 --- a/__tests__/App.snapshot.tsx +++ b/__tests__/App.snapshot.tsx @@ -45,6 +45,7 @@ jest.mock('react-native', () => { return RN; }); +jest.mock('react-native-picker-select', () => 'RNPickerSelect'); // test suite describe('Component App - test', () => { diff --git a/__tests__/Header.snapshot.tsx b/__tests__/Header.snapshot.tsx index 14ba8bffb..b5f8810a0 100644 --- a/__tests__/Header.snapshot.tsx +++ b/__tests__/Header.snapshot.tsx @@ -75,8 +75,6 @@ describe('Component Header - test', () => { setComputingModalVisible={onFunction} setBackgroundError={onFunction} setPrivacyOption={onFunction} - //setPoolsToShieldSelectSapling={onFunction} - //setPoolsToShieldSelectTransparent={onFunction} setUfvkViewModalVisible={onFunction} addLastSnackbar={onFunction} setShieldingAmount={onFunction} diff --git a/__tests__/History.snapshot.tsx b/__tests__/History.snapshot.tsx index 65e2d06b7..92b8c846e 100644 --- a/__tests__/History.snapshot.tsx +++ b/__tests__/History.snapshot.tsx @@ -119,8 +119,6 @@ describe('Component History - test', () => { setZecPrice={onFunction} setComputingModalVisible={onFunction} setPrivacyOption={onFunction} - //setPoolsToShieldSelectSapling={onFunction} - //setPoolsToShieldSelectTransparent={onFunction} setSendPageState={onFunction} setShieldingAmount={onFunction} setScrollToTop={onFunction} @@ -148,8 +146,6 @@ describe('Component History - test', () => { setZecPrice={onFunction} setComputingModalVisible={onFunction} setPrivacyOption={onFunction} - //setPoolsToShieldSelectSapling={onFunction} - //setPoolsToShieldSelectTransparent={onFunction} setSendPageState={onFunction} setShieldingAmount={onFunction} setScrollToTop={onFunction} diff --git a/__tests__/Insight.snapshot.tsx b/__tests__/Insight.snapshot.tsx index c82cf652c..f29fd55a0 100644 --- a/__tests__/Insight.snapshot.tsx +++ b/__tests__/Insight.snapshot.tsx @@ -48,7 +48,7 @@ describe('Component Insight - test', () => { const onClose = jest.fn(); const insight = render( - + , ); expect(insight.toJSON()).toMatchSnapshot(); diff --git a/__tests__/LoadedApp.snapshot.tsx b/__tests__/LoadedApp.snapshot.tsx index 5432b41fd..5682c7db7 100644 --- a/__tests__/LoadedApp.snapshot.tsx +++ b/__tests__/LoadedApp.snapshot.tsx @@ -74,6 +74,7 @@ jest.mock('react-native-fs', () => ({ writeFile: jest.fn(() => Promise.resolve()), // o Promise.reject(new Error('Write failed')) // Agrega más funciones mockeadas según sea necesario })); +jest.mock('react-native-picker-select', () => 'RNPickerSelect'); // test suite describe('Component LoadedApp - test', () => { diff --git a/__tests__/Seed.snapshot.tsx b/__tests__/Seed.snapshot.tsx index ffa7ac78a..30057ca70 100644 --- a/__tests__/Seed.snapshot.tsx +++ b/__tests__/Seed.snapshot.tsx @@ -97,7 +97,7 @@ describe('Component Seed - test', () => { contextLoading.translate = mockTranslate; contextLoading.wallet = mockWallet; contextLoading.info = mockInfo; - contextLoading.totalBalance = mockTotalBalance; + //contextLoading.totalBalance = mockTotalBalance; test('Seed New - snapshot', () => { const seed = render( diff --git a/__tests__/Send.snapshot.tsx b/__tests__/Send.snapshot.tsx index d3ceb1856..f6544daef 100644 --- a/__tests__/Send.snapshot.tsx +++ b/__tests__/Send.snapshot.tsx @@ -90,8 +90,6 @@ describe('Component Send - test', () => { syncingStatusMoreInfoOnClick={onFunction} setZecPrice={onFunction} setPrivacyOption={onFunction} - //setPoolsToShieldSelectSapling={onFunction} - //setPoolsToShieldSelectTransparent={onFunction} setShieldingAmount={onFunction} setScrollToTop={onFunction} /> @@ -120,8 +118,6 @@ describe('Component Send - test', () => { syncingStatusMoreInfoOnClick={onFunction} setZecPrice={onFunction} setPrivacyOption={onFunction} - //setPoolsToShieldSelectSapling={onFunction} - //setPoolsToShieldSelectTransparent={onFunction} setShieldingAmount={onFunction} setScrollToTop={onFunction} /> diff --git a/__tests__/__snapshots__/LoadedApp.snapshot.tsx.snap b/__tests__/__snapshots__/LoadedApp.snapshot.tsx.snap index 4036ed3a2..c7e1d1d96 100644 --- a/__tests__/__snapshots__/LoadedApp.snapshot.tsx.snap +++ b/__tests__/__snapshots__/LoadedApp.snapshot.tsx.snap @@ -26,10 +26,192 @@ exports[`Component LoadedApp - test LoadedApp - snapshot 1`] = ` ] } > - - - Loading... - + + + + + text translated + + + + + text translated + + + text translated + + + text translated + + + text translated + + + text translated + + + text translated + + + + + + + Version : + + + text translated + + + text translatedtext translated + + - - - - - + `; diff --git a/__tests__/__snapshots__/Send.snapshot.tsx.snap b/__tests__/__snapshots__/Send.snapshot.tsx.snap index bc1df8880..08583ab1d 100644 --- a/__tests__/__snapshots__/Send.snapshot.tsx.snap +++ b/__tests__/__snapshots__/Send.snapshot.tsx.snap @@ -38,13 +38,14 @@ exports[`Component Send - test Send currency USD, privacy high & mode advanced - @@ -52,8 +53,9 @@ exports[`Component Send - test Send currency USD, privacy high & mode advanced - style={ { "display": "flex", - "marginTop": 10, + "marginTop": 0, "padding": 10, + "paddingTop": 5, } } > @@ -280,6 +282,7 @@ exports[`Component Send - test Send currency USD, privacy high & mode advanced - "display": "flex", "flexDirection": "row", "justifyContent": "space-between", + "marginTop": 10, } } > @@ -288,8 +291,6 @@ exports[`Component Send - test Send currency USD, privacy high & mode advanced - { "flexDirection": "row", "justifyContent": "flex-end", - "minHeight": 48, - "minWidth": 48, } } > @@ -300,8 +301,6 @@ exports[`Component Send - test Send currency USD, privacy high & mode advanced - "borderRadius": 10, "justifyContent": "flex-end", "margin": 0, - "minHeight": 48, - "minWidth": 48, "padding": 0, "paddingBottom": 3, } @@ -465,7 +464,7 @@ exports[`Component Send - test Send currency USD, privacy high & mode advanced - "display": "flex", "flexDirection": "row", "justifyContent": "flex-start", - "marginTop": 5, + "marginTop": 0, } } > @@ -670,7 +669,7 @@ exports[`Component Send - test Send currency USD, privacy high & mode advanced - "borderRadius": 10, "display": "flex", "flexDirection": "row", - "marginTop": 5, + "marginTop": 0, "padding": 5, } } @@ -703,6 +702,7 @@ exports[`Component Send - test Send currency USD, privacy high & mode advanced - style={ { "color": "#c3c3c3", + "fontSize": 12.5, "opacity": 0.65, } } @@ -788,16 +788,16 @@ exports[`Component Send - test Send currency USD, privacy high & mode advanced - @@ -807,7 +807,7 @@ exports[`Component Send - test Send currency USD, privacy high & mode advanced - "color": "#c3c3c3", "fontSize": 12.5, "fontWeight": "600", - "marginTop": 11, + "marginTop": 5, "opacity": 1, } } @@ -869,7 +869,7 @@ exports[`Component Send - test Send currency USD, privacy high & mode advanced - { "color": "#ffffff", "fontSize": 12.5, - "marginTop": 11, + "marginTop": 5, } } > @@ -881,7 +881,7 @@ exports[`Component Send - test Send currency USD, privacy high & mode advanced - "color": "#ffffff", "fontSize": 12.5, "fontWeight": "700", - "marginTop": 11, + "marginTop": 5, } } > @@ -894,10 +894,19 @@ exports[`Component Send - test Send currency USD, privacy high & mode advanced - + @@ -1196,13 +1205,14 @@ exports[`Component Send - test Send no currency, privacy normal & mode basic - s @@ -1210,8 +1220,9 @@ exports[`Component Send - test Send no currency, privacy normal & mode basic - s style={ { "display": "flex", - "marginTop": 10, + "marginTop": 0, "padding": 10, + "paddingTop": 5, } } > @@ -1438,6 +1449,7 @@ exports[`Component Send - test Send no currency, privacy normal & mode basic - s "display": "flex", "flexDirection": "row", "justifyContent": "space-between", + "marginTop": 10, } } > @@ -1446,8 +1458,6 @@ exports[`Component Send - test Send no currency, privacy normal & mode basic - s { "flexDirection": "row", "justifyContent": "flex-end", - "minHeight": 48, - "minWidth": 48, } } > @@ -1458,8 +1468,6 @@ exports[`Component Send - test Send no currency, privacy normal & mode basic - s "borderRadius": 10, "justifyContent": "flex-end", "margin": 0, - "minHeight": 48, - "minWidth": 48, "padding": 0, "paddingBottom": 3, } @@ -1623,7 +1631,7 @@ exports[`Component Send - test Send no currency, privacy normal & mode basic - s "display": "flex", "flexDirection": "row", "justifyContent": "flex-start", - "marginTop": 5, + "marginTop": 0, } } > @@ -1829,7 +1837,7 @@ exports[`Component Send - test Send no currency, privacy normal & mode basic - s "borderRadius": 10, "display": "flex", "flexDirection": "row", - "marginTop": 5, + "marginTop": 0, "padding": 5, } } @@ -1862,6 +1870,7 @@ exports[`Component Send - test Send no currency, privacy normal & mode basic - s style={ { "color": "#c3c3c3", + "fontSize": 12.5, "opacity": 0.65, } } @@ -1947,16 +1956,16 @@ exports[`Component Send - test Send no currency, privacy normal & mode basic - s @@ -1966,7 +1975,7 @@ exports[`Component Send - test Send no currency, privacy normal & mode basic - s "color": "#c3c3c3", "fontSize": 12.5, "fontWeight": "600", - "marginTop": 11, + "marginTop": 5, "opacity": 1, } } @@ -2028,7 +2037,7 @@ exports[`Component Send - test Send no currency, privacy normal & mode basic - s { "color": "#ffffff", "fontSize": 12.5, - "marginTop": 11, + "marginTop": 5, } } > @@ -2040,7 +2049,7 @@ exports[`Component Send - test Send no currency, privacy normal & mode basic - s "color": "#ffffff", "fontSize": 12.5, "fontWeight": "700", - "marginTop": 11, + "marginTop": 5, } } > @@ -2053,10 +2062,19 @@ exports[`Component Send - test Send no currency, privacy normal & mode basic - s + diff --git a/android/app/build.gradle b/android/app/build.gradle index 9ca82721a..8f360dc76 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -101,8 +101,8 @@ android { applicationId 'org.ZingoLabs.Zingo' // Real minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 186 // Real - versionName "zingo-1.4.2" // Real + versionCode 187 // Real + versionName "zingo-1.4.3" // Real missingDimensionStrategy 'react-native-camera', 'general' testBuildType System.getProperty('testBuildType', 'debug') testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' diff --git a/android/app/src/main/java/org/ZingoLabs/Zingo/BackgroundSyncWorker.kt b/android/app/src/main/java/org/ZingoLabs/Zingo/BackgroundSyncWorker.kt index d6e2e29d2..efe8a3579 100644 --- a/android/app/src/main/java/org/ZingoLabs/Zingo/BackgroundSyncWorker.kt +++ b/android/app/src/main/java/org/ZingoLabs/Zingo/BackgroundSyncWorker.kt @@ -31,6 +31,7 @@ import kotlin.time.Duration.Companion.minutes import kotlin.time.DurationUnit import kotlin.time.toDuration import kotlin.time.toJavaDuration +import org.ZingoLabs.Zingo.Constants.* class BackgroundSyncWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) { @@ -38,7 +39,6 @@ class BackgroundSyncWorker(context: Context, workerParams: WorkerParameters) : W override fun doWork(): Result { val reactContext = ReactApplicationContext(MainApplication.getAppContext()) val rpcModule = RPCModule(reactContext) - val errorPrefix = "error" Log.i("SCHEDULED_TASK_RUN", "Task running") @@ -50,7 +50,7 @@ class BackgroundSyncWorker(context: Context, workerParams: WorkerParameters) : W Log.i("SCHEDULED_TASK_RUN", "background json file SAVED $jsonBackgroundStart") // checking if the wallet file exists - val exists: Boolean = rpcModule.wallet_exists() + val exists: Boolean = rpcModule.fileExists(WalletFileName.value) if (exists) { uniffi.zingo.initLogging() @@ -58,7 +58,7 @@ class BackgroundSyncWorker(context: Context, workerParams: WorkerParameters) : W // check the Server, because the task can run without the App. val balance = uniffi.zingo.executeCommand("balance", "") Log.i("SCHEDULED_TASK_RUN", "Testing if server is active: $balance") - if (balance.lowercase().startsWith(errorPrefix)) { + if (balance.lowercase().startsWith(ErrorPrefix.value)) { // this means this task is running with the App closed loadWalletFile(rpcModule) } else { diff --git a/android/app/src/main/java/org/ZingoLabs/Zingo/Constants.kt b/android/app/src/main/java/org/ZingoLabs/Zingo/Constants.kt new file mode 100644 index 000000000..cb953da23 --- /dev/null +++ b/android/app/src/main/java/org/ZingoLabs/Zingo/Constants.kt @@ -0,0 +1,10 @@ +package org.ZingoLabs.Zingo + +enum class Constants(val value: String) { + // wallet files + WalletFileName("wallet.dat"), + WalletBackupFileName("wallet.backup.dat"), + + BackgroundFileName("background.json"), + ErrorPrefix("error"), +} \ No newline at end of file diff --git a/android/app/src/main/java/org/ZingoLabs/Zingo/RPCModule.kt b/android/app/src/main/java/org/ZingoLabs/Zingo/RPCModule.kt index 87536ae66..4510de00a 100644 --- a/android/app/src/main/java/org/ZingoLabs/Zingo/RPCModule.kt +++ b/android/app/src/main/java/org/ZingoLabs/Zingo/RPCModule.kt @@ -10,80 +10,68 @@ import com.facebook.react.bridge.Promise //import android.util.Log import java.io.File -import java.io.InputStream import kotlin.concurrent.thread +import org.ZingoLabs.Zingo.Constants.* class RPCModule internal constructor(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) { - private val walletFileName = "wallet.dat" - private val walletBackupFileName = "wallet.backup.dat" - private val backgroundFileName = "background.json" - private val errorPrefix = "error" override fun getName(): String { return "RPCModule" } - private fun getFile(file: String): File { - return File(MainApplication.getAppContext()?.filesDir, file) + private fun getDocumentDirectory(): String { + return reactContext.applicationContext.filesDir.absolutePath } - fun wallet_exists(): Boolean { - // Check if a wallet already exists - val file = getFile(walletFileName) + fun fileExists(fileName: String): Boolean { + // Check if a file already exists + val file = File(MainApplication.getAppContext()?.filesDir, fileName) return if (file.exists()) { - Log.i("SCHEDULED_TASK_RUN", "Wallet exists") + Log.i("MAIN", "File $fileName exists") true } else { - Log.i("SCHEDULED_TASK_RUN", "Wallet DOES NOT exist") + Log.i("MAIN", "File $fileName DOES NOT exist") false } } - fun walletBackup_exists(): Boolean { - // Check if a wallet already exists - val file = getFile(walletBackupFileName) - return if (file.exists()) { - Log.i("SCHEDULED_TASK_RUN", "Wallet backup exists") - true - } else { - Log.i("SCHEDULED_TASK_RUN", "Wallet backup DOES NOT exist") - false - } + private fun readFile(fileName: String): ByteArray { + val file = MainApplication.getAppContext()!!.openFileInput(fileName) + return file.readBytes() + } + + private fun writeFile(fileName: String, fileBytes: ByteArray) { + val file = MainApplication.getAppContext()?.openFileOutput(fileName, Context.MODE_PRIVATE) + file?.write(fileBytes) + file?.close() + } + + private fun deleteFile(fileName: String): Boolean { + val file = MainApplication.getAppContext()?.getFileStreamPath(fileName) + return file!!.delete() } @ReactMethod fun walletExists(promise: Promise) { // Check if a wallet already exists - val file = getFile(walletFileName) - if (file.exists()) { - // Log.i("MAIN", "Wallet exists") - promise.resolve(true) - } else { - // Log.i("MAIN", "Wallet DOES NOT exist") - promise.resolve(false) - } + promise.resolve(fileExists(WalletFileName.value)) } @ReactMethod fun walletBackupExists(promise: Promise) { // Check if a wallet backup already exists - val file = getFile(walletBackupFileName) - if (file.exists()) { - // Log.i("MAIN", "Wallet backup exists") - promise.resolve(true) - } else { - // Log.i("MAIN", "Wallet backup DOES NOT exist") - promise.resolve(false) - } + promise.resolve(fileExists(WalletBackupFileName.value)) } - fun saveWalletFile() { + fun saveWalletFile(): Boolean { + uniffi.zingo.initLogging() + // Get the encoded wallet file - val b64encoded = uniffi.zingo.saveToB64() - if (b64encoded.lowercase().startsWith("error")) { + val b64encoded: String = uniffi.zingo.saveToB64() + if (b64encoded.lowercase().startsWith(ErrorPrefix.value)) { // with error don't save the file. Obviously. Log.e("MAIN", "Couldn't save the wallet. $b64encoded") - return + return false } // Log.i("MAIN", b64encoded) @@ -92,44 +80,41 @@ class RPCModule internal constructor(private val reactContext: ReactApplicationC Log.i("MAIN", "file size: ${fileBytes.size} bytes") // Save file to disk - val file = MainApplication.getAppContext()?.openFileOutput(walletFileName, Context.MODE_PRIVATE) - file?.write(fileBytes) - file?.close() + writeFile(WalletFileName.value, fileBytes) } catch (e: IllegalArgumentException) { Log.e("MAIN", "Couldn't save the wallet") + return false } + return true } - private fun saveWalletBackupFile() { + private fun saveWalletBackupFile(): Boolean { // Get the encoded wallet file // Read the file - val fileRead = MainApplication.getAppContext()!!.openFileInput(walletFileName) - val fileBytes = fileRead.readBytes() + val fileBytes = readFile(WalletFileName.value) // Log.i("MAIN", b64encoded) try { // Log.i("MAIN", "file size${fileBytes.size}") // Save file to disk - val file = MainApplication.getAppContext()?.openFileOutput(walletBackupFileName, Context.MODE_PRIVATE) - file?.write(fileBytes) - file?.close() + writeFile(WalletBackupFileName.value, fileBytes) } catch (e: IllegalArgumentException) { Log.e("MAIN", "Couldn't save the wallet backup") + return false } + return true } fun saveBackgroundFile(json: String) { // Log.i("MAIN", b64encoded) try { - val fileBytes: ByteArray = json.toByteArray() + val fileBytes = json.toByteArray() Log.i("MAIN", "file background size: ${fileBytes.size} bytes") // Save file to disk - val file = MainApplication.getAppContext()?.openFileOutput(backgroundFileName, Context.MODE_PRIVATE) - file?.write(fileBytes) - file?.close() + writeFile(BackgroundFileName.value, fileBytes) } catch (e: IllegalArgumentException) { Log.e("MAIN", "Couldn't save the background file") } @@ -142,14 +127,14 @@ class RPCModule internal constructor(private val reactContext: ReactApplicationC uniffi.zingo.initLogging() // Create a seed - val seed = uniffi.zingo.initNew(server, reactContext.applicationContext.filesDir.absolutePath, chainhint, true) - // Log.i("MAIN-Seed", seed) + val resp = uniffi.zingo.initNew(server, getDocumentDirectory(), chainhint, true) + // Log.i("MAIN-Seed", resp) - if (!seed.lowercase().startsWith(errorPrefix)) { + if (!resp.lowercase().startsWith(ErrorPrefix.value)) { saveWalletFile() } - promise.resolve(seed) + promise.resolve(resp) } @ReactMethod @@ -158,14 +143,14 @@ class RPCModule internal constructor(private val reactContext: ReactApplicationC uniffi.zingo.initLogging() - val rseed = uniffi.zingo.initFromSeed(server, seed, birthday.toULong(), reactContext.applicationContext.filesDir.absolutePath, chainhint, true) - // Log.i("MAIN", rseed) + val resp = uniffi.zingo.initFromSeed(server, seed, birthday.toULong(), getDocumentDirectory(), chainhint, true) + // Log.i("MAIN", resp) - if (!rseed.lowercase().startsWith(errorPrefix)) { + if (!resp.lowercase().startsWith(ErrorPrefix.value)) { saveWalletFile() } - promise.resolve(rseed) + promise.resolve(resp) } @ReactMethod @@ -174,14 +159,14 @@ class RPCModule internal constructor(private val reactContext: ReactApplicationC uniffi.zingo.initLogging() - val rufvk = uniffi.zingo.initFromUfvk(server, ufvk, birthday.toULong(), reactContext.applicationContext.filesDir.absolutePath, chainhint, true) - // Log.i("MAIN", rufvk) + val resp = uniffi.zingo.initFromUfvk(server, ufvk, birthday.toULong(), reactContext.applicationContext.filesDir.absolutePath, chainhint, true) + // Log.i("MAIN", resp) - if (!rufvk.lowercase().startsWith(errorPrefix)) { + if (!resp.lowercase().startsWith(ErrorPrefix.value)) { saveWalletFile() } - promise.resolve(rufvk) + promise.resolve(resp) } @ReactMethod @@ -191,9 +176,7 @@ class RPCModule internal constructor(private val reactContext: ReactApplicationC fun loadExistingWalletNative(server: String, chainhint: String): String { // Read the file - val file: InputStream = MainApplication.getAppContext()?.openFileInput(walletFileName)!! - val fileBytes = file.readBytes() - file.close() + val fileBytes = readFile(WalletFileName.value) val middle0w = 0 val middle1w = 6000000 // 6_000_000 - 8 pieces @@ -363,29 +346,25 @@ class RPCModule internal constructor(private val reactContext: ReactApplicationC @ReactMethod fun restoreExistingWalletBackup(promise: Promise) { // Read the file backup - val fileBackup = MainApplication.getAppContext()!!.openFileInput(walletBackupFileName) - val fileBytesBackup = fileBackup.readBytes() + val fileBytesBackup = readFile(WalletBackupFileName.value) // Read the file wallet - val fileWallet = MainApplication.getAppContext()!!.openFileInput(walletFileName) - val fileBytesWallet = fileWallet.readBytes() + val fileBytesWallet = readFile(WalletFileName.value) try { // Save file to disk wallet (with the backup) - val fileWallet2 = MainApplication.getAppContext()?.openFileOutput(walletFileName, Context.MODE_PRIVATE) - fileWallet2?.write(fileBytesBackup) - fileWallet2?.close() + writeFile(WalletFileName.value, fileBytesBackup) } catch (e: IllegalArgumentException) { Log.e("MAIN", "Couldn't save the wallet with the backup") + promise.resolve(false) } try { // Save file to disk backup (with the wallet) - val fileBackup2 = MainApplication.getAppContext()?.openFileOutput(walletBackupFileName, Context.MODE_PRIVATE) - fileBackup2?.write(fileBytesWallet) - fileBackup2?.close() + writeFile(WalletBackupFileName.value, fileBytesWallet) } catch (e: IllegalArgumentException) { Log.e("MAIN", "Couldn't save the backup with the wallet") + promise.resolve(false) } promise.resolve(true) @@ -394,13 +373,8 @@ class RPCModule internal constructor(private val reactContext: ReactApplicationC @ReactMethod fun deleteExistingWallet(promise: Promise) { // check first if the file exists - if (wallet_exists()) { - val file = MainApplication.getAppContext()?.getFileStreamPath(walletFileName) - if (file!!.delete()) { - promise.resolve(true) - } else { - promise.resolve(false) - } + if (fileExists(WalletFileName.value)) { + promise.resolve(deleteFile(WalletFileName.value)) } else { promise.resolve(false) } @@ -409,13 +383,8 @@ class RPCModule internal constructor(private val reactContext: ReactApplicationC @ReactMethod fun deleteExistingWalletBackup(promise: Promise) { // check first if the file exists - if (walletBackup_exists()) { - val file = MainApplication.getAppContext()?.getFileStreamPath(walletBackupFileName) - if (file!!.delete()) { - promise.resolve(true) - } else { - promise.resolve(false) - } + if (fileExists(WalletBackupFileName.value)) { + promise.resolve(deleteFile((WalletBackupFileName.value))) } else { promise.resolve(false) } @@ -432,7 +401,7 @@ class RPCModule internal constructor(private val reactContext: ReactApplicationC // Log.i("execute", "Response to $cmd : $resp") // And save it if it was a sync - if (cmd == "sync" && !resp.lowercase().startsWith(errorPrefix)) { + if (cmd == "sync" && !resp.lowercase().startsWith(ErrorPrefix.value)) { saveWalletFile() } @@ -442,16 +411,12 @@ class RPCModule internal constructor(private val reactContext: ReactApplicationC @ReactMethod fun doSave(promise: Promise) { - saveWalletFile() - - promise.resolve(true) + promise.resolve(saveWalletFile()) } @ReactMethod fun doSaveBackup(promise: Promise) { - saveWalletBackupFile() - - promise.resolve(true) + promise.resolve(saveWalletBackupFile()) } @ReactMethod @@ -478,6 +443,18 @@ class RPCModule internal constructor(private val reactContext: ReactApplicationC promise.resolve(resp) } + @ReactMethod + fun getZenniesDonationAddress(promise: Promise) { + // Log.i("MAIN", "Initialize Light Client") + + uniffi.zingo.initLogging() + + // Initialize Light Client + val resp = uniffi.zingo.getZenniesForZingoDonationAddress() + + promise.resolve(resp) + } + @ReactMethod fun getValueTransfersList(promise: Promise) { // Log.i("MAIN", "Initialize Light Client") diff --git a/android/build.gradle b/android/build.gradle index aa76fdfae..54a2175e4 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -14,7 +14,7 @@ buildscript { mavenCentral() } dependencies { - classpath('com.android.tools.build:gradle:8.0.0') + classpath('com.android.tools.build:gradle:8.1.1') classpath("com.facebook.react:react-native-gradle-plugin") classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" } diff --git a/app/AppState/AppContextLoaded.ts b/app/AppState/AppContextLoaded.ts index e7c9dd015..60bfce9f3 100644 --- a/app/AppState/AppContextLoaded.ts +++ b/app/AppState/AppContextLoaded.ts @@ -31,14 +31,14 @@ export default interface AppContextLoaded { netInfo: NetInfoType; // The total confirmed and pending balance in this wallet - totalBalance: TotalBalanceClass; + totalBalance: TotalBalanceClass | null; // List of all addresses in the wallet, including change addresses and addresses // that don't have any balance or are unused - addresses: AddressClass[]; + addresses: AddressClass[] | null; // List of all T and Z and O value transfers - valueTransfers: ValueTransferType[]; + valueTransfers: ValueTransferType[] | null; // The state of the send page sendPageState: SendPageStateClass; diff --git a/app/AppState/AppContextLoading.ts b/app/AppState/AppContextLoading.ts index cb23482ce..c8c99b2a8 100644 --- a/app/AppState/AppContextLoading.ts +++ b/app/AppState/AppContextLoading.ts @@ -1,7 +1,5 @@ import { StackScreenProps } from '@react-navigation/stack'; -import TotalBalanceClass from './classes/TotalBalanceClass'; - import InfoType from './types/InfoType'; import WalletType from './types/WalletType'; import ZecPriceType from './types/ZecPriceType'; @@ -23,7 +21,6 @@ export default interface AppContextLoading { navigation: StackScreenProps['navigation']; netInfo: NetInfoType; wallet: WalletType; - totalBalance: TotalBalanceClass; info: InfoType; zecPrice: ZecPriceType; background: BackgroundType; diff --git a/app/LoadedApp/LoadedApp.tsx b/app/LoadedApp/LoadedApp.tsx index 446efe83c..eb4455967 100644 --- a/app/LoadedApp/LoadedApp.tsx +++ b/app/LoadedApp/LoadedApp.tsx @@ -12,6 +12,7 @@ import { Linking, SafeAreaView, Platform, + ActivityIndicator, } from 'react-native'; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome'; @@ -83,20 +84,20 @@ import AddressBookFileImpl from '../../components/AddressBook/AddressBookFileImp import simpleBiometrics from '../simpleBiometrics'; import ShowAddressAlertAsync from '../../components/Send/components/ShowAddressAlertAsync'; -const History = React.lazy(() => import('../../components/History')); -const Send = React.lazy(() => import('../../components/Send')); -const Receive = React.lazy(() => import('../../components/Receive')); +import History from '../../components/History'; +import Send from '../../components/Send'; +import Receive from '../../components/Receive'; +import Settings from '../../components/Settings'; +import Menu from './components/Menu'; + const About = React.lazy(() => import('../../components/About')); const Seed = React.lazy(() => import('../../components/Seed')); const Info = React.lazy(() => import('../../components/Info')); const SyncReport = React.lazy(() => import('../../components/SyncReport')); const Rescan = React.lazy(() => import('../../components/Rescan')); -const Settings = React.lazy(() => import('../../components/Settings')); const Pools = React.lazy(() => import('../../components/Pools')); const Insight = React.lazy(() => import('../../components/Insight')); const ShowUfvk = React.lazy(() => import('../../components/Ufvk/ShowUfvk')); - -const Menu = React.lazy(() => import('./components/Menu')); const ComputingTxContent = React.lazy(() => import('./components/ComputingTxContent')); const en = require('../translations/en.json'); @@ -262,8 +263,11 @@ export default function LoadedApp(props: LoadedAppProps) { setBackground(backgroundJson); } - // reading the address book - const ab = await AddressBookFileImpl.readAddressBook(); + // adding `Zenny Tips` address always. + const ab = await AddressBookFileImpl.writeAddressBookItem( + translate('zenny-tips-ab') as string, + await Utils.getZenniesDonationAddress(server.chainName), + ); setAddressBook(ab); setLoading(false); @@ -309,6 +313,26 @@ export default function LoadedApp(props: LoadedAppProps) { } } +type LoadingProps = { + backgroundColor: string; + spinColor: string; +}; + +const Loading: React.FC = ({ backgroundColor, spinColor }) => { + return ( + + + + ); +}; + type LoadedAppClassProps = { navigation: StackScreenProps['navigation']; route: StackScreenProps['route']; @@ -346,9 +370,9 @@ export class LoadedAppClass extends Component { - // this.setState({ poolsToShieldSelectSapling: value }); - //}; - - //setPoolsToShieldSelectTransparent = (value: boolean) => { - // this.setState({ poolsToShieldSelectTransparent: value }); - //}; - setTotalBalance = (totalBalance: TotalBalanceClass) => { if (!isEqual(this.state.totalBalance, totalBalance)) { //console.log('fetch total balance'); @@ -754,7 +770,8 @@ export class LoadedAppClass extends Component 0 ? valueTransfers.filter((vt: ValueTransferType) => vt.confirmations === 0).length : 0; // if a ValueTransfer go from 0 confirmations to > 0 -> Show a message about a ValueTransfer is confirmed - this.state.valueTransfers.length > 0 && + this.state.valueTransfers && + this.state.valueTransfers.length > 0 && this.state.valueTransfers .filter((vtOld: ValueTransferType) => !vtOld.confirmations || vtOld.confirmations === 0) .forEach((vtOld: ValueTransferType) => { @@ -762,8 +779,8 @@ export class LoadedAppClass extends Component vt.txid === vtOld.txid && vt.address === vtOld.address && vt.poolType === vtOld.poolType, ); - console.log('old', vtOld); - console.log('new', vtNew); + //console.log('old', vtOld); + //console.log('new', vtNew); // the ValueTransfer is confirmed if (vtNew.length > 0 && vtNew[0].confirmations > 0) { let message: string = ''; @@ -914,8 +931,14 @@ export class LoadedAppClass extends Component void): Promise => { try { // Construct a sendJson from the sendPage state - const { sendPageState, uaAddress, addresses, server, donation, translate } = this.state; - const sendJson = await Utils.getSendManyJSON(sendPageState, uaAddress, addresses, server, donation, translate); + const { sendPageState, uaAddress, addresses, server, donation } = this.state; + const sendJson = await Utils.getSendManyJSON( + sendPageState, + uaAddress, + addresses ? addresses : ([] as AddressClass[]), + server, + donation, + ); const txid = await this.rpc.sendTransaction(sendJson, setSendProgress); return txid; @@ -1038,7 +1061,7 @@ export class LoadedAppClass extends Component { @@ -1055,9 +1078,9 @@ export class LoadedAppClass extends Component - Loading... - - }> - - - ); + const menu = ; const fnTabBarIcon = (route: StackScreenProps['route'], focused: boolean) => { var iconName; @@ -1551,7 +1563,10 @@ export class LoadedAppClass extends Component @@ -1561,12 +1576,7 @@ export class LoadedAppClass extends Component this.setState({ aboutModalVisible: false })}> - - {translate('loading') as string} - - }> + }> this.setState({ aboutModalVisible: false })} /> @@ -1576,12 +1586,7 @@ export class LoadedAppClass extends Component this.setState({ infoModalVisible: false })}> - - {translate('loading') as string} - - }> + }> this.setState({ infoModalVisible: false })} setZecPrice={this.setZecPrice} /> @@ -1591,12 +1596,7 @@ export class LoadedAppClass extends Component this.setState({ syncReportModalVisible: false })}> - - {translate('loading') as string} - - }> + }> this.setState({ syncReportModalVisible: false })} /> @@ -1606,12 +1606,7 @@ export class LoadedAppClass extends Component this.setState({ poolsModalVisible: false })}> - - {translate('loading') as string} - - }> + }> this.setState({ poolsModalVisible: false })} setPrivacyOption={this.setPrivacyOption} @@ -1624,17 +1619,10 @@ export class LoadedAppClass extends Component this.setState({ insightModalVisible: false })}> - - {translate('loading') as string} - - }> + }> this.setState({ insightModalVisible: false })} - openModal={() => this.setState({ insightModalVisible: true })} setPrivacyOption={this.setPrivacyOption} - setSendPageState={this.setSendPageState} /> @@ -1644,12 +1632,7 @@ export class LoadedAppClass extends Component this.setState({ rescanModalVisible: false })}> - - {translate('loading') as string} - - }> + }> this.setState({ rescanModalVisible: false })} doRescan={this.doRescan} /> @@ -1659,27 +1642,20 @@ export class LoadedAppClass extends Component this.setState({ settingsModalVisible: false })}> - - {translate('loading') as string} - - }> - this.setState({ settingsModalVisible: false })} - setWalletOption={this.setWalletOption} - setServerOption={this.setServerOption} - setCurrencyOption={this.setCurrencyOption} - setLanguageOption={this.setLanguageOption} - setSendAllOption={this.setSendAllOption} - setDonationOption={this.setDonationOption} - setPrivacyOption={this.setPrivacyOption} - setModeOption={this.setModeOption} - setSecurityOption={this.setSecurityOption} - setSelectServerOption={this.setSelectServerOption} - setRescanMenuOption={this.setRescanMenuOption} - /> - + this.setState({ settingsModalVisible: false })} + setWalletOption={this.setWalletOption} + setServerOption={this.setServerOption} + setCurrencyOption={this.setCurrencyOption} + setLanguageOption={this.setLanguageOption} + setSendAllOption={this.setSendAllOption} + setDonationOption={this.setDonationOption} + setPrivacyOption={this.setPrivacyOption} + setModeOption={this.setModeOption} + setSecurityOption={this.setSecurityOption} + setSelectServerOption={this.setSelectServerOption} + setRescanMenuOption={this.setRescanMenuOption} + /> this.setState({ seedViewModalVisible: false })}> - - {translate('loading') as string} - - }> + }> this.setState({ seedViewModalVisible: false })} onClickCancel={() => this.setState({ seedViewModalVisible: false })} @@ -1707,12 +1678,7 @@ export class LoadedAppClass extends Component this.setState({ seedChangeModalVisible: false })}> - - {translate('loading') as string} - - }> + }> await this.onClickOKChangeWallet({ startingApp: false })} onClickCancel={() => this.setState({ seedChangeModalVisible: false })} @@ -1727,12 +1693,7 @@ export class LoadedAppClass extends Component this.setState({ seedBackupModalVisible: false })}> - - {translate('loading') as string} - - }> + }> await this.onClickOKRestoreBackup()} onClickCancel={() => this.setState({ seedBackupModalVisible: false })} @@ -1747,12 +1708,7 @@ export class LoadedAppClass extends Component this.setState({ seedServerModalVisible: false })}> - - {translate('loading') as string} - - }> + }> await this.onClickOKServerWallet()} onClickCancel={async () => { @@ -1771,12 +1727,7 @@ export class LoadedAppClass extends Component this.setState({ ufvkViewModalVisible: false })}> - - {translate('loading') as string} - - }> + }> this.setState({ ufvkViewModalVisible: false })} onClickCancel={() => this.setState({ ufvkViewModalVisible: false })} @@ -1791,12 +1742,7 @@ export class LoadedAppClass extends Component this.setState({ ufvkChangeModalVisible: false })}> - - {translate('loading') as string} - - }> + }> await this.onClickOKChangeWallet({ startingApp: false })} onClickCancel={() => this.setState({ ufvkChangeModalVisible: false })} @@ -1811,12 +1757,7 @@ export class LoadedAppClass extends Component this.setState({ ufvkBackupModalVisible: false })}> - - {translate('loading') as string} - - }> + }> await this.onClickOKRestoreBackup()} onClickCancel={() => this.setState({ ufvkBackupModalVisible: false })} @@ -1831,12 +1772,7 @@ export class LoadedAppClass extends Component this.setState({ ufvkServerModalVisible: false })}> - - {translate('loading') as string} - - }> + }> await this.onClickOKServerWallet()} onClickCancel={async () => { @@ -1855,12 +1791,7 @@ export class LoadedAppClass extends Component this.setState({ computingModalVisible: false })}> - - {translate('loading') as string} - - }> + }> @@ -1876,12 +1807,7 @@ export class LoadedAppClass extends Component {}, }) }> - - {translate('loading') as string} - - }> + }> this.setState({ @@ -1898,11 +1824,9 @@ export class LoadedAppClass extends Component - {mode !== ModeEnum.basic || - (mode === ModeEnum.basic && - (!(mode === ModeEnum.basic && valueTransfers.length <= 0) || - (!readOnly && - !(mode === ModeEnum.basic && totalBalance.spendableOrchard + totalBalance.spendablePrivate <= 0)))) ? ( + {mode === ModeEnum.advanced || + (!!valueTransfers && valueTransfers.length > 0) || + (!readOnly && !!totalBalance && totalBalance.spendableOrchard + totalBalance.spendablePrivate > 0) ? ( ({ @@ -1922,46 +1846,77 @@ export class LoadedAppClass extends Component {() => ( <> - - {translate('loading') as string} - - }> - {/**/} - - + )} {!readOnly && - !(mode === ModeEnum.basic && totalBalance.spendableOrchard + totalBalance.spendablePrivate <= 0) && ( + (mode === ModeEnum.advanced || + (!!totalBalance && totalBalance.spendableOrchard + totalBalance.spendablePrivate > 0)) && ( + {() => ( + <> + + + )} + + )} + + {() => ( + <> + + + )} + + + ) : ( + <> + {valueTransfers === null || addresses === null || totalBalance === null ? ( + + ) : ( + + {() => ( <> {translate('loading') as string} }> - {/**/} - )} - )} - - {() => ( - <> - - {translate('loading') as string} - - }> - - - - )} - - - ) : ( - - - {() => ( - <> - - {translate('loading') as string} - - }> - - - - )} - - + + )} + )} diff --git a/app/LoadedApp/components/Menu.tsx b/app/LoadedApp/components/Menu.tsx index 73080b943..e66bd4fbc 100644 --- a/app/LoadedApp/components/Menu.tsx +++ b/app/LoadedApp/components/Menu.tsx @@ -106,7 +106,7 @@ const Menu: React.FunctionComponent = ({ onItemSelected, updateMenuSt {translate('loadedapp.addressbook') as string} - {!(mode === ModeEnum.basic && valueTransfers.length <= 0) && ( + {!(mode === ModeEnum.basic && valueTransfers && valueTransfers.length <= 0) && ( onItemSelectedWrapper(MenuItemEnum.WalletSeedUfvk)} style={item}> {readOnly ? mode === ModeEnum.basic @@ -142,7 +142,7 @@ const Menu: React.FunctionComponent = ({ onItemSelected, updateMenuSt )} - {!(mode === ModeEnum.basic && valueTransfers.length <= 0) && ( + {!(mode === ModeEnum.basic && valueTransfers && valueTransfers.length <= 0) && ( onItemSelectedWrapper(MenuItemEnum.Insight)} style={item}> {translate('loadedapp.insight') as string} @@ -162,7 +162,7 @@ const Menu: React.FunctionComponent = ({ onItemSelected, updateMenuSt {translate('loadedapp.restorebackupwallet') as string} )} - {mode === ModeEnum.basic && valueTransfers.length === 0 && ( + {mode === ModeEnum.basic && valueTransfers && valueTransfers.length === 0 && ( onItemSelectedWrapper(MenuItemEnum.LoadWalletFromSeed)} style={item}> {translate('loadedapp.loadwalletfromseed-basic') as string} diff --git a/app/LoadingApp/LoadingApp.tsx b/app/LoadingApp/LoadingApp.tsx index fa477c194..8376870c7 100644 --- a/app/LoadingApp/LoadingApp.tsx +++ b/app/LoadingApp/LoadingApp.tsx @@ -1,5 +1,5 @@ /* eslint-disable react-native/no-inline-styles */ -import React, { Component, Suspense, useState, useMemo, useEffect } from 'react'; +import React, { Component, useState, useMemo, useEffect } from 'react'; import { View, Alert, @@ -54,7 +54,6 @@ import { GlobalConst, EventListenerEnum, AppContextLoading, - TotalBalanceClass, InfoType, ZecPriceType, BackgroundErrorType, @@ -77,11 +76,12 @@ import { isEqual } from 'lodash'; import { RPCWalletKindEnum } from '../rpc/enums/RPCWalletKindEnum'; import { RestoreFromTypeEnum } from '../AppState'; -const BoldText = React.lazy(() => import('../../components/Components/BoldText')); -const Button = React.lazy(() => import('../../components/Components/Button')); -const Seed = React.lazy(() => import('../../components/Seed')); -const ImportUfvk = React.lazy(() => import('../../components/Ufvk/ImportUfvk')); -const ChainTypeToggle = React.lazy(() => import('../../components/Components/ChainTypeToggle')); +// no lazy load because slowing down screens. +import BoldText from '../../components/Components/BoldText'; +import Button from '../../components/Components/Button'; +import Seed from '../../components/Seed'; +import ImportUfvk from '../../components/Ufvk/ImportUfvk'; +import ChainTypeToggle from '../../components/Components/ChainTypeToggle'; const en = require('../translations/en.json'); const es = require('../translations/es.json'); @@ -352,7 +352,6 @@ export class LoadingAppClass extends Component this.navigateToLoadedApp()}> - - {translate('loading') as string} - - }> - this.navigateToLoadedApp()} - onClickCancel={() => this.navigateToLoadedApp()} - action={SeedActionEnum.new} - setPrivacyOption={this.setPrivacyOption} - /> - + this.navigateToLoadedApp()} + onClickCancel={() => this.navigateToLoadedApp()} + action={SeedActionEnum.new} + setPrivacyOption={this.setPrivacyOption} + /> )} {screen === 3 && ( @@ -1335,17 +1324,10 @@ export class LoadingAppClass extends Component this.setState({ screen: 1 })}> - - {translate('loading') as string} - - }> - this.doRestore(s, b)} - onClickCancel={() => this.setState({ screen: 1 })} - /> - + this.doRestore(s, b)} + onClickCancel={() => this.setState({ screen: 1 })} + /> )} diff --git a/app/context/contextAppLoaded.tsx b/app/context/contextAppLoaded.tsx index 3d468f288..c548d7469 100644 --- a/app/context/contextAppLoaded.tsx +++ b/app/context/contextAppLoaded.tsx @@ -3,13 +3,11 @@ import { StackScreenProps } from '@react-navigation/stack'; import { SyncingStatusClass, - TotalBalanceClass, ReceivePageStateClass, SendProgressClass, WalletSettingsClass, InfoType, WalletType, - AddressClass, ZecPriceType, BackgroundType, SendPageStateClass, @@ -25,16 +23,15 @@ import { SelectServerEnum, SnackbarType, AppContextLoaded, - ValueTransferType, } from '../AppState'; export const defaultAppContextLoaded: AppContextLoaded = { navigation: {} as StackScreenProps['navigation'], netInfo: {} as NetInfoType, syncingStatus: new SyncingStatusClass(), - totalBalance: new TotalBalanceClass(), - addresses: [] as AddressClass[], - valueTransfers: [] as ValueTransferType[], + totalBalance: null, + addresses: null, + valueTransfers: null, sendPageState: new SendPageStateClass(new ToAddrClass(0)), receivePageState: new ReceivePageStateClass(''), info: {} as InfoType, @@ -62,8 +59,6 @@ export const defaultAppContextLoaded: AppContextLoaded = { setBackgroundError: () => {}, privacy: false, readOnly: false, - //poolsToShieldSelectSapling: true, - //poolsToShieldSelectTransparent: true, mode: ModeEnum.advanced, snackbars: [] as SnackbarType[], addLastSnackbar: () => {}, diff --git a/app/context/contextAppLoading.tsx b/app/context/contextAppLoading.tsx index 08e6e94af..9cea44bd9 100644 --- a/app/context/contextAppLoading.tsx +++ b/app/context/contextAppLoading.tsx @@ -4,7 +4,6 @@ import { StackScreenProps } from '@react-navigation/stack'; import { AppContextLoading, InfoType, - TotalBalanceClass, WalletType, ZecPriceType, BackgroundType, @@ -23,7 +22,6 @@ export const defaultAppContextLoading: AppContextLoading = { navigation: {} as StackScreenProps['navigation'], netInfo: {} as NetInfoType, wallet: {} as WalletType, - totalBalance: new TotalBalanceClass(), info: {} as InfoType, server: {} as ServerType, currency: CurrencyEnum.noCurrency, diff --git a/app/rpc/RPC.ts b/app/rpc/RPC.ts index 810578698..30818d481 100644 --- a/app/rpc/RPC.ts +++ b/app/rpc/RPC.ts @@ -54,7 +54,6 @@ export default class RPC { syncStatusTimerID?: NodeJS.Timeout; updateDataLock: boolean; - updateDataCtr: number; lastWalletBlockHeight: number; lastServerBlockHeight: number; @@ -98,8 +97,6 @@ export default class RPC { this.keepAwake = keepAwake; this.updateDataLock = false; - this.updateDataCtr = 0; - this.lastWalletBlockHeight = 0; this.lastServerBlockHeight = 0; this.walletBirthday = 0; @@ -235,13 +232,18 @@ export default class RPC { } static async rpcFetchServerHeight(): Promise { - const info = await RPC.rpcGetInfoObject(); + try { + const info = await RPC.rpcGetInfoObject(); - if (info) { - return info.latestBlock; - } + if (info) { + return info.latestBlock; + } - return 0; + return 0; + } catch (error) { + console.log(`Critical Error server block height ${error}`); + return 0; + } } static async rpcFetchWalletHeight(): Promise { @@ -268,7 +270,7 @@ export default class RPC { static async rpcShieldFunds(): Promise { try { const shieldStr: string = await RPCModule.execute(CommandEnum.confirm, ''); - console.log(shieldStr); + //console.log(shieldStr); if (shieldStr) { if (shieldStr.toLowerCase().startsWith(GlobalConst.error)) { console.log(`Error shield ${shieldStr}`); @@ -376,12 +378,12 @@ export default class RPC { // clean start. await this.stopSyncProcess(); - // every 30 seconds the App try to Sync the new blocks. + // every 15 seconds the App try to Sync the new blocks. if (!this.refreshTimerID) { this.refreshTimerID = setInterval(() => { //console.log('interval refresh'); this.refresh(false); - }, 30 * 1000); // 30 seconds + }, 15 * 1000); // 15 seconds //console.log('create refresh timer', this.refreshTimerID); this.timers.push(this.refreshTimerID); } @@ -411,6 +413,10 @@ export default class RPC { this.timers.splice(deleted[i], 1); } + await this.fetchWalletHeight(); + await this.fetchWalletBirthday(); + //await this.fetchInfoAndServerHeight(); + // Load the current wallet data await this.loadWalletData(); @@ -435,7 +441,7 @@ export default class RPC { return; } - console.log('stop sync process. in progress', ss.in_progress); + //console.log('stop sync process. in progress', ss.in_progress); while (ss.in_progress) { // interrupting sync process @@ -447,7 +453,7 @@ export default class RPC { returnStatus = await this.doSyncStatus(); ss = await JSON.parse(returnStatus); - console.log('stop sync process. in progress', ss.in_progress); + //console.log('stop sync process. in progress', ss.in_progress); } console.log('stop sync process. STOPPED'); @@ -518,7 +524,7 @@ export default class RPC { return rescanStr; } catch (error) { console.log(`Critical Error rescan ${error}`); - return `Error: ${error}`; + return `Error: rescan ${error}`; } } @@ -538,7 +544,7 @@ export default class RPC { return syncStr; } catch (error) { console.log(`Critical Error sync ${error}`); - return `Error: ${error}`; + return `Error: sync ${error}`; } } @@ -558,15 +564,14 @@ export default class RPC { return syncStatusStr; } catch (error) { console.log(`Critical Error sync status ${error}`); - return `Error: ${error}`; + return `Error: sync status ${error}`; } } async doSend(sendJSON: string): Promise { try { console.log('send JSON', sendJSON); - const preSendStr: String = await RPCModule.execute(CommandEnum.send, sendJSON); - console.log(preSendStr); + await RPCModule.execute(CommandEnum.send, sendJSON); const sendStr: string = await RPCModule.execute(CommandEnum.confirm, ''); if (sendStr) { if (sendStr.toLowerCase().startsWith(GlobalConst.error)) { @@ -581,7 +586,7 @@ export default class RPC { return sendStr; } catch (error) { console.log(`Critical Error send ${error}`); - return `Error: ${error}`; + return `Error: send ${error}`; } } @@ -601,41 +606,45 @@ export default class RPC { return sendProgressStr; } catch (error) { console.log(`Critical Error send progress ${error}`); - return `Error: ${error}`; + return `Error: send progress ${error}`; } } async loadWalletData() { - await this.fetchTotalBalance(); await this.fetchTandZandOValueTransfers(); - await this.fetchWalletSettings(); + await this.fetchAddresses(); + await this.fetchTotalBalance(); await this.fetchInfoAndServerHeight(); + await this.fetchWalletSettings(); } async updateData() { //console.log("Update data triggered"); if (this.updateDataLock) { - //console.log("Update lock, returning"); + console.log('Update lock, returning'); return; } - this.updateDataCtr += 1; - if ((this.inRefresh || this.inSend) && this.updateDataCtr % 5 !== 0) { - // We're refreshing, or sending, in which case update every 5th time - return; - } + // if the App have an error here + // this try-catch prevent to have true in updateDataLock. + try { + this.updateDataLock = true; - this.updateDataLock = true; + await this.fetchWalletHeight(); + await this.fetchWalletBirthday(); + //await this.fetchInfoAndServerHeight(); - await this.fetchWalletHeight(); - await this.fetchWalletBirthday(); - await this.fetchInfoAndServerHeight(); + // And fetch the rest of the data. + await this.loadWalletData(); - // And fetch the rest of the data. - await this.loadWalletData(); - - //console.log(`Finished update data at ${lastServerBlockHeight}`); - this.updateDataLock = false; + //console.log(`Finished update data at ${lastServerBlockHeight}`); + this.updateDataLock = false; + } catch (error) { + console.log('Internal error update data', error); + this.updateDataLock = false; + // relaunch the interval tasks just in case they are aborted. + this.configure(); + } } async refresh(fullRefresh: boolean, fullRescan?: boolean) { @@ -650,12 +659,12 @@ export default class RPC { return; } - // And fetch the rest of the data. - await this.loadWalletData(); - await this.fetchWalletHeight(); await this.fetchWalletBirthday(); - await this.fetchInfoAndServerHeight(); + //await this.fetchInfoAndServerHeight(); + + // And fetch the rest of the data. + await this.loadWalletData(); if (!this.lastServerBlockHeight) { //console.log('the last server block is zero'); @@ -692,7 +701,7 @@ export default class RPC { spendableOrchard: 0, spendablePrivate: 0, total: 0, - }); + } as TotalBalanceClass); this.doRescan() .then(result => { console.log('rescan finished', result); @@ -765,12 +774,12 @@ export default class RPC { // if the syncId change then reset the % if (this.prevSyncId !== this.syncId) { if (this.prevSyncId !== -1) { - // And fetch the rest of the data. - await this.loadWalletData(); - await this.fetchWalletHeight(); await this.fetchWalletBirthday(); - await this.fetchInfoAndServerHeight(); + //await this.fetchInfoAndServerHeight(); + + // And fetch the rest of the data. + await this.loadWalletData(); await RPCModule.doSave(); @@ -898,12 +907,12 @@ export default class RPC { // here we can release the screen... this.keepAwake(false); - // And fetch the rest of the data. - await this.loadWalletData(); - await this.fetchWalletHeight(); await this.fetchWalletBirthday(); - await this.fetchInfoAndServerHeight(); + //await this.fetchInfoAndServerHeight(); + + // And fetch the rest of the data. + await this.loadWalletData(); await RPCModule.doSave(); @@ -930,12 +939,12 @@ export default class RPC { if (this.prevBatchNum !== batchNum) { // if finished batches really fast, the App have to save the wallet delayed. if (this.prevBatchNum !== -1 && this.batches >= 1) { - // And fetch the rest of the data. - await this.loadWalletData(); - await this.fetchWalletHeight(); await this.fetchWalletBirthday(); - await this.fetchInfoAndServerHeight(); + //await this.fetchInfoAndServerHeight(); + + // And fetch the rest of the data. + await this.loadWalletData(); await RPCModule.doSave(); this.batches = 0; @@ -1009,17 +1018,24 @@ export default class RPC { this.fnSetWalletSettings(walletSettings); } catch (error) { - console.log(`Critical Error transaction filter threshold ${error}`); + console.log(`Critical Error wallet settings ${error}`); return; } } async fetchInfoAndServerHeight(): Promise { - const info = await RPC.rpcGetInfoObject(); + try { + const info = await RPC.rpcGetInfoObject(); - if (info) { - this.fnSetInfo(info); - this.lastServerBlockHeight = info.latestBlock; + if (info) { + this.fnSetInfo(info); + this.lastServerBlockHeight = info.latestBlock; + } + } catch (error) { + console.log(`Critical Error info & server block height ${error}`); + // relaunch the interval tasks just in case they are aborted. + this.configure(); + return; } } @@ -1142,7 +1158,55 @@ export default class RPC { this.fnSetAllAddresses(allAddresses); } catch (error) { - console.log(`Critical Error notes ${error}`); + console.log(`Critical Error addresses balances notes ${error}`); + // relaunch the interval tasks just in case they are aborted. + this.configure(); + return; + } + } + + // This method will get the total balances + async fetchAddresses() { + try { + const addressesStr: string = await RPCModule.execute(CommandEnum.addresses, ''); + if (addressesStr) { + if (addressesStr.toLowerCase().startsWith(GlobalConst.error)) { + console.log(`Error addresses ${addressesStr}`); + return; + } + } else { + console.log('Internal Error addresses'); + return; + } + const addressesJSON: RPCAddressType[] = await JSON.parse(addressesStr); + + let allAddresses: AddressClass[] = []; + + addressesJSON.forEach((u: RPCAddressType) => { + // If this has any pending txns, show that in the UI + const receivers: string = + (u.receivers.orchard_exists ? ReceiverEnum.o : '') + + (u.receivers.sapling ? ReceiverEnum.z : '') + + (u.receivers.transparent ? ReceiverEnum.t : ''); + if (u.address) { + const abu = new AddressClass(u.address, u.address, AddressKindEnum.u, receivers); + allAddresses.push(abu); + } + if (u.address && u.receivers.sapling) { + const abz = new AddressClass(u.address, u.receivers.sapling, AddressKindEnum.z, receivers); + allAddresses.push(abz); + } + if (u.address && u.receivers.transparent) { + const abt = new AddressClass(u.address, u.receivers.transparent, AddressKindEnum.t, receivers); + allAddresses.push(abt); + } + }); + + this.fnSetAllAddresses(allAddresses); + } catch (error) { + console.log(`Critical Error addresses ${error}`); + // relaunch the interval tasks just in case they are aborted. + this.configure(); return; } } @@ -1164,15 +1228,24 @@ export default class RPC { this.lastWalletBlockHeight = heightJSON.height; } catch (error) { console.log(`Critical Error wallet height ${error}`); + // relaunch the interval tasks just in case they are aborted. + this.configure(); return; } } async fetchWalletBirthday(): Promise { - const wallet = await RPC.rpcFetchWallet(this.readOnly); + try { + const wallet = await RPC.rpcFetchWallet(this.readOnly); - if (wallet) { - this.walletBirthday = wallet.birthday; + if (wallet) { + this.walletBirthday = wallet.birthday; + } + } catch (error) { + console.log(`Critical Error wallet birthday ${error}`); + // relaunch the interval tasks just in case they are aborted. + this.configure(); + return; } } @@ -1194,6 +1267,8 @@ export default class RPC { //console.log(valueTransfersJSON); + await this.fetchWalletHeight(); + await this.fetchWalletBirthday(); await this.fetchInfoAndServerHeight(); let vtList: ValueTransferType[] = []; @@ -1249,6 +1324,8 @@ export default class RPC { this.fnSetValueTransfersList(vtList); } catch (error) { console.log(`Critical Error txs list value transfers ${error}`); + // relaunch the interval tasks just in case they are aborted. + this.configure(); return; } } @@ -1327,7 +1404,7 @@ export default class RPC { progress = await JSON.parse(pro); sendId = progress.id; } catch (e) { - console.log(e); + console.log('Error parsing status send progress', e); if (!sendTxid && !sendError) { return; } diff --git a/app/translations/en.json b/app/translations/en.json index d6f463480..e86632166 100644 --- a/app/translations/en.json +++ b/app/translations/en.json @@ -1,6 +1,6 @@ { "zingo": "Zingo", - "version": "zingo-1.4.2 (186)", + "version": "zingo-1.4.3 (187)", "loading": "loading...", "connectingserver": "Connecting to the server...", "wait": "Please wait...", @@ -21,7 +21,9 @@ "confirm": "Confirm", "menudrawer-acc": "Open Menu Drawer", "menu-acc": "Open Menu", - "donation": "Thanks for supporting ZingoLabs!", + "donation": "Donation to Zingo!\nThanks for supporting ZingoLabs!", + "zenny-tips-ab": "Zenny Tips", + "nym-donation": "I need Nym network security!", "restarting": "Error connecting to the Server, the App will restart in a few seconds.", "change-privacy": "New privacy policy: ", "warning-binance": "WARNING: Binance is collecting and holding user funds without timely recourse. Do NOT deposit into Binance from this Wallet.", @@ -132,7 +134,6 @@ "selectingserver": "Determining the best lightwalletd.", "selectingserversame": "Your actual server is the most optimized one already.", "selectingserverbest": "In this moment this is the most optimized server:", - "nymmemo": "I need Nym network security", "incoming-funds": "Incoming funds\n", "valuetransfer-confirmed": "Transaction confirmed\n", "payment-made": "Payment made\n", diff --git a/app/translations/es.json b/app/translations/es.json index 707b8b75e..fcdc68212 100644 --- a/app/translations/es.json +++ b/app/translations/es.json @@ -1,6 +1,6 @@ { "zingo": "Zingo", - "version": "zingo-1.4.2 (186)", + "version": "zingo-1.4.3 (187)", "loading": "cargando...", "connectingserver": "Conectando con el servidor...", "wait": "Por favor espere...", @@ -21,7 +21,9 @@ "confirm": "Confirmar", "menudrawer-acc": "Abrir Menú Lateral", "menu-acc": "Abrir Menú", - "donation": "Gracias por apoyar ZingoLabs!", + "donation": "¡Donación a Zingo!\n¡Gracias por apoyar a ZingoLabs!", + "zenny-tips-ab": "Zenny Propinas", + "nym-donation": "¡Necesito seguridad de red Nym!", "restarting": "Error conectando con el servidor, la Aplicación se reiniciará en breves segundos.", "change-privacy": "Nueva Política de Privacidad: ", "warning-binance": "ADVERTENCIA: Binance recopila y retiene los fondos de los usuarios sin un recurso oportuno. NO deposite en Binance desde este Monedero.", @@ -132,7 +134,6 @@ "selectingserver": "Determinando el mejor lightwalletd.", "selectingserversame": "Su servidor actual ya es el más optimizado.", "selectingserverbest": "En este momento este es el servidor más optimizado:", - "nymmemo": "Necesito seguridad de red Nym", "incoming-funds": "Fondos entrantes\n", "valuetransfer-confirmed": "Transacción confirmada\n", "payment-made": "Pago realizado\n", diff --git a/app/translations/pt.json b/app/translations/pt.json index cdeae6da5..eeca0d3b5 100644 --- a/app/translations/pt.json +++ b/app/translations/pt.json @@ -1,6 +1,6 @@ { "zingo": "Zingo", - "version": "zingo-1.4.2 (186)", + "version": "zingo-1.4.3 (187)", "loading": "carregando...", "connectingserver": "Conectando-se ao servidor...", "wait": "Aguarde um momento...", @@ -21,7 +21,9 @@ "confirm": "Confirmar", "menudrawer-acc": "Abrir Menu Lateral", "menu-acc": "Abrir Menu", - "donation": "Obrigado por apoiar a ZingoLabs!", + "donation": "Doação para o Zingo!\nObrigado por apoiar o ZingoLabs!", + "zenny-tips-ab": "Zenny Gorjetas", + "nym-donation": "Eu preciso de segurança de rede Nym!", "restarting": "Erro ao conectar ao servidor, o aplicativo será reiniciado em alguns segundos.", "change-privacy": "Nova política de privacidade: ", "warning-binance": "AVISO: A Binance está coletando e mantendo fundos dos usuários sem recurso oportuno. NÃO deposite na Binance a partir desta Carteira.", @@ -132,7 +134,6 @@ "selectingserver": "Determinando a melhor lightwalletd.", "selectingserversame": "Seu servidor atual já é o mais otimizado.", "selectingserverbest": "Neste momento ele é o servidor mais otimizado:", - "nymmemo": "Eu preciso de segurança de rede Nym", "incoming-funds": "Fundos recebidos\n", "valuetransfer-confirmed": "Transação confirmada\n", "payment-made": "Pagamento efetuado\n", diff --git a/app/translations/ru.json b/app/translations/ru.json index 5671c93ab..fa541446c 100644 --- a/app/translations/ru.json +++ b/app/translations/ru.json @@ -1,6 +1,6 @@ { "zingo": "Zingo", - "version": "zingo-1.4.2 (186)", + "version": "zingo-1.4.3 (187)", "loading": "загрузка...", "connectingserver": "Подключение к серверу...", "wait": "Пожалуйста, подождите...", @@ -21,7 +21,9 @@ "confirm": "Подтвердить", "menudrawer-acc": "Открыть панель меню", "menu-acc": "Открыть меню", - "donation": "Спасибо за поддержку ZingoLabs!", + "donation": "Пожертвование в пользу Zingo!\nСпасибо за поддержку ZingoLabs!", + "zenny-tips-ab": "Zenny советы", + "nym-donation": "Мне нужна сетевая безопасность Nym!", "restarting": "Ошибка подключения к Серверу, приложение перезапустится через несколько секунд.", "change-privacy": "Новая политика конфиденциальности: ", "warning-binance": "ВНИМАНИЕ: Binance собирает и удерживает средства пользователей без своевременного обращения к ним. НЕ делайте депозиты на Binance с этого кошелька.", @@ -132,7 +134,6 @@ "selectingserver": "Определение ближайшего сервера.", "selectingserversame": "Ваш текущий сервер является ближайшим.", "selectingserverbest": "В этот момент его самый оптимизированный сервер:", - "nymmemo": "Мне нужна сетевая безопасность Nym", "incoming-funds": "Входящие средства\n", "valuetransfer-confirmed": "Транзакция подтверждена\n", "payment-made": "Платеж произведен\n", diff --git a/app/uris/checkServerURI.ts b/app/uris/checkServerURI.ts index d082069be..cb5a9caee 100644 --- a/app/uris/checkServerURI.ts +++ b/app/uris/checkServerURI.ts @@ -49,7 +49,7 @@ const checkServerURI = async (uri: string, oldUri: string): Promise { // donations only for mainnet. if (chainName === ChainNameEnum.mainChainName) { @@ -117,16 +118,54 @@ export default class Utils { return ''; } - static getDefaultDonationAmount(): string { + static getDonationAmount(): string { const { decimalSeparator } = getNumberFormatSettings(); return '0' + decimalSeparator + '01'; } - static getDefaultDonationMemo(translate: (key: string) => TranslateType): string { + static getDonationMemo(translate: (key: string) => TranslateType): string { return translate('donation') as string; } + // ZENNIES FOR ZINGO + static async getZenniesDonationAddress(chainName: ChainNameEnum): Promise { + // donations only for mainnet. + if (chainName === ChainNameEnum.mainChainName) { + // UA -> we need a fresh one. + const ua: string = await RPCModule.getZenniesDonationAddress(); + return ua; + } + return ''; + } + + static getZenniesDonationAmount(): string { + const { decimalSeparator } = getNumberFormatSettings(); + + return '0' + decimalSeparator + '01'; + } + + // NYM + static async getNymDonationAddress(chainName: ChainNameEnum): Promise { + // donations only for mainnet. + if (chainName === ChainNameEnum.mainChainName) { + // UA -> we need a fresh one. + const ua: string = await RPCModule.getDonationAddress(); + return ua; + } + return ''; + } + + static getNymDonationAmount(): string { + const { decimalSeparator } = getNumberFormatSettings(); + + return '0' + decimalSeparator + '01'; + } + + static getNymDonationMemo(translate: (key: string) => TranslateType): string { + return translate('nym-donation') as string; + } + static utf16Split(s: string, chunksize: number): string[] { const ans = []; @@ -198,7 +237,6 @@ export default class Utils { addresses: AddressClass[], server: ServerType, donation: boolean, - translate: (key: string) => TranslateType, ): Promise { let donationAddress: boolean = false; const json: Promise = Promise.all( @@ -206,7 +244,10 @@ export default class Utils { const memo = `${to.memo || ''}${to.includeUAMemo ? '\nReply to: \n' + uaAddress : ''}`; const amount = parseInt((Utils.parseStringLocaleToNumberFloat(to.amount) * 10 ** 8).toFixed(0), 10); - donationAddress = to.to === (await Utils.getDonationAddress(server.chainName)); + donationAddress = + to.to === (await Utils.getDonationAddress(server.chainName)) || + to.to === (await Utils.getZenniesDonationAddress(server.chainName)) || + to.to === (await Utils.getNymDonationAddress(server.chainName)); if (memo === '') { return [{ address: to.to, amount } as SendJsonToTypeType]; @@ -240,16 +281,16 @@ export default class Utils { const donationTransaction: SendJsonToTypeType[] = []; // we need to exclude 2 use cases: - // 1. send to self (make no sense to do a donation here) - // 2. send to donation UA (make no sense to do a double donation) + // 2. send to one of our donation UA's + // (make no sense to do a double donation) if (donation && server.chainName === ChainNameEnum.mainChainName && !donationAddress) { donationTransaction.push({ - address: await Utils.getDonationAddress(server.chainName), + address: await Utils.getZenniesDonationAddress(server.chainName), amount: parseInt( - (Utils.parseStringLocaleToNumberFloat(Utils.getDefaultDonationAmount()) * 10 ** 8).toFixed(0), + (Utils.parseStringLocaleToNumberFloat(Utils.getZenniesDonationAmount()) * 10 ** 8).toFixed(0), 10, ), - memo: Utils.getDefaultDonationMemo(translate) + '\n' + translate('settings.donation-title'), + memo: '', // zancas decision to not leak info with no reason. }); } diff --git a/components/AddressBook/AddressBook.tsx b/components/AddressBook/AddressBook.tsx index b1080848b..87f7aa2e8 100644 --- a/components/AddressBook/AddressBook.tsx +++ b/components/AddressBook/AddressBook.tsx @@ -36,6 +36,7 @@ import AddressBookFileImpl from './AddressBookFileImpl'; import RPC from '../../app/rpc'; import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome'; import { faAnglesUp } from '@fortawesome/free-solid-svg-icons'; +import Utils from '../../app/utils'; type AddressBookProps = { closeModal: () => void; @@ -45,13 +46,14 @@ type AddressBookProps = { const AddressBook: React.FunctionComponent = ({ closeModal, setAddressBook, setSendPageState }) => { const context = useContext(ContextAppLoaded); - const { translate, language, addressBook, addressBookCurrentAddress, addressBookOpenPriorModal } = context; + const { translate, language, addressBook, addressBookCurrentAddress, addressBookOpenPriorModal, server } = context; const { colors } = useTheme() as unknown as ThemeType; moment.locale(language); const [numAb, setNumAb] = useState(50); const [loadMoreButton, setLoadMoreButton] = useState(false); const [addressBookSorted, setAddressBookSorted] = useState([]); + const [addressBookProtected, setAddressBookProtected] = useState([]); const [currentItem, setCurrentItem] = useState(null); const [titleViewHeight, setTitleViewHeight] = useState(0); @@ -64,20 +66,29 @@ const AddressBook: React.FunctionComponent = ({ closeModal, se useScrollToTop(scrollViewRef); const fetchAddressBookSorted = useMemo(async () => { + // excluding this address from the list + const zennyTips = await Utils.getZenniesDonationAddress(server.chainName); return addressBook + .filter((ab: AddressBookFileClass) => ab.address !== zennyTips) .sort((a, b) => { - const nA = a.label.toUpperCase(); - const nB = b.label.toUpperCase(); - if (nA < nB) { - return -1; - } else if (nA > nB) { - return 1; - } else { - return 0; - } + const aLabel = a.label; + const bLabel = b.label; + return aLabel.localeCompare(bLabel); }) .slice(0, numAb); - }, [addressBook, numAb]); + }, [addressBook, numAb, server.chainName]); + + const fetchAddressBookProtected = useMemo(async () => { + // only protected address to use internally ZingoLabs. + const zennyTips = await Utils.getZenniesDonationAddress(server.chainName); + return addressBook + .filter((ab: AddressBookFileClass) => ab.address === zennyTips) + .sort((a, b) => { + const aLabel = a.label; + const bLabel = b.label; + return aLabel.localeCompare(bLabel); + }); + }, [addressBook, server.chainName]); // because this screen is fired from more places than the menu. useEffect(() => { @@ -87,8 +98,10 @@ const AddressBook: React.FunctionComponent = ({ closeModal, se useEffect(() => { (async () => { const abs = await fetchAddressBookSorted; + const abp = await fetchAddressBookProtected; setLoadMoreButton(numAb < (abs.length || 0)); setAddressBookSorted(abs); + setAddressBookProtected(abp); // find the current address if (addressBookCurrentAddress) { const index: number = abs.findIndex((i: AddressBookFileClass) => i.address === addressBookCurrentAddress); @@ -100,7 +113,7 @@ const AddressBook: React.FunctionComponent = ({ closeModal, se setCurrentItem(index); } })(); - }, [addressBookCurrentAddress, fetchAddressBookSorted, numAb]); + }, [addressBookCurrentAddress, fetchAddressBookProtected, fetchAddressBookSorted, numAb]); useEffect(() => { const keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', () => { @@ -225,7 +238,7 @@ const AddressBook: React.FunctionComponent = ({ closeModal, se doAction={doAction} /> )} - {addressBookSorted.length === 0 && currentItem !== -1 && ( + {!addressBookCurrentAddress && addressBookSorted.length === 0 && currentItem !== -1 && ( = ({ closeModal, se ); })} + {!addressBookCurrentAddress && + addressBookProtected.flatMap((aBItem, index) => { + return ( + + + + ); + })} {loadMoreButton ? ( void; handleScrollToTop: () => void; doAction: (action: AddressBookActionEnum, label: string, address: string) => void; + addressProtected?: boolean; }; const AbSummaryLine: React.FunctionComponent = ({ index, @@ -42,6 +43,7 @@ const AbSummaryLine: React.FunctionComponent = ({ closeModal, handleScrollToTop, doAction, + addressProtected, }) => { const context = useContext(ContextAppLoaded); const { translate, navigation, readOnly, mode, totalBalance, language } = context; @@ -80,25 +82,34 @@ const AbSummaryLine: React.FunctionComponent = ({ flexDirection: 'row', marginTop: 15, paddingBottom: 15, - borderBottomWidth: 1, - borderBottomColor: colors.border, + borderBottomWidth: addressProtected ? 3 : 1, + borderBottomColor: addressProtected ? colors.zingo : colors.border, + opacity: addressProtected ? 0.5 : 1, }}> { - setCurrentItem(index); - setAction(AddressBookActionEnum.Modify); - handleScrollToTop(); + if (!addressProtected) { + setCurrentItem(index); + setAction(AddressBookActionEnum.Modify); + handleScrollToTop(); + } }}> + style={{ + fontSize: 18, + marginHorizontal: 10, + color: addressProtected ? colors.zingo : colors.primary, + opacity: 1, + fontWeight: 'bold', + }}> {displayContact} @@ -110,19 +121,26 @@ const AbSummaryLine: React.FunctionComponent = ({ - - { - setCurrentItem(index); - setAction(AddressBookActionEnum.Modify); - handleScrollToTop(); - }}> - - - + {!addressProtected && ( + + { + setCurrentItem(index); + setAction(AddressBookActionEnum.Modify); + handleScrollToTop(); + }}> + + + + )} {!readOnly && - !(mode === ModeEnum.basic && totalBalance.spendableOrchard + totalBalance.spendablePrivate <= 0) && ( + !addressProtected && + !( + mode === ModeEnum.basic && + totalBalance && + totalBalance.spendableOrchard + totalBalance.spendablePrivate <= 0 + ) && ( = ({ )} - - onPressDelete()}> - - - + {!addressProtected && ( + + onPressDelete()}> + + + + )} ); diff --git a/components/Components/AddressItem.tsx b/components/Components/AddressItem.tsx index 73005e8c5..94a0746d5 100644 --- a/components/Components/AddressItem.tsx +++ b/components/Components/AddressItem.tsx @@ -31,6 +31,7 @@ type AddressItemProps = { withIcon?: boolean; withSendIcon?: boolean; setSendPageState?: (s: SendPageStateClass) => void; + addressProtected?: boolean; }; const AddressItem: React.FunctionComponent = ({ @@ -42,6 +43,7 @@ const AddressItem: React.FunctionComponent = ({ closeModal, openModal, setSendPageState, + addressProtected, }) => { const context = useContext(ContextAppLoaded); const { @@ -127,7 +129,7 @@ const AddressItem: React.FunctionComponent = ({ {(!oneLine || (oneLine && !contact)) && !onlyContact && ( { - if (address && !oneLine) { + if (address && !oneLine && !addressProtected) { Clipboard.setString(address); addLastSnackbar({ message: translate('history.addresscopied') as string, @@ -178,9 +180,14 @@ const AddressItem: React.FunctionComponent = ({ )} {withSendIcon && setSendPageState && + !addressProtected && contact && !readOnly && - !(mode === ModeEnum.basic && totalBalance.spendableOrchard + totalBalance.spendablePrivate <= 0) && ( + !( + mode === ModeEnum.basic && + totalBalance && + totalBalance.spendableOrchard + totalBalance.spendablePrivate <= 0 + ) && ( { diff --git a/components/Components/CircularProgress.tsx b/components/Components/CircularProgress.tsx index a933732b8..14cfa71ab 100644 --- a/components/Components/CircularProgress.tsx +++ b/components/Components/CircularProgress.tsx @@ -27,7 +27,6 @@ const CircularProgress: React.FunctionComponent = props = return ( - {/* Background Circle */} = props = {...{ strokeWidth }} /> - {/* Progress Circle */} = props = {...{ strokeWidth }} /> - {/* Text */} = ({ setZecPrice, if (min < 60) { return min.toString(); } else { - return (min / 60).toFixed(0).toString() + ':' + (min % 60).toFixed(0).toString(); + return (min / 60).toFixed(0).toString() + ':' + (min % 60).toFixed(0).toString().padStart(2, '0'); } }; diff --git a/components/Header/Header.tsx b/components/Header/Header.tsx index 9d7f9abb3..9dcb734e1 100644 --- a/components/Header/Header.tsx +++ b/components/Header/Header.tsx @@ -67,8 +67,6 @@ type HeaderProps = { setBackgroundError?: (title: string, error: string) => void; noPrivacy?: boolean; setPrivacyOption?: (value: boolean) => Promise; - //setPoolsToShieldSelectSapling?: (v: boolean) => void; - //setPoolsToShieldSelectTransparent?: (v: boolean) => void; setUfvkViewModalVisible?: (v: boolean) => void; addLastSnackbar?: (snackbar: SnackbarType) => void; receivedLegend?: boolean; @@ -93,8 +91,6 @@ const Header: React.FunctionComponent = ({ setBackgroundError, noPrivacy, setPrivacyOption, - //setPoolsToShieldSelectSapling, - //setPoolsToShieldSelectTransparent, setUfvkViewModalVisible, addLastSnackbar, receivedLegend, @@ -110,8 +106,6 @@ const Header: React.FunctionComponent = ({ zecPrice, privacy, readOnly, - //poolsToShieldSelectSapling, - //poolsToShieldSelectTransparent, valueTransfers, wallet, restartApp, @@ -144,7 +138,6 @@ const Header: React.FunctionComponent = ({ const opacityValue = useRef(new Animated.Value(1)).current; const [showShieldButton, setShowShieldButton] = useState(false); - //const [poolsToShield, setPoolsToShield] = useState(PoolToShieldEnum.noPoolToShield); const [blocksRemaining, setBlocksRemaining] = useState(0); const [shieldingFee, setShieldingFee] = useState(0); @@ -206,97 +199,51 @@ const Header: React.FunctionComponent = ({ const runProposeStr = await runShieldPropose(); if (runProposeStr.toLowerCase().startsWith(GlobalConst.error)) { // snack with error - console.log(runProposeStr); + console.log('Error shield proposing', runProposeStr); //Alert.alert('Calculating the FEE', runProposeStr); } else { try { const runProposeJson: RPCShieldProposeType = JSON.parse(runProposeStr); if (runProposeJson.error) { // snack with error - console.log(runProposeJson.error); + console.log('Error shield proposing', runProposeJson.error); //Alert.alert('Calculating the FEE', runProposeJson.error); } else { if (runProposeJson.fee) { - console.log('fee', runProposeJson.fee); + //console.log('fee', runProposeJson.fee); proposeFee = runProposeJson.fee / 10 ** 8; } if (runProposeJson.value_to_shield) { - console.log('value to shield', runProposeJson.fee); + //console.log('value to shield', runProposeJson.fee); proposeAmount = runProposeJson.value_to_shield / 10 ** 8; } } } catch (e) { // snack with error - console.log(runProposeStr); + console.log('Error shield proposing', e); //Alert.alert('Calculating the FEE', runProposeJson.error); } } setShieldingFee(proposeFee); setShieldingAmount(proposeAmount); - console.log(proposeFee, proposeAmount); + //console.log(proposeFee, proposeAmount); })(); } - }, [readOnly, setShieldingAmount, totalBalance.transparentBal, somePending]); + }, [readOnly, setShieldingAmount, totalBalance?.transparentBal, somePending]); useEffect(() => { setShowShieldButton(!readOnly && (somePending ? 0 : shieldingAmount) > 0); - - //if ((somePending ? 0 : totalBalance.transparentBal) > 0 && totalBalance.spendablePrivate > 0) { - // setPoolsToShield(PoolToShieldEnum.allPoolToShield); - //} else if ((somePending ? 0 : totalBalance.transparentBal) > 0) { - // setPoolsToShield(PoolToShieldEnum.transparentPoolToShield); - //} else if (totalBalance.spendablePrivate > 0) { - // setPoolsToShield(PoolToShieldEnum.saplingPoolToShield); - //} else { - // setPoolsToShield(PoolToShieldEnum.noPoolToShield); - //} }, [readOnly, shieldingAmount, somePending]); - /* - useEffect(() => { - // for basic mode always have to be 'all', It's easier for the user. - if ( - mode === ModeEnum.basic && - (poolsToShield === PoolToShieldEnum.saplingPoolToShield || - poolsToShield === PoolToShieldEnum.transparentPoolToShield) - ) { - setPoolsToShield(PoolToShieldEnum.allPoolToShield); - if (setPoolsToShieldSelectSapling) { - setPoolsToShieldSelectSapling(true); - } - if (setPoolsToShieldSelectTransparent) { - setPoolsToShieldSelectTransparent(true); - } - } - }, [mode, poolsToShield, setPoolsToShieldSelectSapling, setPoolsToShieldSelectTransparent]); - */ - const shieldFunds = async () => { if (!setComputingModalVisible || !setBackgroundError || !addLastSnackbar || !setScrollToTop) { return; } - //if (poolsToShield === '') { - // return; - //} // now zingolib only can shield `transparent`. let pools: PoolToShieldEnum = PoolToShieldEnum.transparentPoolToShield; - //if (pools === PoolToShieldEnum.allPoolToShield) { - // if (!poolsToShieldSelectSapling && !poolsToShieldSelectTransparent) { - // pools = PoolToShieldEnum.noPoolToShield; - // } else if (poolsToShieldSelectSapling && !poolsToShieldSelectTransparent) { - // pools = PoolToShieldEnum.saplingPoolToShield; - // } else if (!poolsToShieldSelectSapling && poolsToShieldSelectTransparent) { - // pools = PoolToShieldEnum.transparentPoolToShield; - // } - //} - - //if (pools === '') { - // return; - //} - setComputingModalVisible(true); // We need to activate this flag because if the App is syncing // while shielding, then it going to finish the current batch @@ -304,8 +251,7 @@ const Header: React.FunctionComponent = ({ await RPC.rpcSetInterruptSyncAfterBatch(GlobalConst.true); // because I don't what the user is doing, I need to the re-run the shield // command right before the confirmation - const proposeStr: string = await RPCModule.execute(CommandEnum.shield, ''); - console.log(proposeStr); + await RPCModule.execute(CommandEnum.shield, ''); const shieldStr = await RPC.rpcShieldFunds(); if (shieldStr) { @@ -392,54 +338,14 @@ const Header: React.FunctionComponent = ({ }, [syncingStatus.inProgress, noSyncingStatus]); const calculateAmountToShield = (): string => { - //return poolsToShield === PoolToShieldEnum.saplingPoolToShield && totalBalance.spendablePrivate > shieldingFee - // ? Utils.parseNumberFloatToStringLocale(totalBalance.spendablePrivate - shieldingFee, 8) - // : poolsToShield === PoolToShieldEnum.transparentPoolToShield && - // (somePending ? 0 : totalBalance.transparentBal) > shieldingFee - // ? Utils.parseNumberFloatToStringLocale((somePending ? 0 : totalBalance.transparentBal) - shieldingFee, 8) - // : poolsToShieldSelectSapling && - // poolsToShieldSelectTransparent && - // totalBalance.spendablePrivate + (somePending ? 0 : totalBalance.transparentBal) > shieldingFee - // ? Utils.parseNumberFloatToStringLocale( - // totalBalance.spendablePrivate + (somePending ? 0 : totalBalance.transparentBal) - shieldingFee, - // 8, - // ) - // : poolsToShieldSelectSapling && totalBalance.spendablePrivate > shieldingFee - // ? Utils.parseNumberFloatToStringLocale(totalBalance.spendablePrivate - shieldingFee, 8) - // : poolsToShieldSelectTransparent && (somePending ? 0 : totalBalance.transparentBal) > shieldingFee - // ? Utils.parseNumberFloatToStringLocale((somePending ? 0 : totalBalance.transparentBal) - shieldingFee, 8) - // : '0'; return Utils.parseNumberFloatToStringLocale(somePending ? 0 : shieldingAmount, 8); }; const calculatePoolsToShield = (): string => { - //return poolsToShield !== PoolToShieldEnum.allPoolToShield - // ? poolsToShield - // : poolsToShieldSelectSapling && poolsToShieldSelectTransparent - // ? PoolToShieldEnum.allPoolToShield - // : poolsToShieldSelectSapling - // ? PoolToShieldEnum.saplingPoolToShield - // : poolsToShieldSelectTransparent - // ? PoolToShieldEnum.transparentPoolToShield - // : PoolToShieldEnum.allPoolToShield; return PoolToShieldEnum.transparentPoolToShield; }; const calculateDisableButtonToShield = (): boolean => { - //return poolsToShield === PoolToShieldEnum.saplingPoolToShield && totalBalance.spendablePrivate > shieldingFee - // ? false - // : poolsToShield === PoolToShieldEnum.transparentPoolToShield && - // (somePending ? 0 : totalBalance.transparentBal) > shieldingFee - // ? false - // : poolsToShieldSelectSapling && - // poolsToShieldSelectTransparent && - // totalBalance.spendablePrivate + (somePending ? 0 : totalBalance.transparentBal) > shieldingFee - // ? false - // : poolsToShieldSelectSapling && totalBalance.spendablePrivate > shieldingFee - // ? false - // : poolsToShieldSelectTransparent && (somePending ? 0 : totalBalance.transparentBal) > shieldingFee - // ? false - // : true; return (somePending ? 0 : shieldingAmount) <= shieldingFee; }; @@ -681,11 +587,12 @@ const Header: React.FunctionComponent = ({ currencyName={info.currencyName} color={colors.text} size={36} - amtZec={totalBalance.total} + amtZec={totalBalance ? totalBalance.total : 0} privacy={privacy} smallPrefix={true} /> {mode !== ModeEnum.basic && + totalBalance && (totalBalance.orchardBal !== totalBalance.spendableOrchard || totalBalance.privateBal > 0 || totalBalance.transparentBal > 0) && ( @@ -711,7 +618,7 @@ const Header: React.FunctionComponent = ({ )} - {receivedLegend && totalBalance.total > 0 && ( + {receivedLegend && totalBalance && totalBalance.total > 0 && ( = ({ @@ -747,7 +654,7 @@ const Header: React.FunctionComponent = ({ )} - {showShieldButton /*&& !!poolsToShield*/ && + {showShieldButton && setComputingModalVisible && (mode === ModeEnum.advanced || (mode === ModeEnum.basic && !calculateDisableButtonToShield())) && ( @@ -766,85 +673,6 @@ const Header: React.FunctionComponent = ({ onPress={onPressShieldFunds} disabled={calculateDisableButtonToShield()} /> - {/*mode !== ModeEnum.basic && - poolsToShield === PoolToShieldEnum.allPoolToShield && - setPoolsToShieldSelectSapling && - setPoolsToShieldSelectTransparent && ( - - setPoolsToShieldSelectSapling(!poolsToShieldSelectSapling)}> - - - - {translate('history.shield-z') as string} - - {poolsToShieldSelectSapling ? ( - - ) : ( - - )} - - - - setPoolsToShieldSelectTransparent(!poolsToShieldSelectTransparent)}> - - - - {translate('history.shield-t') as string} - - {poolsToShieldSelectTransparent ? ( - - ) : ( - - )} - - - - - )*/} )} @@ -883,8 +711,8 @@ const Header: React.FunctionComponent = ({ {readOnly && ( <> {setUfvkViewModalVisible && - !(mode === ModeEnum.basic && valueTransfers.length <= 0) && - !(mode === ModeEnum.basic && totalBalance.total <= 0) ? ( + !(mode === ModeEnum.basic && valueTransfers && valueTransfers.length <= 0) && + !(mode === ModeEnum.basic && totalBalance && totalBalance.total <= 0) ? ( ufvkShowModal()}> diff --git a/components/History/History.tsx b/components/History/History.tsx index 5c908c8d2..bd318b792 100644 --- a/components/History/History.tsx +++ b/components/History/History.tsx @@ -35,8 +35,6 @@ type HistoryProps = { setZecPrice: (p: number, d: number) => void; setComputingModalVisible: (visible: boolean) => void; setPrivacyOption: (value: boolean) => Promise; - //setPoolsToShieldSelectSapling: (v: boolean) => void; - //setPoolsToShieldSelectTransparent: (v: boolean) => void; setUfvkViewModalVisible?: (v: boolean) => void; setSendPageState: (s: SendPageStateClass) => void; setShieldingAmount: (value: number) => void; @@ -52,8 +50,6 @@ const History: React.FunctionComponent = ({ setZecPrice, setComputingModalVisible, setPrivacyOption, - //setPoolsToShieldSelectSapling, - //setPoolsToShieldSelectTransparent, setUfvkViewModalVisible, setSendPageState, setShieldingAmount, @@ -69,7 +65,7 @@ const History: React.FunctionComponent = ({ const [valueTransferDetail, setValueTransferDetail] = useState({} as ValueTransferType); const [valueTransferDetailIndex, setValueTransferDetailIndex] = useState(-1); const [numVt, setNumVt] = useState(50); - const [loadMoreButton, setLoadMoreButton] = useState(numVt < (valueTransfers.length || 0)); + const [loadMoreButton, setLoadMoreButton] = useState(false); const [valueTransfersSorted, setValueTransfersSorted] = useState([]); const [isAtTop, setIsAtTop] = useState(true); const scrollViewRef = useRef(null); @@ -85,6 +81,9 @@ const History: React.FunctionComponent = ({ // - txid // - address // - pool + if (!valueTransfers) { + return [] as ValueTransferType[]; + } return valueTransfers .sort((a: ValueTransferType, b: ValueTransferType) => { const timeComparison = b.time - a.time; @@ -119,7 +118,7 @@ const History: React.FunctionComponent = ({ }, [valueTransfers, numVt]); useEffect(() => { - setLoadMoreButton(numVt < (valueTransfers.length || 0)); + setLoadMoreButton(numVt < (valueTransfers ? valueTransfers.length : 0)); setValueTransfersSorted(fetchValueTransfersSorted); }, [fetchValueTransfersSorted, numVt, valueTransfers]); @@ -175,7 +174,7 @@ const History: React.FunctionComponent = ({ setValueTransferDetailModalShowing(false)} openModal={() => setValueTransferDetailModalShowing(true)} @@ -195,8 +194,6 @@ const History: React.FunctionComponent = ({ setComputingModalVisible={setComputingModalVisible} setBackgroundError={setBackgroundError} setPrivacyOption={setPrivacyOption} - //setPoolsToShieldSelectSapling={setPoolsToShieldSelectSapling} - //setPoolsToShieldSelectTransparent={setPoolsToShieldSelectTransparent} setUfvkViewModalVisible={setUfvkViewModalVisible} addLastSnackbar={addLastSnackbar} setShieldingAmount={setShieldingAmount} diff --git a/components/History/components/ValueTransferDetail.tsx b/components/History/components/ValueTransferDetail.tsx index 9f6005126..27e890ad1 100644 --- a/components/History/components/ValueTransferDetail.tsx +++ b/components/History/components/ValueTransferDetail.tsx @@ -67,6 +67,7 @@ const ValueTransferDetail: React.FunctionComponent = ( const [spendColor, setSpendColor] = useState(colors.primaryDisabled); const [expandTxid, setExpandTxid] = useState(false); const [showNavigator, setShowNavigator] = useState(true); + const [addressProtected, setAddressProtected] = useState(true); const isTheFirstMount = useRef(true); const memoTotal = vt.memos && vt.memos.length > 0 ? vt.memos.join('\n') : ''; @@ -91,6 +92,13 @@ const ValueTransferDetail: React.FunctionComponent = ( setSpendColor(spendCo); }, [colors.primary, colors.primaryDisabled, colors.text, vt.confirmations, vt.kind]); + useEffect(() => { + (async () => { + setAddressProtected(await isAddressProtected(vt.address ? vt.address : '')); + })(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [vt.address]); + const handleTxIDClick = (txid?: string) => { if (!txid) { return; @@ -126,10 +134,15 @@ const ValueTransferDetail: React.FunctionComponent = ( }; const thisWalletAddress: (add: string) => boolean = (add: string) => { - const address: AddressClass[] = addresses.filter((a: AddressClass) => a.address === add); + const address: AddressClass[] = addresses ? addresses.filter((a: AddressClass) => a.address === add) : []; return address.length >= 1; }; + const isAddressProtected: (add: string) => Promise = async (add: string) => { + const zennyTips = await Utils.getZenniesDonationAddress(server.chainName); + return zennyTips === add; + }; + //console.log('vt', index, totalLength, isTheFirstMount); return ( @@ -287,6 +300,7 @@ const ValueTransferDetail: React.FunctionComponent = ( setSendPageState={setSendPageState} closeModal={closeModal} openModal={openModal} + addressProtected={addressProtected} /> )} diff --git a/components/Insight/Insight.tsx b/components/Insight/Insight.tsx index 6fc882a1c..d52c9f870 100644 --- a/components/Insight/Insight.tsx +++ b/components/Insight/Insight.tsx @@ -18,7 +18,7 @@ import FadeText from '../Components/FadeText'; import Header from '../Header'; import RPCModule from '../../app/RPCModule'; import AddressItem from '../Components/AddressItem'; -import { ButtonTypeEnum, CommandEnum, SendPageStateClass, SnackbarDurationEnum } from '../../app/AppState'; +import { ButtonTypeEnum, CommandEnum, SnackbarDurationEnum } from '../../app/AppState'; import moment from 'moment'; import 'moment/locale/es'; import 'moment/locale/pt'; @@ -81,17 +81,10 @@ const getPercent = (percent: number) => { type InsightProps = { closeModal: () => void; - openModal: () => void; setPrivacyOption: (value: boolean) => Promise; - setSendPageState: (s: SendPageStateClass) => void; }; -const Insight: React.FunctionComponent = ({ - closeModal, - setPrivacyOption, - openModal, - setSendPageState, -}) => { +const Insight: React.FunctionComponent = ({ closeModal, setPrivacyOption }) => { const context = useContext(ContextAppLoaded); const { info, translate, privacy, addLastSnackbar, language } = context; const { colors } = useTheme() as unknown as ThemeType; @@ -130,7 +123,7 @@ const Insight: React.FunctionComponent = ({ try { resultJSON = await JSON.parse(resultStr); } catch (e) { - console.log(resultStr); + console.log('Error getting info from the server', e); resultJSON = {}; } let amounts: { value: number; address: string; tag: string }[] = []; @@ -217,10 +210,8 @@ const Insight: React.FunctionComponent = ({ oneLine={true} onlyContact={true} withIcon={true} - withSendIcon={true} - setSendPageState={setSendPageState} - closeModal={closeModal} - openModal={openModal} + closeModal={() => {}} + openModal={() => {}} /> )} {!expandAddress[index] && !!item.address && ( diff --git a/components/Pools/Pools.tsx b/components/Pools/Pools.tsx index 43a30cca3..19f2f1709 100644 --- a/components/Pools/Pools.tsx +++ b/components/Pools/Pools.tsx @@ -66,104 +66,107 @@ const Pools: React.FunctionComponent = ({ closeModal, setPrivacyOpti {translate('pools.orchard-title') as string} - - - 0 && totalBalance.spendableOrchard === totalBalance.orchardBal - ? 1 - : 0.5, - }} - privacy={privacy} - /> - - - 0 && totalBalance.spendableOrchard === totalBalance.orchardBal - ? colors.primary - : 'red' - } - privacy={privacy} - /> - - - - - - {translate('pools.sapling-title') as string} - - - - 0 && totalBalance.spendablePrivate === totalBalance.privateBal - ? 1 - : 0.5, - }} - privacy={privacy} - /> - - - 0 && totalBalance.spendablePrivate === totalBalance.privateBal - ? colors.syncing - : 'red' - } - privacy={privacy} - /> - - - - - - {translate('pools.transparent-title') as string} - - - - - - - - {somePending && ( - - - {translate('send.somefunds') as string} - + {totalBalance && ( + <> + + + 0 && totalBalance.spendableOrchard === totalBalance.orchardBal + ? 1 + : 0.5, + }} + privacy={privacy} + /> + + + 0 && totalBalance.spendableOrchard === totalBalance.orchardBal + ? colors.primary + : 'red' + } + privacy={privacy} + /> + + + + + + {translate('pools.sapling-title') as string} + + + + 0 && totalBalance.spendablePrivate === totalBalance.privateBal + ? 1 + : 0.5, + }} + privacy={privacy} + /> + + + 0 && totalBalance.spendablePrivate === totalBalance.privateBal + ? colors.syncing + : 'red' + } + privacy={privacy} + /> + + + + + + {translate('pools.transparent-title') as string} + + + + + + + {somePending && ( + + + {translate('send.somefunds') as string} + + )} + )} diff --git a/components/Receive/Receive.tsx b/components/Receive/Receive.tsx index ab309a581..d66ffb059 100644 --- a/components/Receive/Receive.tsx +++ b/components/Receive/Receive.tsx @@ -53,7 +53,7 @@ const Receive: React.FunctionComponent = ({ }; useEffect(() => { - if (addresses && addresses.length && uaAddress) { + if (addresses && addresses.length > 0 && uaAddress) { const uadd = addresses.filter(a => a.addressKind === AddressKindEnum.u) || []; const zadd = addresses.filter(a => a.uaAddress === uaAddress && a.addressKind === AddressKindEnum.z) || []; const tadd = addresses.filter(a => a.uaAddress === uaAddress && a.addressKind === AddressKindEnum.t) || []; @@ -63,6 +63,11 @@ const Receive: React.FunctionComponent = ({ const uaAddressIndex = uadd.findIndex(a => a.address === uaAddress); setUIndex(uaAddressIndex); + } else if (addresses && addresses.length > 0) { + const uadd = addresses.filter(a => a.addressKind === AddressKindEnum.u) || []; + setUaddrs(uadd); + + setUIndex(0); } }, [addresses, uaAddress]); diff --git a/components/Send/Send.tsx b/components/Send/Send.tsx index 4e6eef078..928d75185 100644 --- a/components/Send/Send.tsx +++ b/components/Send/Send.tsx @@ -1,5 +1,5 @@ /* eslint-disable react-native/no-inline-styles */ -import React, { useState, useEffect, useContext, useCallback } from 'react'; +import React, { useState, useEffect, useContext, useCallback, useRef } from 'react'; import { View, ScrollView, Modal, Keyboard, TextInput, TouchableOpacity, Platform, Text, Alert } from 'react-native'; import { faQrcode, @@ -34,6 +34,7 @@ import { ChainNameEnum, ButtonTypeEnum, GlobalConst, + AddressClass, } from '../../app/AppState'; import { parseZcashURI, ZcashURITargetClass } from '../../app/uris'; import RPCModule from '../../app/RPCModule'; @@ -73,8 +74,6 @@ type SendProps = { setZecPrice: (p: number, d: number) => void; setPrivacyOption: (value: boolean) => Promise; setShieldingAmount: (value: number) => void; - //setPoolsToShieldSelectSapling: (v: boolean) => void; - //setPoolsToShieldSelectTransparent: (v: boolean) => void; setScrollToTop: (value: boolean) => void; }; @@ -90,8 +89,6 @@ const Send: React.FunctionComponent = ({ setZecPrice, setPrivacyOption, setShieldingAmount, - //setPoolsToShieldSelectSapling, - //setPoolsToShieldSelectTransparent, setScrollToTop, }) => { const context = useContext(ContextAppLoaded); @@ -142,9 +139,13 @@ const Send: React.FunctionComponent = ({ //const [sendAllClick, setSendAllClick] = useState(false); const [proposeSendLastError, setProposeSendLastError] = useState(''); const [spendableBalanceLastError, setSpendableBalanceLastError] = useState(''); + const [keyboardVisible, setKeyboardVisible] = useState(false); + const [contentHeight, setContentHeight] = useState(0); + const [pickerTempSelectedAddress, setPickerTempSelectedAddress] = useState(''); const isFocused = useIsFocused(); const slideAnim = useSharedValue(0); + const scrollViewRef = useRef(null); const { decimalSeparator } = getNumberFormatSettings(); const runSendPropose = async ( @@ -176,11 +177,13 @@ const Send: React.FunctionComponent = ({ }; const defaultValuesSpendableMaxAmount = useCallback((): void => { - setSpendable(totalBalance.spendableOrchard + totalBalance.spendablePrivate); + setSpendable(totalBalance ? totalBalance.spendableOrchard + totalBalance.spendablePrivate : 0); const max = - totalBalance.spendableOrchard + - totalBalance.spendablePrivate - - (donation && !donationAddress ? Utils.parseStringLocaleToNumberFloat(Utils.getDefaultDonationAmount()) : 0); + (totalBalance ? totalBalance.spendableOrchard : 0) + + (totalBalance ? totalBalance.spendablePrivate : 0) - + (donation && server.chainName === ChainNameEnum.mainChainName && !donationAddress + ? Utils.parseStringLocaleToNumberFloat(Utils.getZenniesDonationAmount()) + : 0); if (max >= 0) { // if max is 0 then the user can send a memo with amount 0. setMaxAmount(max); @@ -191,7 +194,15 @@ const Send: React.FunctionComponent = ({ setNegativeMaxAmount(true); } setSpendableBalanceLastError(''); - }, [donation, donationAddress, totalBalance.spendableOrchard, totalBalance.spendablePrivate]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [ + donation, + donationAddress, + server.chainName, + totalBalance, + totalBalance?.spendableOrchard, + totalBalance?.spendablePrivate, + ]); const calculateFeeWithPropose = useCallback( async ( @@ -227,10 +238,9 @@ const Send: React.FunctionComponent = ({ sendJson = await Utils.getSendManyJSON( sendPageStateCalculateFee, uaAddress, - addresses, + addresses ? addresses : ([] as AddressClass[]), server, donation, - translate, ); console.log('SEND', sendJson); } @@ -280,8 +290,8 @@ const Send: React.FunctionComponent = ({ if (runProposeJson.amount) { const newAmount = runProposeJson.amount / 10 ** 8 - - (donation && !donationAddress - ? Utils.parseStringLocaleToNumberFloat(Utils.getDefaultDonationAmount()) + (donation && server.chainName === ChainNameEnum.mainChainName && !donationAddress + ? Utils.parseStringLocaleToNumberFloat(Utils.getZenniesDonationAmount()) : 0); console.log('AMOUNT', newAmount); updateToField(null, Utils.parseNumberFloatToStringLocale(newAmount, 8), null, null, null); @@ -309,7 +319,7 @@ const Send: React.FunctionComponent = ({ return; } // spendable - let spendableBalance = totalBalance.spendableOrchard + totalBalance.spendablePrivate; + let spendableBalance = totalBalance ? totalBalance.spendableOrchard + totalBalance.spendablePrivate : 0; let zenniesForZingo = donationAddress ? false : donation; const spendableBalanceJSON = { address, zennies_for_zingo: zenniesForZingo }; console.log('SPENDABLEBALANCE', spendableBalanceJSON); @@ -364,15 +374,15 @@ const Send: React.FunctionComponent = ({ } //setSendAllClick(false); }, + // eslint-disable-next-line react-hooks/exhaustive-deps [ defaultValuesSpendableMaxAmount, donation, donationAddress, - totalBalance.spendableOrchard, - totalBalance.spendablePrivate, + totalBalance, + totalBalance?.spendableOrchard, + totalBalance?.spendablePrivate, validAddress, - //sendAllClick, - //updateToField, ], ); @@ -465,8 +475,8 @@ const Send: React.FunctionComponent = ({ useEffect(() => { const stillConf = - totalBalance.orchardBal !== totalBalance.spendableOrchard || - totalBalance.privateBal !== totalBalance.spendablePrivate || + (totalBalance ? totalBalance.orchardBal : 0) !== (totalBalance ? totalBalance.spendableOrchard : 0) || + (totalBalance ? totalBalance.privateBal : 0) !== (totalBalance ? totalBalance.spendablePrivate : 0) || somePending; const showShield = (somePending ? 0 : shieldingAmount) > 0; //const showUpgrade = @@ -476,10 +486,11 @@ const Send: React.FunctionComponent = ({ }, [ shieldingAmount, somePending, - totalBalance.orchardBal, - totalBalance.privateBal, - totalBalance.spendableOrchard, - totalBalance.spendablePrivate, + totalBalance, + totalBalance?.orchardBal, + totalBalance?.privateBal, + totalBalance?.spendableOrchard, + totalBalance?.spendablePrivate, ]); useEffect(() => { @@ -663,9 +674,11 @@ const Send: React.FunctionComponent = ({ useEffect(() => { const keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', () => { slideAnim.value = withTiming(0 - titleViewHeight + 25, { duration: 100, easing: Easing.linear }); + setKeyboardVisible(true); }); const keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', () => { slideAnim.value = withTiming(0, { duration: 100, easing: Easing.linear }); + setKeyboardVisible(false); }); return () => { @@ -693,12 +706,22 @@ const Send: React.FunctionComponent = ({ }, [mode, setZecPrice]); useEffect(() => { - const items = addressBook.map((item: AddressBookFileClass) => ({ - label: item.label, - value: item.address, - })); - setItemsPicker(items); - }, [addressBook]); + (async () => { + const zennyTips = await Utils.getZenniesDonationAddress(server.chainName); + const items = addressBook + .filter((item: AddressBookFileClass) => item.address !== zennyTips) + .sort((a, b) => { + const aLabel = a.label; + const bLabel = b.label; + return aLabel.localeCompare(bLabel); + }) + .map((item: AddressBookFileClass) => ({ + label: item.label, + value: item.address, + })); + setItemsPicker(items); + })(); + }, [addressBook, server.chainName]); useEffect(() => { (async () => { @@ -714,7 +737,10 @@ const Send: React.FunctionComponent = ({ const address = sendPageState.toaddr.to; if (address) { (async () => { - const donationA = address === (await Utils.getDonationAddress(server.chainName)); + const donationA = + address === (await Utils.getDonationAddress(server.chainName)) || + address === (await Utils.getZenniesDonationAddress(server.chainName)) || + address === (await Utils.getNymDonationAddress(server.chainName)); setDonationAddress(donationA); })(); } else { @@ -802,6 +828,13 @@ const Send: React.FunctionComponent = ({ return len; }; + const scrollToEnd = () => { + if (scrollViewRef.current) { + //console.log('scrolling to end', keyboardVisible); + scrollViewRef.current.scrollTo({ y: contentHeight, animated: true }); + } + }; + //console.log('render Send - 4', sendPageState); console.log( 'Render, spendable', @@ -812,6 +845,8 @@ const Send: React.FunctionComponent = ({ fee, 'Amount', sendPageState.toaddr.amount, + keyboardVisible, + contentHeight, ); const returnPage = ( @@ -847,7 +882,7 @@ const Send: React.FunctionComponent = ({ calculatedFee={fee} donationAmount={ donation && server.chainName === ChainNameEnum.mainChainName && !donationAddress - ? Utils.parseStringLocaleToNumberFloat(Utils.getDefaultDonationAmount()) + ? Utils.parseStringLocaleToNumberFloat(Utils.getZenniesDonationAmount()) : 0 } closeModal={() => { @@ -894,8 +929,6 @@ const Send: React.FunctionComponent = ({ setComputingModalVisible={setComputingModalVisible} setBackgroundError={setBackgroundError} setPrivacyOption={setPrivacyOption} - //setPoolsToShieldSelectSapling={setPoolsToShieldSelectSapling} - //setPoolsToShieldSelectTransparent={setPoolsToShieldSelectTransparent} addLastSnackbar={addLastSnackbar} setShieldingAmount={setShieldingAmount} setScrollToTop={setScrollToTop} @@ -907,21 +940,27 @@ const Send: React.FunctionComponent = ({ {translate('warning-binance') as string} )} - - + setContentHeight(height)} + keyboardShouldPersistTaps="handled" + contentContainerStyle={{}} + testID="send.scroll-view"> + {[sendPageState.toaddr].map((ta, i) => { return ( - + {translate('send.toaddress') as string} @@ -998,7 +1037,11 @@ const Send: React.FunctionComponent = ({ {!updatingToField ? ( = ({ color: colors.primary, }} useNativeAndroidPickerStyle={false} - onValueChange={async (itemValue: string) => { - if (validAddress === 1 && ta.to && itemValue && ta.to !== itemValue) { + onDonePress={async () => { + // only for IOS + if ( + validAddress === 1 && + ta.to && + pickerTempSelectedAddress && + ta.to !== pickerTempSelectedAddress + ) { setUpdatingToField(true); await ShowAddressAlertAsync(translate) .then(() => { - updateToField(itemValue, null, null, null, null); + updateToField(pickerTempSelectedAddress, null, null, null, null); }) .catch(() => { updateToField(ta.to, null, null, null, null); @@ -1019,8 +1068,31 @@ const Send: React.FunctionComponent = ({ setTimeout(() => { setUpdatingToField(false); }, 500); - } else if (ta.to !== itemValue) { - updateToField(itemValue, null, null, null, null); + } else if (ta.to !== pickerTempSelectedAddress) { + updateToField(pickerTempSelectedAddress, null, null, null, null); + } + setPickerTempSelectedAddress(''); + }} + onValueChange={async (itemValue: string) => { + // only for Android + if (Platform.OS === GlobalConst.platformOSandroid) { + if (validAddress === 1 && ta.to && itemValue && ta.to !== itemValue) { + setUpdatingToField(true); + await ShowAddressAlertAsync(translate) + .then(() => { + updateToField(itemValue, null, null, null, null); + }) + .catch(() => { + updateToField(ta.to, null, null, null, null); + }); + setTimeout(() => { + setUpdatingToField(false); + }, 500); + } else if (ta.to !== itemValue) { + updateToField(itemValue, null, null, null, null); + } + } else { + setPickerTempSelectedAddress(itemValue); } }}> = ({ - - + + = ({ margin: 0, padding: 0, paddingBottom: 3, - minWidth: 48, - minHeight: 48, }}> {`${translate('send.amount')}`} @@ -1094,8 +1164,6 @@ const Send: React.FunctionComponent = ({ margin: 0, padding: 0, marginLeft: 10, - minWidth: 48, - minHeight: 48, }}> {translate('send.sendall') as string} @@ -1186,7 +1254,7 @@ const Send: React.FunctionComponent = ({ flexDirection: 'row', justifyContent: 'flex-start', alignItems: 'center', - marginTop: 5, + marginTop: 0, }}> = ({ /> - {donation && !donationAddress && ( + {donation && server.chainName === ChainNameEnum.mainChainName && !donationAddress && ( = ({ {(translate('send.confirm-donation') as string) + ': ' + - Utils.getDefaultDonationAmount() + + Utils.getZenniesDonationAmount() + ' '} {')'} @@ -1241,7 +1309,7 @@ const Send: React.FunctionComponent = ({ style={{ display: 'flex', flexDirection: 'row', - marginTop: 5, + marginTop: 0, backgroundColor: colors.card, padding: 5, borderRadius: 10, @@ -1278,7 +1346,7 @@ const Send: React.FunctionComponent = ({ style={{ display: 'flex', flexDirection: 'row', - marginTop: 5, + marginTop: 0, backgroundColor: colors.card, padding: 5, borderRadius: 10, @@ -1289,7 +1357,7 @@ const Send: React.FunctionComponent = ({ color={colors.primary} style={{ marginRight: 5 }} /> - {translate('send.somefunds') as string} + {translate('send.somefunds') as string} )} @@ -1299,7 +1367,7 @@ const Send: React.FunctionComponent = ({ style={{ display: 'flex', flexDirection: 'row', - marginTop: 5, + marginTop: 0, backgroundColor: colors.card, padding: 5, borderRadius: 10, @@ -1383,20 +1451,21 @@ const Send: React.FunctionComponent = ({ - - - + + + {translate('send.spendable') as string} - + + @@ -1412,9 +1481,7 @@ const Send: React.FunctionComponent = ({ justifyContent: 'space-between', alignItems: 'center', }}> - - {translate('send.memo') as string} - + {translate('send.memo') as string} {translate('send.includeua') as string} = ({ borderColor: colors.text, minWidth: 48, minHeight: 48, - maxHeight: 150, + maxHeight: 130, }}> = ({ !memoIcon ) { setMemoIcon(true); + scrollToEnd(); } if ( e.nativeEvent.contentSize.height <= @@ -1501,6 +1569,17 @@ const Send: React.FunctionComponent = ({ } }} maxLength={GlobalConst.memoMaxLength} + onFocus={() => { + // I need to wait for the keyboard is totally open + // otherwise the scroll to end never happened. + if (keyboardVisible) { + scrollToEnd(); + } else { + setTimeout(() => { + scrollToEnd(); + }, 1000); + } + }} /> {ta.memo && ( = ({ }}> {`${countMemoBytes(ta.memo, ta.includeUAMemo)} `} - {translate('loadedapp.of') as string} - {' ' + GlobalConst.memoMaxLength.toString() + ' '} + + {translate('loadedapp.of') as string} + + + {' ' + GlobalConst.memoMaxLength.toString() + ' '} + )} @@ -1556,7 +1640,7 @@ const Send: React.FunctionComponent = ({ flexDirection: 'column', justifyContent: 'center', alignItems: 'center', - marginVertical: 5, + marginVertical: 0, }}> = ({ onPress={() => { // donation - a Zenny is the minimum if ( + server.chainName === ChainNameEnum.mainChainName && donationAddress && Utils.parseStringLocaleToNumberFloat(sendPageState.toaddr.amount) < - Utils.parseStringLocaleToNumberFloat(Utils.getDefaultDonationAmount()) + Utils.parseStringLocaleToNumberFloat(Utils.getZenniesDonationAmount()) ) { addLastSnackbar({ message: `${translate('send.donation-minimum-message') as string}` }); - updateToField(null, Utils.getDefaultDonationAmount(), null, null, false); + updateToField(null, Utils.getZenniesDonationAmount(), null, null, false); return; } if (!netInfo.isConnected) { @@ -1623,6 +1708,7 @@ const Send: React.FunctionComponent = ({ defaultValueFee(); defaultValuesSpendableMaxAmount(); clearToAddr(); + setPickerTempSelectedAddress(''); }} /> @@ -1663,9 +1749,9 @@ const Send: React.FunctionComponent = ({ if (update) { updateToField( await Utils.getDonationAddress(server.chainName), - Utils.getDefaultDonationAmount(), + Utils.getDonationAmount(), null, - Utils.getDefaultDonationMemo(translate), + Utils.getDonationMemo(translate), true, ); } diff --git a/components/Send/components/Confirm.tsx b/components/Send/components/Confirm.tsx index 6149923ef..8eb40f102 100644 --- a/components/Send/components/Confirm.tsx +++ b/components/Send/components/Confirm.tsx @@ -94,19 +94,22 @@ const Confirm: React.FunctionComponent = ({ ); const totalSpendable: number = Utils.parseStringLocaleToNumberFloat( - Utils.parseNumberFloatToStringLocale(totalBalance.spendableOrchard + totalBalance.spendablePrivate, 8), + Utils.parseNumberFloatToStringLocale( + totalBalance ? totalBalance.spendableOrchard + totalBalance.spendablePrivate : 0, + 8, + ), ); console.log('total', totalAmount); - console.log('orchard', totalBalance.spendableOrchard); - console.log('sapling', totalBalance.spendablePrivate); + console.log('orchard', totalBalance?.spendableOrchard); + console.log('sapling', totalBalance?.spendablePrivate); // amount + fee - if (totalAmount <= totalBalance.spendableOrchard) { + if (totalAmount <= (totalBalance ? totalBalance.spendableOrchard : 0)) { from = PrivacyLevelFromEnum.orchardPrivacyLevel; - } else if (totalBalance.spendableOrchard > 0 && totalAmount <= totalSpendable) { + } else if ((totalBalance ? totalBalance.spendableOrchard : 0) > 0 && totalAmount <= totalSpendable) { from = PrivacyLevelFromEnum.orchardAndSaplingPrivacyLevel; - } else if (totalAmount <= totalBalance.spendablePrivate) { + } else if (totalAmount <= (totalBalance ? totalBalance.spendablePrivate : 0)) { from = PrivacyLevelFromEnum.saplingPrivacyLevel; } @@ -203,6 +206,7 @@ const Confirm: React.FunctionComponent = ({ // whatever else return '-'; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [ addLastSnackbar, calculatedFee, @@ -210,8 +214,9 @@ const Confirm: React.FunctionComponent = ({ sendPageState.toaddr.amount, sendPageState.toaddr.to, server.chainName, - totalBalance.spendableOrchard, - totalBalance.spendablePrivate, + totalBalance, + totalBalance?.spendableOrchard, + totalBalance?.spendablePrivate, translate, ]); diff --git a/ios/AppDelegate.swift b/ios/AppDelegate.swift index f4f3839df..11d37a395 100644 --- a/ios/AppDelegate.swift +++ b/ios/AppDelegate.swift @@ -20,9 +20,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { private var bridge: RCTBridge! private var bgTask: BGProcessingTask? = nil private var timeStampStrStart: String? = nil - private let errorPrefix = "error" - - + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { let jsCodeLocation: URL @@ -247,7 +245,7 @@ extension AppDelegate { func stopSyncingProcess() { NSLog("BGTask stopSyncingProcess") let statusStr = executeCommand(cmd: "syncstatus", args: "") - if statusStr.lowercased().hasPrefix(errorPrefix) { + if statusStr.lowercased().hasPrefix(Constants.ErrorPrefix.rawValue) { NSLog("BGTask stopSyncingProcess - no lightwalled likely") return } @@ -267,7 +265,7 @@ extension AppDelegate { Thread.sleep(forTimeInterval: 0.5) let newStatusStr = executeCommand(cmd: "syncstatus", args: "") - if newStatusStr.lowercased().hasPrefix(errorPrefix) { + if newStatusStr.lowercased().hasPrefix(Constants.ErrorPrefix.rawValue) { NSLog("BGTask stopSyncingProcess - error getting new status") return } @@ -301,14 +299,19 @@ extension AppDelegate { } NSLog("BGTask syncingProcessBackgroundTask") - let exists = rpcmodule.wallet_exists() - - if exists { + var exists: String = "false" + do { + exists = try rpcmodule.fileExists(Constants.WalletFileName.rawValue) + } catch { + NSLog("BGTask syncingProcessBackgroundTask - Wallet exists error: \(error.localizedDescription)") + } + + if exists == "true" { // chaeck the server let balance = executeCommand(cmd: "balance", args: "") let balanceStr = String(balance) NSLog("BGTask syncingProcessBackgroundTask - testing if server is active \(balanceStr)") - if balanceStr.lowercased().hasPrefix(errorPrefix) { + if balanceStr.lowercased().hasPrefix(Constants.ErrorPrefix.rawValue) { // this task is running with the App closed. self.loadWalletFile() } else { diff --git a/ios/Constants.swift b/ios/Constants.swift new file mode 100644 index 000000000..01aa03d70 --- /dev/null +++ b/ios/Constants.swift @@ -0,0 +1,17 @@ +// +// Constants.swift +// ZingoMobile +// +// Created by Juan Carlos Carmona Calvo on 7/17/24. +// + +import Foundation + +enum Constants: String { + // wallet files + case WalletFileName = "wallet.dat.txt" + case WalletBackupFileName = "wallet.backup.dat.txt" + + case BackgroundFileName = "background.json" + case ErrorPrefix = "error" +} diff --git a/ios/Podfile.lock b/ios/Podfile.lock index e3e984abb..e52461575 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -2,19 +2,19 @@ PODS: - BEMCheckBox (1.4.1) - boost (1.76.0) - DoubleConversion (1.1.6) - - FBLazyVector (0.72.14) - - FBReactNativeSpec (0.72.14): - - RCT-Folly (= 2021.07.22.00) - - RCTRequired (= 0.72.14) - - RCTTypeSafety (= 0.72.14) - - React-Core (= 0.72.14) - - React-jsi (= 0.72.14) - - ReactCommon/turbomodule/core (= 0.72.14) + - FBLazyVector (0.72.15) + - FBReactNativeSpec (0.72.15): + - RCT-Folly (= 2021.07.22.00) + - RCTRequired (= 0.72.15) + - RCTTypeSafety (= 0.72.15) + - React-Core (= 0.72.15) + - React-jsi (= 0.72.15) + - ReactCommon/turbomodule/core (= 0.72.15) - fmt (6.2.1) - glog (0.3.5) - - hermes-engine (0.72.14): - - hermes-engine/Pre-built (= 0.72.14) - - hermes-engine/Pre-built (0.72.14) + - hermes-engine (0.72.15): + - hermes-engine/Pre-built (= 0.72.15) + - hermes-engine/Pre-built (0.72.15) - libevent (2.1.12) - RCT-Folly (2021.07.22.00): - boost @@ -33,26 +33,26 @@ PODS: - fmt (~> 6.2.1) - glog - libevent - - RCTRequired (0.72.14) - - RCTTypeSafety (0.72.14): - - FBLazyVector (= 0.72.14) - - RCTRequired (= 0.72.14) - - React-Core (= 0.72.14) - - React (0.72.14): - - React-Core (= 0.72.14) - - React-Core/DevSupport (= 0.72.14) - - React-Core/RCTWebSocket (= 0.72.14) - - React-RCTActionSheet (= 0.72.14) - - React-RCTAnimation (= 0.72.14) - - React-RCTBlob (= 0.72.14) - - React-RCTImage (= 0.72.14) - - React-RCTLinking (= 0.72.14) - - React-RCTNetwork (= 0.72.14) - - React-RCTSettings (= 0.72.14) - - React-RCTText (= 0.72.14) - - React-RCTVibration (= 0.72.14) - - React-callinvoker (0.72.14) - - React-Codegen (0.72.14): + - RCTRequired (0.72.15) + - RCTTypeSafety (0.72.15): + - FBLazyVector (= 0.72.15) + - RCTRequired (= 0.72.15) + - React-Core (= 0.72.15) + - React (0.72.15): + - React-Core (= 0.72.15) + - React-Core/DevSupport (= 0.72.15) + - React-Core/RCTWebSocket (= 0.72.15) + - React-RCTActionSheet (= 0.72.15) + - React-RCTAnimation (= 0.72.15) + - React-RCTBlob (= 0.72.15) + - React-RCTImage (= 0.72.15) + - React-RCTLinking (= 0.72.15) + - React-RCTNetwork (= 0.72.15) + - React-RCTSettings (= 0.72.15) + - React-RCTText (= 0.72.15) + - React-RCTVibration (= 0.72.15) + - React-callinvoker (0.72.15) + - React-Codegen (0.72.15): - DoubleConversion - FBReactNativeSpec - glog @@ -67,11 +67,11 @@ PODS: - React-rncore - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - React-Core (0.72.14): + - React-Core (0.72.15): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - - React-Core/Default (= 0.72.14) + - React-Core/Default (= 0.72.15) - React-cxxreact - React-hermes - React-jsi @@ -81,7 +81,7 @@ PODS: - React-utils - SocketRocket (= 0.6.1) - Yoga - - React-Core/CoreModulesHeaders (0.72.14): + - React-Core/CoreModulesHeaders (0.72.15): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) @@ -95,7 +95,7 @@ PODS: - React-utils - SocketRocket (= 0.6.1) - Yoga - - React-Core/Default (0.72.14): + - React-Core/Default (0.72.15): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) @@ -108,23 +108,23 @@ PODS: - React-utils - SocketRocket (= 0.6.1) - Yoga - - React-Core/DevSupport (0.72.14): + - React-Core/DevSupport (0.72.15): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - - React-Core/Default (= 0.72.14) - - React-Core/RCTWebSocket (= 0.72.14) + - React-Core/Default (= 0.72.15) + - React-Core/RCTWebSocket (= 0.72.15) - React-cxxreact - React-hermes - React-jsi - React-jsiexecutor - - React-jsinspector (= 0.72.14) + - React-jsinspector (= 0.72.15) - React-perflogger - React-runtimeexecutor - React-utils - SocketRocket (= 0.6.1) - Yoga - - React-Core/RCTActionSheetHeaders (0.72.14): + - React-Core/RCTActionSheetHeaders (0.72.15): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) @@ -138,7 +138,7 @@ PODS: - React-utils - SocketRocket (= 0.6.1) - Yoga - - React-Core/RCTAnimationHeaders (0.72.14): + - React-Core/RCTAnimationHeaders (0.72.15): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) @@ -152,7 +152,7 @@ PODS: - React-utils - SocketRocket (= 0.6.1) - Yoga - - React-Core/RCTBlobHeaders (0.72.14): + - React-Core/RCTBlobHeaders (0.72.15): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) @@ -166,7 +166,7 @@ PODS: - React-utils - SocketRocket (= 0.6.1) - Yoga - - React-Core/RCTImageHeaders (0.72.14): + - React-Core/RCTImageHeaders (0.72.15): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) @@ -180,7 +180,7 @@ PODS: - React-utils - SocketRocket (= 0.6.1) - Yoga - - React-Core/RCTLinkingHeaders (0.72.14): + - React-Core/RCTLinkingHeaders (0.72.15): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) @@ -194,7 +194,7 @@ PODS: - React-utils - SocketRocket (= 0.6.1) - Yoga - - React-Core/RCTNetworkHeaders (0.72.14): + - React-Core/RCTNetworkHeaders (0.72.15): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) @@ -208,7 +208,7 @@ PODS: - React-utils - SocketRocket (= 0.6.1) - Yoga - - React-Core/RCTSettingsHeaders (0.72.14): + - React-Core/RCTSettingsHeaders (0.72.15): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) @@ -222,7 +222,7 @@ PODS: - React-utils - SocketRocket (= 0.6.1) - Yoga - - React-Core/RCTTextHeaders (0.72.14): + - React-Core/RCTTextHeaders (0.72.15): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) @@ -236,7 +236,7 @@ PODS: - React-utils - SocketRocket (= 0.6.1) - Yoga - - React-Core/RCTVibrationHeaders (0.72.14): + - React-Core/RCTVibrationHeaders (0.72.15): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) @@ -250,11 +250,11 @@ PODS: - React-utils - SocketRocket (= 0.6.1) - Yoga - - React-Core/RCTWebSocket (0.72.14): + - React-Core/RCTWebSocket (0.72.15): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - - React-Core/Default (= 0.72.14) + - React-Core/Default (= 0.72.15) - React-cxxreact - React-hermes - React-jsi @@ -264,57 +264,57 @@ PODS: - React-utils - SocketRocket (= 0.6.1) - Yoga - - React-CoreModules (0.72.14): + - React-CoreModules (0.72.15): - RCT-Folly (= 2021.07.22.00) - - RCTTypeSafety (= 0.72.14) - - React-Codegen (= 0.72.14) - - React-Core/CoreModulesHeaders (= 0.72.14) - - React-jsi (= 0.72.14) + - RCTTypeSafety (= 0.72.15) + - React-Codegen (= 0.72.15) + - React-Core/CoreModulesHeaders (= 0.72.15) + - React-jsi (= 0.72.15) - React-RCTBlob - - React-RCTImage (= 0.72.14) - - ReactCommon/turbomodule/core (= 0.72.14) + - React-RCTImage (= 0.72.15) + - ReactCommon/turbomodule/core (= 0.72.15) - SocketRocket (= 0.6.1) - - React-cxxreact (0.72.14): + - React-cxxreact (0.72.15): - boost (= 1.76.0) - DoubleConversion - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - - React-callinvoker (= 0.72.14) - - React-debug (= 0.72.14) - - React-jsi (= 0.72.14) - - React-jsinspector (= 0.72.14) - - React-logger (= 0.72.14) - - React-perflogger (= 0.72.14) - - React-runtimeexecutor (= 0.72.14) - - React-debug (0.72.14) - - React-hermes (0.72.14): + - React-callinvoker (= 0.72.15) + - React-debug (= 0.72.15) + - React-jsi (= 0.72.15) + - React-jsinspector (= 0.72.15) + - React-logger (= 0.72.15) + - React-perflogger (= 0.72.15) + - React-runtimeexecutor (= 0.72.15) + - React-debug (0.72.15) + - React-hermes (0.72.15): - DoubleConversion - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - RCT-Folly/Futures (= 2021.07.22.00) - - React-cxxreact (= 0.72.14) + - React-cxxreact (= 0.72.15) - React-jsi - - React-jsiexecutor (= 0.72.14) - - React-jsinspector (= 0.72.14) - - React-perflogger (= 0.72.14) - - React-jsi (0.72.14): + - React-jsiexecutor (= 0.72.15) + - React-jsinspector (= 0.72.15) + - React-perflogger (= 0.72.15) + - React-jsi (0.72.15): - boost (= 1.76.0) - DoubleConversion - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - - React-jsiexecutor (0.72.14): + - React-jsiexecutor (0.72.15): - DoubleConversion - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - - React-cxxreact (= 0.72.14) - - React-jsi (= 0.72.14) - - React-perflogger (= 0.72.14) - - React-jsinspector (0.72.14) - - React-logger (0.72.14): + - React-cxxreact (= 0.72.15) + - React-jsi (= 0.72.15) + - React-perflogger (= 0.72.15) + - React-jsinspector (0.72.15) + - React-logger (0.72.15): - glog - react-native-biometrics (3.0.1): - React-Core @@ -337,7 +337,7 @@ PODS: - React-Core - react-native-simple-biometrics (1.5.2): - React-Core - - React-NativeModulesApple (0.72.14): + - React-NativeModulesApple (0.72.15): - hermes-engine - React-callinvoker - React-Core @@ -346,17 +346,17 @@ PODS: - React-runtimeexecutor - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - React-perflogger (0.72.14) - - React-RCTActionSheet (0.72.14): - - React-Core/RCTActionSheetHeaders (= 0.72.14) - - React-RCTAnimation (0.72.14): - - RCT-Folly (= 2021.07.22.00) - - RCTTypeSafety (= 0.72.14) - - React-Codegen (= 0.72.14) - - React-Core/RCTAnimationHeaders (= 0.72.14) - - React-jsi (= 0.72.14) - - ReactCommon/turbomodule/core (= 0.72.14) - - React-RCTAppDelegate (0.72.14): + - React-perflogger (0.72.15) + - React-RCTActionSheet (0.72.15): + - React-Core/RCTActionSheetHeaders (= 0.72.15) + - React-RCTAnimation (0.72.15): + - RCT-Folly (= 2021.07.22.00) + - RCTTypeSafety (= 0.72.15) + - React-Codegen (= 0.72.15) + - React-Core/RCTAnimationHeaders (= 0.72.15) + - React-jsi (= 0.72.15) + - ReactCommon/turbomodule/core (= 0.72.15) + - React-RCTAppDelegate (0.72.15): - RCT-Folly - RCTRequired - RCTTypeSafety @@ -368,54 +368,54 @@ PODS: - React-RCTNetwork - React-runtimescheduler - ReactCommon/turbomodule/core - - React-RCTBlob (0.72.14): + - React-RCTBlob (0.72.15): - hermes-engine - RCT-Folly (= 2021.07.22.00) - - React-Codegen (= 0.72.14) - - React-Core/RCTBlobHeaders (= 0.72.14) - - React-Core/RCTWebSocket (= 0.72.14) - - React-jsi (= 0.72.14) - - React-RCTNetwork (= 0.72.14) - - ReactCommon/turbomodule/core (= 0.72.14) - - React-RCTImage (0.72.14): - - RCT-Folly (= 2021.07.22.00) - - RCTTypeSafety (= 0.72.14) - - React-Codegen (= 0.72.14) - - React-Core/RCTImageHeaders (= 0.72.14) - - React-jsi (= 0.72.14) - - React-RCTNetwork (= 0.72.14) - - ReactCommon/turbomodule/core (= 0.72.14) - - React-RCTLinking (0.72.14): - - React-Codegen (= 0.72.14) - - React-Core/RCTLinkingHeaders (= 0.72.14) - - React-jsi (= 0.72.14) - - ReactCommon/turbomodule/core (= 0.72.14) - - React-RCTNetwork (0.72.14): - - RCT-Folly (= 2021.07.22.00) - - RCTTypeSafety (= 0.72.14) - - React-Codegen (= 0.72.14) - - React-Core/RCTNetworkHeaders (= 0.72.14) - - React-jsi (= 0.72.14) - - ReactCommon/turbomodule/core (= 0.72.14) - - React-RCTSettings (0.72.14): - - RCT-Folly (= 2021.07.22.00) - - RCTTypeSafety (= 0.72.14) - - React-Codegen (= 0.72.14) - - React-Core/RCTSettingsHeaders (= 0.72.14) - - React-jsi (= 0.72.14) - - ReactCommon/turbomodule/core (= 0.72.14) - - React-RCTText (0.72.14): - - React-Core/RCTTextHeaders (= 0.72.14) - - React-RCTVibration (0.72.14): - - RCT-Folly (= 2021.07.22.00) - - React-Codegen (= 0.72.14) - - React-Core/RCTVibrationHeaders (= 0.72.14) - - React-jsi (= 0.72.14) - - ReactCommon/turbomodule/core (= 0.72.14) - - React-rncore (0.72.14) - - React-runtimeexecutor (0.72.14): - - React-jsi (= 0.72.14) - - React-runtimescheduler (0.72.14): + - React-Codegen (= 0.72.15) + - React-Core/RCTBlobHeaders (= 0.72.15) + - React-Core/RCTWebSocket (= 0.72.15) + - React-jsi (= 0.72.15) + - React-RCTNetwork (= 0.72.15) + - ReactCommon/turbomodule/core (= 0.72.15) + - React-RCTImage (0.72.15): + - RCT-Folly (= 2021.07.22.00) + - RCTTypeSafety (= 0.72.15) + - React-Codegen (= 0.72.15) + - React-Core/RCTImageHeaders (= 0.72.15) + - React-jsi (= 0.72.15) + - React-RCTNetwork (= 0.72.15) + - ReactCommon/turbomodule/core (= 0.72.15) + - React-RCTLinking (0.72.15): + - React-Codegen (= 0.72.15) + - React-Core/RCTLinkingHeaders (= 0.72.15) + - React-jsi (= 0.72.15) + - ReactCommon/turbomodule/core (= 0.72.15) + - React-RCTNetwork (0.72.15): + - RCT-Folly (= 2021.07.22.00) + - RCTTypeSafety (= 0.72.15) + - React-Codegen (= 0.72.15) + - React-Core/RCTNetworkHeaders (= 0.72.15) + - React-jsi (= 0.72.15) + - ReactCommon/turbomodule/core (= 0.72.15) + - React-RCTSettings (0.72.15): + - RCT-Folly (= 2021.07.22.00) + - RCTTypeSafety (= 0.72.15) + - React-Codegen (= 0.72.15) + - React-Core/RCTSettingsHeaders (= 0.72.15) + - React-jsi (= 0.72.15) + - ReactCommon/turbomodule/core (= 0.72.15) + - React-RCTText (0.72.15): + - React-Core/RCTTextHeaders (= 0.72.15) + - React-RCTVibration (0.72.15): + - RCT-Folly (= 2021.07.22.00) + - React-Codegen (= 0.72.15) + - React-Core/RCTVibrationHeaders (= 0.72.15) + - React-jsi (= 0.72.15) + - ReactCommon/turbomodule/core (= 0.72.15) + - React-rncore (0.72.15) + - React-runtimeexecutor (0.72.15): + - React-jsi (= 0.72.15) + - React-runtimescheduler (0.72.15): - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) @@ -423,30 +423,30 @@ PODS: - React-debug - React-jsi - React-runtimeexecutor - - React-utils (0.72.14): + - React-utils (0.72.15): - glog - RCT-Folly (= 2021.07.22.00) - React-debug - - ReactCommon/turbomodule/bridging (0.72.14): + - ReactCommon/turbomodule/bridging (0.72.15): - DoubleConversion - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - - React-callinvoker (= 0.72.14) - - React-cxxreact (= 0.72.14) - - React-jsi (= 0.72.14) - - React-logger (= 0.72.14) - - React-perflogger (= 0.72.14) - - ReactCommon/turbomodule/core (0.72.14): + - React-callinvoker (= 0.72.15) + - React-cxxreact (= 0.72.15) + - React-jsi (= 0.72.15) + - React-logger (= 0.72.15) + - React-perflogger (= 0.72.15) + - ReactCommon/turbomodule/core (0.72.15): - DoubleConversion - glog - hermes-engine - RCT-Folly (= 2021.07.22.00) - - React-callinvoker (= 0.72.14) - - React-cxxreact (= 0.72.14) - - React-jsi (= 0.72.14) - - React-logger (= 0.72.14) - - React-perflogger (= 0.72.14) + - React-callinvoker (= 0.72.15) + - React-cxxreact (= 0.72.15) + - React-jsi (= 0.72.15) + - React-logger (= 0.72.15) + - React-perflogger (= 0.72.15) - ReactNativeART (1.2.0): - React - RNCAsyncStorage (1.23.1): @@ -675,27 +675,27 @@ SPEC CHECKSUMS: BEMCheckBox: 5ba6e37ade3d3657b36caecc35c8b75c6c2b1a4e boost: 7dcd2de282d72e344012f7d6564d024930a6a440 DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 - FBLazyVector: d98eefb42c5a64cb28ef966bd9096c76770d8f24 - FBReactNativeSpec: 53d4eb00e8e1b6e987a3dd5906d2afe131cc54c8 + FBLazyVector: 25cbffbaec517695d376ab4bc428948cd0f08088 + FBReactNativeSpec: e03b22fbf7017a6f76641ea4472e73c915dcdda7 fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b - hermes-engine: b213bace5f31766ad1434d2d9b2cbf04cf92a2b6 + hermes-engine: 5b340c6a5affbf3aba22185be41563bbb2426654 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 - RCTRequired: 264adaca1d8b1a9c078761891898d4142df05313 - RCTTypeSafety: 279a89da7058a69899778a127be73fab38b84499 - React: 725b4e11f6ffb43d6f9b14e82879073623db4071 - React-callinvoker: c2ba5e7e1187d0f37705b9dcaaf9bbf24d3fe9dc - React-Codegen: 590303f222cffc109dc0d122854fa8281fa536b7 - React-Core: 89fe417d4957766ef20b4bec921a0721e914d988 - React-CoreModules: 57ea4ca8627be90b1a29916e0640d879e5684305 - React-cxxreact: 8bcd7336084fbaaad0304935896f2cb62659894d - React-debug: d360c17c84e514b9143e78217072183d4fcfb9c0 - React-hermes: d2e7945d1b480a2e732d64303564d9870edf22e9 - React-jsi: 53bff70353449aa006546c00024736de3ed66219 - React-jsiexecutor: e9a70be9304ef2e66eeebac35710f958b076dc14 - React-jsinspector: 275d9f80210f15f0af9a4b7fd5683fab9738e28e - React-logger: 8da4802de77a0eb62512396ad6bb1769904c2f0e + RCTRequired: fb207f74935626041e7308c9e88dcdda680f1073 + RCTTypeSafety: 146fd11361680250b7580dd1f7f601995cfad1b1 + React: f3712351445cc96ba507425675a0cd8d31321d0c + React-callinvoker: dcc51a66e02d20a70aeca2abbb1388d4d3011bf8 + React-Codegen: d64399cfcc319735a4f61c2f7df64fdfee9f7307 + React-Core: f8ceb3440b6cf30ce4eea884ed77990b7f9bec13 + React-CoreModules: 9d1e6f44bf658431a3b99561c8058b54b5959190 + React-cxxreact: 2150e05cdd30c815c1bf27f41062cd33832ffe31 + React-debug: 4e90d08c78aa207c064a3860e1540ff252695585 + React-hermes: 1ed296db543b7fdb01916a8e56255fcea0758264 + React-jsi: af5a8eaca28d67822fb14c648486d40737d2d2ab + React-jsiexecutor: d3eef5ddc78eeb9f0d02bed657a7f41d4910b966 + React-jsinspector: b86a8abae760c28d69366bbc1d991561e51341ed + React-logger: ed7c9e01e58529065e7da6bf8318baf15024283e react-native-biometrics: 352e5a794bfffc46a0c86725ea7dc62deb085bdc react-native-camera: 3eae183c1d111103963f3dd913b65d01aef8110f react-native-keep-awake: 5cfb49d1b2ee4321b2ffbc651e2d6d64d6f66772 @@ -703,23 +703,23 @@ SPEC CHECKSUMS: react-native-pager-view: f2a27430f15fc7780ce9308c66d2b942e415e036 react-native-safe-area-context: dcab599c527c2d7de2d76507a523d20a0b83823d react-native-simple-biometrics: 0f8ace5091780426188cef7f7593259effcd448e - React-NativeModulesApple: 3107f777453f953906d9ba9dc5f8cbd91a6ef913 - React-perflogger: daabc494c6328efc1784a4b49b8b74fca305d11c - React-RCTActionSheet: 0e0e64a7cf6c07f1de73d1f0a92d26a70262b256 - React-RCTAnimation: faef65b19e73029c4828167985b0a7c01c62756d - React-RCTAppDelegate: b24e761d235760656226364bb259e3f1508559c2 - React-RCTBlob: 9e9784a84b824b6d7e2cce05a8087c8c3a47a559 - React-RCTImage: 15e211cbb629210ab9c1fa37e07e7100362b12ed - React-RCTLinking: 50d5faf19b02541cefb78ee5d505029283c8ef95 - React-RCTNetwork: dfa9fb4ad2ae459b9193a14204b1d9da907d15a7 - React-RCTSettings: 37611fa97d44a9c5a7ea844cfb953d3513f7ace0 - React-RCTText: 39ed334f64484d07b85a8159cf117814ff069ff6 - React-RCTVibration: 62462803b5fe0842e0be6d9ef86dd74e0df4a614 - React-rncore: 25ad3a3c1e0f4edf77913b9af3af9f497b7f99a5 - React-runtimeexecutor: e5c2f0a1493d72c61b97465ccfedc339157b3179 - React-runtimescheduler: f284b4fdad43fe811041129099f1339b54783135 - React-utils: 22a77b05da25ce49c744faa82e73856dcae1734e - ReactCommon: ff94462e007c568d8cdebc32e3c97af86ec93bb5 + React-NativeModulesApple: ee36a33f5ad8d80487c43e6b4370ea2eaaa81750 + React-perflogger: 6acc671f527e69c0cd93b8e62821d33d3ddf25ca + React-RCTActionSheet: 569bb9db46d85565d14697e15ecf2166e035eb07 + React-RCTAnimation: 0eea98143c2938a8751a33722623d3e8a38fe1e4 + React-RCTAppDelegate: b4511be9c9c947ef53c9a26c996139cd903bfdc9 + React-RCTBlob: e6fd9d6b975faf765fdc29a959e8e79eb0bb65a0 + React-RCTImage: 0220975422a367e784dfd794adfc6454fab23c1f + React-RCTLinking: 1abf9834017e080ecbd5b6a28b4fb15eb843a3dd + React-RCTNetwork: 5ed275bf87d97a7ba5218cf245b1f103e96f82cd + React-RCTSettings: 1d070387f01b3b01543fb2a4ef867ad0004f6a78 + React-RCTText: 82562208357b11285ffa8d7b33a9d769612a8101 + React-RCTVibration: 372a12b697a170aaee792f8a9999c40e1f2692d0 + React-rncore: d1ccbd5adaf4a67703790838b7c62f140e72d32a + React-runtimeexecutor: d4f7ff5073fcf87e14dbf89541d434218630246e + React-runtimescheduler: ae08ede2e0267be2a4d8ba82a54d5908949d5a34 + React-utils: 8eb3c12fd4a4da6df3824f7d9a961d73a6ed6e5d + ReactCommon: d2de36ed3eebe700d7169b9e80f7d1a4b98e178d ReactNativeART: 78edc68dd4a1e675338cd0cd113319cf3a65f2ab RNCAsyncStorage: 826b603ae9c0f88b5ac4e956801f755109fa4d5c RNCCheckbox: a3ca9978cb0846b981d28da4e9914bd437403d77 @@ -734,7 +734,7 @@ SPEC CHECKSUMS: RNSnackbar: 3727b42bf6c4314a53c18185b5203e915a4ab020 RNSVG: af3907ac5d4fa26a862b75a16d8f15bc74f2ceda SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 - Yoga: c32e0be1a17f8f1f0e633a3122f7666441f52c82 + Yoga: 6f5ab94cd8b1ecd04b6e973d0bc583ede2a598cc PODFILE CHECKSUM: c9cecc573a259bf0e0ca3708539e7fbcae548299 diff --git a/ios/RPCModule.swift b/ios/RPCModule.swift index 38023d08a..396b2ce27 100644 --- a/ios/RPCModule.swift +++ b/ios/RPCModule.swift @@ -11,11 +11,6 @@ import React @objc(RPCModule) class RPCModule: NSObject { - private let walletFileName = "wallet.dat.txt" - private let walletBackupFileName = "wallet.backup.dat.txt" - private let backgroundFileName = "background.json" - private let errorPrefix = "error" - @objc static func requiresMainQueueSetup() -> Bool { return true @@ -23,9 +18,7 @@ class RPCModule: NSObject { enum FileError: Error { case documentsDirectoryNotFoundError(String) - case readWalletUtf8StringError(String) - case readWalletDecodedDataError(String) - case saveFileDecodingError(String) + case readWalletError(String) case saveFileError(String) case writeFileError(String) case deleteFileError(String) @@ -46,48 +39,33 @@ class RPCModule: NSObject { return fileName } - func fileExists(_ fileName: String) -> String { - let fileExists = FileManager.default.fileExists(atPath: fileName) + func fileExists(_ fileName: String) throws -> String { + let fileExists = try FileManager.default.fileExists(atPath: getFileName(fileName)) if fileExists { + NSLog("File exists \(fileName)") return "true" } else { + NSLog("File DOES not exists \(fileName)") return "false" } } - func wallet_exists() -> Bool { - do { - let fileName = try getFileName(walletFileName) - if (fileExists(fileName) == "true") { - return true - } else { - return false - } - } catch { - NSLog("wallet exists error: \(error.localizedDescription)") - return false - } + func readFile(_ fileName: String) throws -> String { + return try String(contentsOfFile: getFileName(fileName), encoding: .utf8) } - func walletBackup_exists() -> Bool { - do { - let fileName = try getFileName(walletBackupFileName) - if (fileExists(fileName) == "true") { - return true - } else { - return false - } - } catch { - NSLog("wallet backup exists error: \(error.localizedDescription)") - return false - } + func writeFile(_ fileName: String, fileBase64EncodedString: String) throws { + try fileBase64EncodedString.write(toFile: getFileName(fileName), atomically: true, encoding: .utf8) } + func deleteFile(_ fileName: String) throws { + try FileManager.default.removeItem(atPath: getFileName(fileName)) + } + @objc(walletExists:reject:) func walletExists(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { do { - let fileName = try getFileName(walletFileName) - resolve(fileExists(fileName)) + resolve(try fileExists(Constants.WalletFileName.rawValue)) } catch { NSLog("wallet exists error: \(error.localizedDescription)") resolve("false") @@ -97,8 +75,7 @@ class RPCModule: NSObject { @objc(walletBackupExists:reject:) func walletBackupExists(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { do { - let fileName = try getFileName(walletBackupFileName) - resolve(fileExists(fileName)) + resolve(try fileExists(Constants.WalletBackupFileName.rawValue)) } catch { NSLog("wallet backup exists error: \(error.localizedDescription)") resolve("false") @@ -106,57 +83,49 @@ class RPCModule: NSObject { } func saveWalletFile(_ base64EncodedString: String) throws { - let fileName = try getFileName(walletFileName) - NSLog("save wallet file name \(fileName)") do { - try base64EncodedString.write(toFile: fileName, atomically: true, encoding: .utf8) + try writeFile(Constants.WalletFileName.rawValue, fileBase64EncodedString: base64EncodedString) } catch { throw FileError.writeFileError("Error writting wallet file error: \(error.localizedDescription)") } } func saveWalletBackupFile(_ base64EncodedString: String) throws { - let fileName = try getFileName(walletBackupFileName) do { - try base64EncodedString.write(toFile: fileName, atomically: true, encoding: .utf8) + try writeFile(Constants.WalletBackupFileName.rawValue, fileBase64EncodedString: base64EncodedString) } catch { throw FileError.writeFileError("Error writting wallet backup file error: \(error.localizedDescription)") } } - func saveBackgroundFile(_ data: String) throws { - let fileName = try getFileName(backgroundFileName) + func saveBackgroundFile(_ jsonString: String) throws { do { - try data.write(toFile: fileName, atomically: true, encoding: .utf8) + // the content of this JSON can be represented safely in utf8. + try jsonString.write(toFile: getFileName(Constants.BackgroundFileName.rawValue), atomically: true, encoding: .utf8) } catch { throw FileError.writeFileError("Error writting background file error: \(error.localizedDescription)") } } func readWalletUtf8String() throws -> String { - let fileName = try getFileName(walletFileName) do { - let content = try String(contentsOfFile: fileName, encoding: .utf8) - return content + return try readFile(Constants.WalletFileName.rawValue) } catch { - throw FileError.readWalletUtf8StringError("Error reading wallet format error: \(error.localizedDescription)") + throw FileError.readWalletError("Error reading wallet format error: \(error.localizedDescription)") } } func readWalletBackup() throws -> String { - let fileName = try getFileName(walletBackupFileName) do { - let content = try String(contentsOfFile: fileName, encoding: .utf8) - return content + return try readFile(Constants.WalletBackupFileName.rawValue) } catch { - throw FileError.readWalletDecodedDataError("Error reading wallet backup format error: \(error.localizedDescription)") + throw FileError.readWalletError("Error reading wallet backup format error: \(error.localizedDescription)") } } func deleteExistingWallet() throws { - let fileName = try getFileName(walletFileName) do { - try FileManager.default.removeItem(atPath: fileName) + try deleteFile(Constants.WalletFileName.rawValue) } catch { throw FileError.deleteFileError("Error deleting wallet error: \(error.localizedDescription)") } @@ -165,7 +134,7 @@ class RPCModule: NSObject { @objc(deleteExistingWallet:reject:) func deleteExistingWallet(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { do { - if wallet_exists() { + if try fileExists(Constants.WalletFileName.rawValue) == "true" { try self.deleteExistingWallet() resolve("true") } else { @@ -178,9 +147,8 @@ class RPCModule: NSObject { } func deleteExistingWalletBackup() throws { - let fileName = try getFileName(walletBackupFileName) do { - try FileManager.default.removeItem(atPath: fileName) + try deleteFile(Constants.WalletBackupFileName.rawValue) } catch { throw FileError.deleteFileError("Error deleting wallet backup error: \(error.localizedDescription)") } @@ -189,7 +157,7 @@ class RPCModule: NSObject { @objc(deleteExistingWalletBackup:reject:) func deleteExistingWalletBackup(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { do { - if walletBackup_exists() { + if try fileExists(Constants.WalletBackupFileName.rawValue) == "true" { try self.deleteExistingWalletBackup() resolve("true") } else { @@ -203,7 +171,7 @@ class RPCModule: NSObject { func saveWalletInternal() throws { let walletEncodedString = saveToB64() - if !walletEncodedString.lowercased().hasPrefix(errorPrefix) { + if !walletEncodedString.lowercased().hasPrefix(Constants.ErrorPrefix.rawValue) { try self.saveWalletFile(walletEncodedString) } else { throw FileError.saveFileError("Error saving wallet error: \(walletEncodedString)") @@ -211,15 +179,14 @@ class RPCModule: NSObject { } func saveWalletBackupInternal() throws { - let walletData = try readWalletUtf8String() - try self.saveWalletBackupFile(walletData) + let walletString = try readWalletUtf8String() + try self.saveWalletBackupFile(walletString) } func createNewWallet(server: String, chainhint: String) throws -> String { - let documentsDirectory = try getDocumentsDirectory() - let seed = initNew(serveruri: server, datadir: documentsDirectory, chainhint: chainhint, monitorMempool: true) + let seed = initNew(serveruri: server, datadir: try getDocumentsDirectory(), chainhint: chainhint, monitorMempool: true) let seedStr = String(seed) - if !seedStr.lowercased().hasPrefix(errorPrefix) { + if !seedStr.lowercased().hasPrefix(Constants.ErrorPrefix.rawValue) { try self.saveWalletInternal() } return seedStr @@ -238,10 +205,9 @@ class RPCModule: NSObject { } func restoreWalletFromSeed(server: String, chainhint: String, restoreSeed: String, birthday: String) throws -> String { - let documentsDirectory = try getDocumentsDirectory() - let seed = initFromSeed(serveruri: server, seed: restoreSeed, birthday: UInt64(birthday) ?? 0, datadir: documentsDirectory, chainhint: chainhint, monitorMempool: true) + let seed = initFromSeed(serveruri: server, seed: restoreSeed, birthday: UInt64(birthday) ?? 0, datadir: try getDocumentsDirectory(), chainhint: chainhint, monitorMempool: true) let seedStr = String(seed) - if !seedStr.lowercased().hasPrefix(errorPrefix) { + if !seedStr.lowercased().hasPrefix(Constants.ErrorPrefix.rawValue) { try self.saveWalletInternal() } return seedStr @@ -260,10 +226,9 @@ class RPCModule: NSObject { } func restoreWalletFromUfvk(server: String, chainhint: String, restoreUfvk: String, birthday: String) throws -> String { - let documentsDirectory = try getDocumentsDirectory() - let ufvk = initFromUfvk(serveruri: server, ufvk: restoreUfvk, birthday: UInt64(birthday) ?? 0, datadir: documentsDirectory, chainhint: chainhint, monitorMempool: true) + let ufvk = initFromUfvk(serveruri: server, ufvk: restoreUfvk, birthday: UInt64(birthday) ?? 0, datadir: try getDocumentsDirectory(), chainhint: chainhint, monitorMempool: true) let ufvkStr = String(ufvk) - if !ufvkStr.lowercased().hasPrefix(errorPrefix) { + if !ufvkStr.lowercased().hasPrefix(Constants.ErrorPrefix.rawValue) { try self.saveWalletInternal() } return ufvkStr @@ -282,9 +247,7 @@ class RPCModule: NSObject { } func loadExistingWallet(server: String, chainhint: String) throws -> String { - let documentsDirectory = try getDocumentsDirectory() - let walletEncodedUtf8String = try self.readWalletUtf8String() - let seed = initFromB64(serveruri: server, datab64: walletEncodedUtf8String, datadir: documentsDirectory, chainhint: chainhint, monitorMempool: true) + let seed = initFromB64(serveruri: server, datab64: try self.readWalletUtf8String(), datadir: try getDocumentsDirectory(), chainhint: chainhint, monitorMempool: true) let seedStr = String(seed) return seedStr } @@ -343,20 +306,22 @@ class RPCModule: NSObject { let resolve = dict["resolve"] as? RCTPromiseResolveBlock { let resp = executeCommand(cmd: method, args: args) let respStr = String(resp) - if method == "sync" && !respStr.lowercased().hasPrefix(errorPrefix) { + if method == "sync" && !respStr.lowercased().hasPrefix(Constants.ErrorPrefix.rawValue) { // Also save the wallet after sync do { try self.saveWalletInternal() } catch { - NSLog("Executing a command error: \(error.localizedDescription)") - resolve("Error: [Native] Executing command. \(error.localizedDescription)") + let err = "Error: [Native] Executing command. Saving wallet. \(error.localizedDescription)" + NSLog(err) + resolve(err) } } resolve(respStr) } else { - NSLog("Error executing a command. Command argument problem.") + let err = "Error: [Native] Executing command. Command argument problem." + NSLog(err) if let resolve = dict["resolve"] as? RCTPromiseResolveBlock { - resolve("Error: [Native] Executing command. Command argument problem.") + resolve(err) } } } @@ -378,9 +343,10 @@ class RPCModule: NSObject { let respStr = String(resp) resolve(respStr) } else { - NSLog("Error getting latest block server. Argument problem") + let err = "Error: [Native] Getting server latest block. Argument problem." + NSLog(err) if let resolve = dict["resolve"] as? RCTPromiseResolveBlock { - resolve("Error: [Native] Getting server latest block. Argument problem.") + resolve(err) } } } @@ -391,24 +357,45 @@ class RPCModule: NSObject { self.getLatestBlockAsync(dict) } + func getDonationAddressAsync(_ dict: [AnyHashable: Any]) { + if let resolve = dict["resolve"] as? RCTPromiseResolveBlock { + let resp = getDeveloperDonationAddress() + let respStr = String(resp) + resolve(respStr) + } else { + let err = "Error: [Native] Getting developer donation address. Command arguments problem." + NSLog(err) + if let resolve = dict["resolve"] as? RCTPromiseResolveBlock { + resolve(err) + } + } + } + @objc(getDonationAddress:reject:) func getDonationAddress(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { let dict: [String: Any] = ["resolve": resolve] self.getDonationAddressAsync(dict) } - func getDonationAddressAsync(_ dict: [AnyHashable: Any]) { + func getZenniesDonationAddressAsync(_ dict: [AnyHashable: Any]) { if let resolve = dict["resolve"] as? RCTPromiseResolveBlock { - let resp = getDeveloperDonationAddress() + let resp = getZenniesForZingoDonationAddress() let respStr = String(resp) resolve(respStr) } else { - NSLog("Error getting developer donation address") - if let resolve = dict["resolve"] as? RCTPromiseResolveBlock { - resolve("Error: [Native] Getting developer donation address. Command arguments problem.") + let err = "Error: [Native] Getting zennies donation address. Command arguments problem." + NSLog(err) + if let resolve = dict["resolve"] as? RCTPromiseResolveBlock { + resolve(err) } } } + + @objc(getZenniesDonationAddress:reject:) + func getZenniesDonationAddress(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + let dict: [String: Any] = ["resolve": resolve] + self.getZenniesDonationAddressAsync(dict) + } @objc(getValueTransfersList:reject:) func getValueTransfersList(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { @@ -422,9 +409,10 @@ class RPCModule: NSObject { let respStr = String(resp) resolve(respStr) } else { - NSLog("Error getting value transfers list") + let err = "Error: [Native] Getting value transfers. Command arguments problem." + NSLog(err) if let resolve = dict["resolve"] as? RCTPromiseResolveBlock { - resolve("Error: [Native] Getting value transfers list. Command arguments problem.") + resolve(err) } } } @@ -441,9 +429,10 @@ class RPCModule: NSObject { let respStr = String(resp) resolve(respStr) } else { - NSLog("Error getting transaction summaries list") + let err = "Error: [Native] Getting transaction summaries list. Command arguments problem." + NSLog(err) if let resolve = dict["resolve"] as? RCTPromiseResolveBlock { - resolve("Error: [Native] Getting transaction summaries list. Command arguments problem.") + resolve(err) } } } diff --git a/ios/RPCModuleBridge.m b/ios/RPCModuleBridge.m index 40f7a8492..837091677 100644 --- a/ios/RPCModuleBridge.m +++ b/ios/RPCModuleBridge.m @@ -66,6 +66,9 @@ @interface RCT_EXTERN_MODULE(RPCModule, NSObject) RCT_EXTERN_METHOD(getDonationAddress: (RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) +RCT_EXTERN_METHOD(getZenniesDonationAddress: + (RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject) RCT_EXTERN_METHOD(getValueTransfersList: (RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) diff --git a/ios/ZingoMobile.xcodeproj/project.pbxproj b/ios/ZingoMobile.xcodeproj/project.pbxproj index 1a029b5e2..28c76fe5e 100644 --- a/ios/ZingoMobile.xcodeproj/project.pbxproj +++ b/ios/ZingoMobile.xcodeproj/project.pbxproj @@ -8,6 +8,8 @@ /* Begin PBXBuildFile section */ 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; + 1F0338192C48782D00A3FC49 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F0338182C48782D00A3FC49 /* Constants.swift */; }; + 1F03381A2C49575900A3FC49 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F0338182C48782D00A3FC49 /* Constants.swift */; }; 1F0893FF2BA4C4380089FD88 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 1F0893FE2BA4C4380089FD88 /* PrivacyInfo.xcprivacy */; }; 1F0894002BA4C4380089FD88 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 1F0893FE2BA4C4380089FD88 /* PrivacyInfo.xcprivacy */; }; 1F5569272BBCB4D900F2CD6C /* RPCModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F5569262BBCB4D900F2CD6C /* RPCModule.swift */; }; @@ -44,6 +46,7 @@ 13B07F961A680F5B00A75B9A /* Zingo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Zingo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = ZingoMobile/Images.xcassets; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = ZingoMobile/Info.plist; sourceTree = ""; }; + 1F0338182C48782D00A3FC49 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; 1F0893FE2BA4C4380089FD88 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; 1F5569252BBCB4D900F2CD6C /* RPCModule-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RPCModule-Bridging-Header.h"; sourceTree = ""; }; 1F5569262BBCB4D900F2CD6C /* RPCModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RPCModule.swift; sourceTree = ""; }; @@ -121,6 +124,7 @@ 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */, 1F5569252BBCB4D900F2CD6C /* RPCModule-Bridging-Header.h */, 1F5CEBBA2BBF025700E2551A /* AppDelegate.swift */, + 1F0338182C48782D00A3FC49 /* Constants.swift */, ); name = ZingoMobile; sourceTree = ""; @@ -440,6 +444,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 1F03381A2C49575900A3FC49 /* Constants.swift in Sources */, 1FA935B12BE454FA00117DF5 /* RPCModuleBridge.m in Sources */, 1F5E677C2BD30D0A007B17AA /* zingo.swift in Sources */, 1FA935B02BE4506300117DF5 /* RPCModule.swift in Sources */, @@ -451,6 +456,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 1F0338192C48782D00A3FC49 /* Constants.swift in Sources */, 1F5CEBBB2BBF025700E2551A /* AppDelegate.swift in Sources */, 1F5E677B2BD30D0A007B17AA /* zingo.swift in Sources */, 1F5569272BBCB4D900F2CD6C /* RPCModule.swift in Sources */, @@ -546,7 +552,7 @@ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = ZingoMobile/ZingoMobile.entitlements; - CURRENT_PROJECT_VERSION = 186; + CURRENT_PROJECT_VERSION = 187; DEVELOPMENT_TEAM = 788KRST4S8; ENABLE_BITCODE = NO; EXCLUDED_ARCHS = ""; @@ -563,7 +569,7 @@ "$(PROJECT_DIR)", "$(inherited)", ); - MARKETING_VERSION = 1.4.2; + MARKETING_VERSION = 1.4.3; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", @@ -587,7 +593,7 @@ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = ZingoMobile/ZingoMobile.entitlements; - CURRENT_PROJECT_VERSION = 186; + CURRENT_PROJECT_VERSION = 187; DEVELOPMENT_TEAM = 788KRST4S8; ENABLE_BITCODE = NO; EXCLUDED_ARCHS = ""; @@ -604,7 +610,7 @@ "$(PROJECT_DIR)", "$(inherited)", ); - MARKETING_VERSION = 1.4.2; + MARKETING_VERSION = 1.4.3; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", diff --git a/ios/ZingoMobile/PrivacyInfo.xcprivacy b/ios/ZingoMobile/PrivacyInfo.xcprivacy new file mode 100644 index 000000000..41b8317f0 --- /dev/null +++ b/ios/ZingoMobile/PrivacyInfo.xcprivacy @@ -0,0 +1,37 @@ + + + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryUserDefaults + NSPrivacyAccessedAPITypeReasons + + CA92.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategorySystemBootTime + NSPrivacyAccessedAPITypeReasons + + 35F9.1 + + + + NSPrivacyCollectedDataTypes + + NSPrivacyTracking + + + diff --git a/ios/ZingoMobileTests/ZingoMobileTest.swift b/ios/ZingoMobileTests/ZingoMobileTest.swift index 92c4b0ada..17d5a679e 100644 --- a/ios/ZingoMobileTests/ZingoMobileTest.swift +++ b/ios/ZingoMobileTests/ZingoMobileTest.swift @@ -67,7 +67,7 @@ class ZingoMobileTests: XCTestCase { NSLog("Test create New Wallet KO \(newWalletKO)") XCTAssertTrue(newWalletKO.lowercased().hasPrefix(errorPrefix), "Create New Wallet NOT fails, and it have to \(newWalletKO)") - if (rpcmodule.wallet_exists()) { + if (try rpcmodule.fileExists(Constants.WalletFileName.rawValue) == "true") { // load wallet from file, expecting ERROR. let loadWalletKO = try rpcmodule.loadExistingWallet(server: serverKO, chainhint: chainhint) NSLog("Test create Load Wallet KO \(loadWalletKO)") diff --git a/package.json b/package.json index 094b48428..f30cf7fe9 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "randomcolor": "^0.6.2", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-native": "0.72.14", + "react-native": "0.72.15", "react-native-biometrics": "^3.0.1", "react-native-camera": "^4.2.1", "react-native-fs": "^2.20.0", diff --git a/rust/Cargo.lock b/rust/Cargo.lock index b2e805066..cbc97db12 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -537,7 +537,7 @@ dependencies = [ [[package]] name = "build_utils" version = "0.1.0" -source = "git+https://github.com/zingolabs/zingolib?tag=mob-release-1.4.2#6e1a16fe31e466ce525de39f7c10603822d58bed" +source = "git+https://github.com/zingolabs/zingolib?tag=mob-release-1.4.3#9fa9940760431c137c2e46e115dd2a296808ca7f" [[package]] name = "bumpalo" @@ -800,7 +800,7 @@ dependencies = [ [[package]] name = "darkside-tests" version = "0.1.0" -source = "git+https://github.com/zingolabs/zingolib?tag=mob-release-1.4.2#6e1a16fe31e466ce525de39f7c10603822d58bed" +source = "git+https://github.com/zingolabs/zingolib?tag=mob-release-1.4.3#9fa9940760431c137c2e46e115dd2a296808ca7f" dependencies = [ "futures-util", "hex", @@ -2352,7 +2352,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" dependencies = [ "bytes 1.6.1", - "heck 0.5.0", + "heck 0.4.1", "itertools", "log", "multimap", @@ -3347,18 +3347,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.62" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.62" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", @@ -3367,9 +3367,9 @@ dependencies = [ [[package]] name = "thread-id" -version = "4.2.1" +version = "4.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0ec81c46e9eb50deaa257be2f148adf052d1fb7701cfd55ccfab2525280b70b" +checksum = "cfe8f25bbdd100db7e1d34acf7fd2dc59c4bf8f7483f505eaa7d4f12f76cc0ea" dependencies = [ "libc", "winapi", @@ -3433,9 +3433,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.38.0" +version = "1.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +checksum = "eb2caba9f80616f438e09748d5acda951967e1ea58508ef53d9c6402485a46df" dependencies = [ "backtrace", "bytes 1.6.1", @@ -4545,7 +4545,7 @@ dependencies = [ [[package]] name = "zingo-memo" version = "0.1.0" -source = "git+https://github.com/zingolabs/zingolib?tag=mob-release-1.4.2#6e1a16fe31e466ce525de39f7c10603822d58bed" +source = "git+https://github.com/zingolabs/zingolib?tag=mob-release-1.4.3#9fa9940760431c137c2e46e115dd2a296808ca7f" dependencies = [ "zcash_address", "zcash_client_backend", @@ -4557,7 +4557,7 @@ dependencies = [ [[package]] name = "zingo-netutils" version = "0.1.0" -source = "git+https://github.com/zingolabs/zingolib?tag=mob-release-1.4.2#6e1a16fe31e466ce525de39f7c10603822d58bed" +source = "git+https://github.com/zingolabs/zingolib?tag=mob-release-1.4.3#9fa9940760431c137c2e46e115dd2a296808ca7f" dependencies = [ "http 0.2.12", "http-body 0.4.6", @@ -4576,7 +4576,7 @@ dependencies = [ [[package]] name = "zingo-status" version = "0.1.0" -source = "git+https://github.com/zingolabs/zingolib?tag=mob-release-1.4.2#6e1a16fe31e466ce525de39f7c10603822d58bed" +source = "git+https://github.com/zingolabs/zingolib?tag=mob-release-1.4.3#9fa9940760431c137c2e46e115dd2a296808ca7f" dependencies = [ "zcash_primitives", ] @@ -4584,7 +4584,7 @@ dependencies = [ [[package]] name = "zingo-testutils" version = "0.1.0" -source = "git+https://github.com/zingolabs/zingolib?tag=mob-release-1.4.2#6e1a16fe31e466ce525de39f7c10603822d58bed" +source = "git+https://github.com/zingolabs/zingolib?tag=mob-release-1.4.3#9fa9940760431c137c2e46e115dd2a296808ca7f" dependencies = [ "http 0.2.12", "incrementalmerkletree", @@ -4609,7 +4609,7 @@ dependencies = [ [[package]] name = "zingo-testvectors" version = "0.1.0" -source = "git+https://github.com/zingolabs/zingolib?tag=mob-release-1.4.2#6e1a16fe31e466ce525de39f7c10603822d58bed" +source = "git+https://github.com/zingolabs/zingolib?tag=mob-release-1.4.3#9fa9940760431c137c2e46e115dd2a296808ca7f" dependencies = [ "zcash_primitives", "zingoconfig", @@ -4618,7 +4618,7 @@ dependencies = [ [[package]] name = "zingoconfig" version = "0.1.0" -source = "git+https://github.com/zingolabs/zingolib?tag=mob-release-1.4.2#6e1a16fe31e466ce525de39f7c10603822d58bed" +source = "git+https://github.com/zingolabs/zingolib?tag=mob-release-1.4.3#9fa9940760431c137c2e46e115dd2a296808ca7f" dependencies = [ "dirs", "http 0.2.12", @@ -4631,7 +4631,7 @@ dependencies = [ [[package]] name = "zingolib" version = "0.2.0" -source = "git+https://github.com/zingolabs/zingolib?tag=mob-release-1.4.2#6e1a16fe31e466ce525de39f7c10603822d58bed" +source = "git+https://github.com/zingolabs/zingolib?tag=mob-release-1.4.3#9fa9940760431c137c2e46e115dd2a296808ca7f" dependencies = [ "append-only-vec", "base58", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index d500b6ff7..878d1bc2f 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -7,8 +7,8 @@ members = [ resolver = "2" [workspace.dependencies] -zingolib = { git="https://github.com/zingolabs/zingolib", default-features=true, tag = "mob-release-1.4.2" } -zingoconfig = { git="https://github.com/zingolabs/zingolib", default-features=true, tag = "mob-release-1.4.2" } +zingolib = { git="https://github.com/zingolabs/zingolib", default-features=true, tag = "mob-release-1.4.3" } +zingoconfig = { git="https://github.com/zingolabs/zingolib", default-features=true, tag = "mob-release-1.4.3" } uniffi = "0.27" tokio = { version = "1.24", features = [ "full" ] } diff --git a/rust/android/Cargo.toml b/rust/android/Cargo.toml index 840816079..4adaa2fda 100644 --- a/rust/android/Cargo.toml +++ b/rust/android/Cargo.toml @@ -12,8 +12,8 @@ regchest = [] zingoconfig = { workspace = true } zingomobile_utils = { path = "../zingomobile_utils" } regchest_utils = { git="https://github.com/zingolabs/zingo-regchest", default-features=true, branch = "dev" } -zingo-testutils = { git="https://github.com/zingolabs/zingolib", default-features=true, tag = "mob-release-1.4.2" } -darkside-tests = { git="https://github.com/zingolabs/zingolib", default-features=true, tag = "mob-release-1.4.2" } +zingo-testutils = { git="https://github.com/zingolabs/zingolib", default-features=true, tag = "mob-release-1.4.3" } +darkside-tests = { git="https://github.com/zingolabs/zingolib", default-features=true, tag = "mob-release-1.4.3" } json = "0.12.4" env_logger = "0.10.0" tokio = { workspace = true } diff --git a/rust/lib/src/lib.rs b/rust/lib/src/lib.rs index 9baf68b99..ab1ec1337 100644 --- a/rust/lib/src/lib.rs +++ b/rust/lib/src/lib.rs @@ -247,6 +247,10 @@ pub fn get_developer_donation_address() -> String { zingoconfig::DEVELOPER_DONATION_ADDRESS.to_string() } +pub fn get_zennies_for_zingo_donation_address() -> String { + zingoconfig::ZENNIES_FOR_ZINGO_DONATION_ADDRESS.to_string() +} + pub fn get_transaction_summaries() -> String { let resp: String; { diff --git a/rust/lib/src/zingo.udl b/rust/lib/src/zingo.udl index 01027dc42..431da032f 100644 --- a/rust/lib/src/zingo.udl +++ b/rust/lib/src/zingo.udl @@ -37,6 +37,7 @@ namespace zingo { string save_to_b64(); string get_latest_block_server(string serveruri); string get_developer_donation_address(); + string get_zennies_for_zingo_donation_address(); string get_transaction_summaries(); string get_value_transfers(); }; \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 9680e93f4..36f8ba63e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7556,10 +7556,10 @@ react-native@*: ws "^6.2.2" yargs "^17.6.2" -react-native@0.72.14: - version "0.72.14" - resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.72.14.tgz#d69c7bec66716946ea96613813618ba10403f942" - integrity sha512-7L0ync/mSyyUPL09lXYFiseibKwhXs4dWVm8olWfFAKqe8xjwsGD4CWXCUEydhHI906FIhJKMjIK59wb98zAug== +react-native@0.72.15: + version "0.72.15" + resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.72.15.tgz#9b74b0c39ec42befb70d494b535f863c4229ef55" + integrity sha512-UDxOZwCxhwb0dGuvcB/04uWzhDJ8etqW3fMOq6bv35WwEXMgKXXqZpshhMo64UVWm/m2ZmM32ckn5sf1EIqD9Q== dependencies: "@jest/create-cache-key-function" "^29.2.1" "@react-native-community/cli" "^11.4.1"