Compare commits

..
Author SHA1 Message Date
Richard Ramos f49383db8e feat_: extract storenode cycle to go-waku 2024-11-22 11:26:00 -04:00
969 changed files with 36496 additions and 22900 deletions
+185
View File
@@ -0,0 +1,185 @@
legacy.status-im.utils.build/warning-handler
legacy.status-im.utils.build/get-current-sha
status-im.constants/spacing-char
status-im.constants/arg-wrapping-char
legacy.status-im.ios.core/init
legacy.status-im.ui.components.camera/aspects
legacy.status-im.ui.components.camera/capture-targets
legacy.status-im.ui.components.camera/set-torch
legacy.status-im.ui.components.camera/request-access-ios
legacy.status-im.chat.models.message-content/stylings
legacy.status-im.chat.models.message-content/actions
legacy.status-im.chat.models.message-content/blank-string
legacy.status-im.chat.models.message-content/sorted-ranges
legacy.status-im.ethereum.mnemonic/words->passphrase
native-module.core/listener
native-module.core/multiaccount-reset
native-module.core/extract-group-membership-signatures
native-module.core/sign-group-membership
native-module.core/update-mailservers
legacy.status-im.ethereum.abi-spec/bytes-to-hex
legacy.status-im.android.core/init
legacy.status-im.chat.models.message/transport-keys
legacy.status-im.utils.datetime/week
legacy.status-im.utils.datetime/time-ago
legacy.status-im.utils.datetime/format-date
legacy.status-im.utils.datetime/get-ordinal-date
reagent.dom/render
reagent.dom/unmount-component-at-node
reagent.dom/dom-node
reagent.dom/force-update-all
legacy.status-im.multiaccounts.create.core/get-new-key-code
legacy.status-im.ethereum.decode/string
legacy.status-im.ui.screens.network.views/mainnet?
legacy.status-im.data-store.chats/event->string
legacy.status-im.mailserver.constants/seven-days
legacy.status-im.mailserver.constants/connection-timeout
legacy.status-im.hardwallet.card/install-applet
legacy.status-im.hardwallet.card/install-cash-applet
legacy.status-im.multiaccount.login.data-test/all-contacts
legacy.status-im.multiaccount.login.data-test/multiaccounts
legacy.status-im.multiaccount.login.data-test/get-chats
legacy.status-im.multiaccount.login.data-test/transport
legacy.status-im.multiaccount.login.data-test/topics
legacy.status-im.utils.utils/clear-timeout
legacy.status-im.utils.handlers/logged-in
legacy.status-im.multiaccounts.model/credentials
legacy.status-im.multiaccounts.login.core/contract-fleet?
legacy.status-im.multiaccounts.login.core/fetch-nodes
status-im.config/rpc-networks-only?
status-im.config/waku-enabled?
legacy.status-im.utils.pairing/has-paired-installations?
legacy.status-im.tribute-to-talk.core-test/user-cofx
mocks.js-dependencies/action-button
mocks.js-dependencies/camera
mocks.js-dependencies/dismiss-keyboard
mocks.js-dependencies/emoji-picker
mocks.js-dependencies/i18n
mocks.js-dependencies/qr-code
mocks.js-dependencies/svg
mocks.js-dependencies/icons
mocks.js-dependencies/webview
mocks.js-dependencies/desktop-linking
mocks.js-dependencies/desktop-shortcuts
mocks.js-dependencies/snoopy
mocks.js-dependencies/snoopy-filter
mocks.js-dependencies/snoopy-bars
mocks.js-dependencies/snoopy-buffer
mocks.js-dependencies/desktop-menu
mocks.js-dependencies/desktop-config
mocks.js-dependencies/react-native-navigation-twopane
mocks.js-dependencies/react-native-screens
mocks.js-dependencies/react-native-shake
mocks.js-dependencies/back-handler
mocks.js-dependencies/react
mocks.js-dependencies/react-navigation-native
mocks.js-dependencies/react-navigation-stack
mocks.js-dependencies/react-navigation-bottom-tabs
mocks.js-dependencies/react-native-haptic-feedback
mocks.js-dependencies/mock
quo.previews.main/init
legacy.status-im.chat.models.message-list-test/descending-range
legacy.status-im.chat.models.message-list-test/random-range
legacy.status-im.ethereum.eip165/supports?
legacy.status-im.utils.hex/valid-hex?
legacy.status-im.multiaccounts.core/chat-send?
legacy.status-im.hardwallet.simulated-keycard/install-cash-applet
legacy.status-im.hardwallet.simulated-keycard/sign-typed-data
legacy.status-im.utils.core/safe-read-message-content
legacy.status-im.ui.components.react/native-modules
legacy.status-im.ui.components.react/progress-bar
react-native.fs/move-file
react-native.fs/read-dir
react-native.fs/mkdir
react-native.fs/unlink
react-native.fs/file-exists?
legacy.status-im.ui.components.colors/white
legacy.status-im.ui.components.colors/black
legacy.status-im.ui.components.core/animated-header
legacy.status-im.ui.components.core/safe-area-provider
legacy.status-im.ui.components.core/safe-area-consumer
legacy.status-im.ui.components.core/safe-area-view
legacy.status-im.utils.universal-links.core/open!
legacy.status-im.transport.filters.core-test/member-2
legacy.status-im.ui.screens.chat.ttt/one-to-one-chat-description-container
legacy.status-im.ethereum.ens/ttl
legacy.status-im.ethereum.ens/addr-hash
legacy.status-im.ethereum.ens/name-hash
legacy.status-im.ethereum.ens/ABI-hash
legacy.status-im.ethereum.ens/pubkey-hash
legacy.status-im.network.core/get-network
status-im.constants/desktop-content-types
status-im.constants/blocks-per-hour
status-im.constants/one-earth-day
status-im.constants/left-pane-min-width
status-im.constants/system
status-im.constants/contact-discovery
status-im.constants/send-transaction-failed-parse-response
status-im.constants/send-transaction-failed-parse-params
status-im.constants/send-transaction-no-account-selected
status-im.constants/send-transaction-invalid-tx-sender
status-im.constants/web3-get-logs
status-im.constants/web3-transaction-receipt
status-im.constants/web3-new-filter
status-im.constants/web3-new-pending-transaction-filter
status-im.constants/web3-new-block-filter
status-im.constants/web3-uninstall-filter
status-im.constants/web3-get-filter-changes
status-im.constants/web3-shh-post
status-im.constants/web3-shh-new-identity
status-im.constants/web3-shh-has-identity
status-im.constants/web3-shh-new-group
status-im.constants/web3-shh-add-to-group
status-im.constants/web3-shh-new-filter
status-im.constants/web3-shh-uninstall-filter
status-im.constants/web3-shh-get-filter-changes
status-im.constants/web3-shh-get-messages
status-im.constants/status-create-address
status-im.constants/event-transfer-hash
status-im.constants/regx-rtl-characters
status-im.constants/desktop-msg-chars-hard-limit
status-im.constants/debug-metrics
status-im.constants/scan-qr-code
status-im.constants/ipfs-proto-code
status-im.constants/swarm-proto-code
legacy.status-im.multiaccounts.update.publisher/publish-update!
legacy.status-im.utils.async/task-queue
legacy.status-im.utils.async/async-periodic-run!
legacy.status-im.desktop.core/app-root
legacy.status-im.desktop.core/init
legacy.status-im.chat.models-test/test-db
legacy.status-im.ui.components.spacing/padding-vertical
legacy.status-im.utils.money/percent-change
utils.debounce/clear-all
legacy.status-im.transport.db/create-chat
legacy.status-im.utils.priority-map/priority-map
legacy.status-im.utils.priority-map/priority-map-by
legacy.status-im.utils.priority-map/priority-map-keyfn
legacy.status-im.utils.priority-map/empty-message-map
legacy.status-im.wallet.choose-recipient.core/use-default-eth-gas
legacy.status-im.ui.components.animation/decay
legacy.status-im.ui.components.animation/remove-all-listeners
legacy.status-im.ui.components.animation/stop-animation
legacy.status-im.ui.components.animation/animated
legacy.status-im.ui.components.animation/add
legacy.status-im.ui.components.animation/subtract
legacy.status-im.ui.components.animation/get-layout
legacy.status-im.wallet.transactions-test/uri-query-data
legacy.status-im.utils.name/shortened-name
legacy.status-im.ui.components.button.haptic/trigger
legacy.status-im.contact.db/filter-dapps
legacy.status-im.contact.db/filter-group-contacts
legacy.status-im.contact.db/legacy-pending?
legacy.status-im.utils.transducers-test/preview-call-1
legacy.status-im.utils.transducers-test/preview-call-2
legacy.status-im.utils.types/to-string
legacy.status-im.chat.db/datemark?
legacy.status-im.chat.db/gap?
legacy.status-im.chat.db/map->sorted-seq
legacy.status-im.utils.snoopy/status-module-filter
legacy.status-im.utils.snoopy/websocket-filter
legacy.status-im.utils.snoopy/touches-filter
legacy.status-im.utils.snoopy/native-animation-filter
legacy.status-im.utils.snoopy/keyboard-observer-filter
legacy.status-im.utils.multihash/hex
legacy.status-im.utils.multihash/decode-array
+3 -28
View File
@@ -4,7 +4,7 @@
legacy.status-im.utils.views/letsubs clojure.core/let
reagent.core/with-let clojure.core/let
legacy.status-im.utils.fx/defn clj-kondo.lint-as/def-catch-all
utils.re-frame/defn clojure.core/defn
utils.re-frame/defn clj-kondo.lint-as/def-catch-all
quo.react/with-deps-check clojure.core/fn
quo.previews.preview/list-comp clojure.core/for
legacy.status-im.utils.styles/def clojure.core/def
@@ -13,29 +13,7 @@
test-helpers.unit/deftest-event clojure.core/defn
taoensso.tufte/defnp clojure.core/defn}
:linters {:clojure-lsp/unused-public-var {:exclude-when-defined-by #{utils.re-frame/defn}
:exclude #{
;; even if we are not
;; using color now, we
;; will need it later
quo.foundations.colors
;; same for funcs from
;; native-module
native-module.core
;; some funcs used
;; temporarily during
;; development
test-helpers.component
test-helpers.unit
;; not sure if unused
;; functions here should
;; be removed:
keycard.keycard
react-native.fs}}
:case-duplicate-test {:level :error}
:linters {:case-duplicate-test {:level :error}
:case-quoted-test {:level :error}
:case-symbol-test {:level :error}
:clj-kondo-config {:level :error}
@@ -62,8 +40,7 @@
:equals-true {:level :error}
:inline-def {:level :error}
:invalid-arity {:skip-args [legacy.status-im.utils.fx/defn
utils.re-frame/defn
utils.re-frame/merge]}
utils.re-frame/defn]}
:loop-without-recur {:level :error}
:minus-one {:level :error}
:misplaced-docstring {:level :error}
@@ -76,8 +53,6 @@
:redundant-do {:level :error}
:redundant-let {:level :error}
:refer-all {:level :error}
;; ignore error in config itself saying that `:shadowed-fn-param` is unknown
#_{:clj-kondo/ignore [:clj-kondo-config]}
:shadowed-fn-param {:level :error}
:shadowed-var {:level :error
;; We temporarily use :include to define an
+1 -1
View File
@@ -35,4 +35,4 @@ TEST_NETWORKS_ENABLED=1
SHOW_NOT_IMPLEMENTED_FEATURES=0
ENABLE_ALERT_BANNER=0
FLAG_WALLET_CONNECT_ENABLED=1
API_LOGGING_ENABLED=1
LOG_REQUEST_GO=1
+1 -1
View File
@@ -39,4 +39,4 @@ DELETE_MESSAGE_UNDO_TIME_LIMIT=10000
ENABLE_ALERT_BANNER=0
FLAG_WALLET_CONNECT_ENABLED=1
MOBILE_DATA_SYNCING_TOGGLE_ENABLE=0
API_LOGGING_ENABLED=1
LOG_REQUEST_GO=1
+1 -1
View File
@@ -36,4 +36,4 @@ FAST_CREATE_COMMUNITY_ENABLED=1
TEST_NETWORKS_ENABLED=1
ENABLE_ALERT_BANNER=1
FLAG_WALLET_CONNECT_ENABLED=1
API_LOGGING_ENABLED=1
LOG_REQUEST_GO=1
+2 -2
View File
@@ -2,7 +2,7 @@ DEBUG_WEBVIEW=1
ETHEREUM_DEV_CLUSTER=1
EXTENSIONS=0
GROUP_CHATS_ENABLED=1
LOG_LEVEL=debug
LOG_LEVEL=info
MAILSERVER_CONFIRMATIONS_ENABLED=1
MAINNET_WARNING_ENABLED=1
PFS_ENCRYPTION_ENABLED=1
@@ -23,4 +23,4 @@ FAST_CREATE_COMMUNITY_ENABLED=0
TEST_NETWORKS_ENABLED=0
ENABLE_ALERT_BANNER=1
FLAG_WALLET_CONNECT_ENABLED=1
API_LOGGING_ENABLED=1
LOG_REQUEST_GO=0
+1 -1
View File
@@ -20,4 +20,4 @@ FAST_CREATE_COMMUNITY_ENABLED=0
TEST_NETWORKS_ENABLED=0
STATUS_PROXY_STAGE_NAME=prod
FLAG_WALLET_CONNECT_ENABLED=1
API_LOGGING_ENABLED=0
LOG_REQUEST_GO=0
+34 -16
View File
@@ -1,26 +1,39 @@
[comment]: # (Please replace ... with your information. Remove < and >)
[comment]: # (To auto-close issue on merge, please insert the related issue number after # i.e fixes #566)
If you submit PR for issue with bounty then write here Fixes #NN where NN is issue number
*otherwise*
fixes #...
## Summary
### Summary
[comment]: # (Summarise the problem and how the pull request solves it)
...
## Review notes
[comment]: # (Optional. Specify if something in particular should be looked at, or ignored, during review)
<!-- (Optional, remove if no changes to documentation) -->
Documentation change PR (review please): https://github.com/status-im/status.im/pull/xxx
## Testing notes
[comment]: # (Optional)
### Review notes
<!-- (Optional. Specify if something in particular should be looked at, or ignored, during review) -->
### Platforms
[comment]: # (Optional. Specify which platforms should be tested)
### Testing notes
<!-- (Optional) -->
#### Platforms
<!-- (Optional. Specify which platforms should be tested) -->
- Android
- iOS
- macOS
- Linux
- Windows
### Areas that may be impacted
[comment]: # (Optional. Specify if some specific areas need to be tested, such as 1-1 chats)
#### Areas that maybe impacted
<!-- (Optional. Specify if some specific areas has to be tested, for example 1-1 chats) -->
#### Functional
##### Functional
- 1-1 chats
- public chats
@@ -35,27 +48,32 @@ fixes #...
- fleet
- bootnodes
#### Non-functional
##### Non-functional
- battery performance
- CPU performance / speed of the app
- network consumption
## Steps to test
[comment]: # (Specify exact steps to test if there are such)
### Steps to test
<!-- (Specify exact steps to test if there are such) -->
- Open Status
- ...
- Step 3, etc.
<!-- (PRs will only be accepted if squashed into single commit.) -->
[comment]: # (Can be ready or wip)
status: ready
### Before and after screenshots comparison
| Figma (if available) | iOS (if available) | Android (if available)
| --- | --- | --- |
| Please embed Image/Video here of the before and after. | Please embed Image/Video here of the before and after. | Please embed Image/Video here of the before and after. |
status: ready <!-- Can be ready or wip -->
<!-- Uncomment this section for status-go upgrade/dogfooding pull requests
- Specify potentially impacted user flows in _Areas that may be impacted*.
- Specify potentially impacted user flows in _Areas that maybe impacted*.
- Ensure that _Steps to test_ is filled in.
### Risk
+4 -4
View File
@@ -43,6 +43,8 @@ export NODE_OPTIONS += --openssl-legacy-provider
# The path can be anything, but home is usually safest.
export KEYSTORE_PATH ?= $(HOME)/.gradle/status-im.keystore
# Our custom config is located in nix/nix.conf
export NIX_USER_CONF_FILES = $(PWD)/nix/nix.conf
# Location of symlinks to derivations that should not be garbage collected
export _NIX_GCROOTS = ./.nix-gcroots
# Defines which variables will be kept for Nix pure shell, use semicolon as divider
@@ -267,11 +269,9 @@ run-metro: export TARGET := clojure
run-metro: ##@run Start Metro to build React Native changes
@scripts/run-metro.sh
export RE_FRISK_PORT ?= 4567
run-re-frisk: export TARGET := clojure
run-re-frisk: ##@run Start re-frisk server
yarn shadow-cljs run re-frisk-remote.core/start ${RE_FRISK_PORT}
yarn shadow-cljs run re-frisk-remote.core/start
# TODO: Migrate this to a Nix recipe, much the same way as nix/mobile/android/targets/release-android.nix
run-android: export TARGET := android
@@ -445,7 +445,7 @@ android-ports: export RCT_METRO_PORT ?= 8081
android-ports: ##@other Add proxies to Android Device/Simulator
adb reverse tcp:$(RCT_METRO_PORT) tcp:$(RCT_METRO_PORT) && \
adb reverse tcp:3449 tcp:3449 && \
adb reverse tcp:$(RE_FRISK_PORT) tcp:$(RE_FRISK_PORT) && \
adb reverse tcp:4567 tcp:4567 && \
adb reverse tcp:$(FLOWSTORM_PORT) tcp:$(FLOWSTORM_PORT) && \
adb forward tcp:5561 tcp:5561
+1 -1
View File
@@ -1 +1 @@
2.32.0
2.30.0
+3 -8
View File
@@ -54,9 +54,6 @@ react {
//
// The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
// hermesFlags = ["-O", "-output-source-map"]
/* Autolinking */
autolinkLibrariesWithApp()
}
/**
@@ -146,10 +143,6 @@ android {
kotlinOptions {
jvmTarget = JavaVersion.VERSION_17
}
// Disable default lint checks to remove redundant lintVitalReportRelease task
lintOptions {
checkReleaseBuilds false
}
// https://developer.android.com/studio/projects/install-ndk#vanilla_cmake
externalNativeBuild {
@@ -304,7 +297,7 @@ dependencies {
implementation("com.facebook.fresco:fresco:2.5.0")
implementation("com.facebook.fresco:animated-gif:2.5.0")
implementation("com.squareup.okhttp3:okhttp-tls:4.11.0")
implementation("com.google.prefab:cli:2.1.0")
implementation("com.google.prefab:cli:2.0.0")
implementation("com.android.tools.build:aapt2:8.1.1-10154469")
}
@@ -340,3 +333,5 @@ task hemroidBuild(type: Exec) {
}
preBuild.dependsOn hemroidBuild
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
-2
View File
@@ -6,8 +6,6 @@ LOCAL_MODULE := status-logs
LOCAL_SRC_FILES := Log.c
LOCAL_CPPFLAGS := -std=c++11 -fexceptions -I$(LOCAL_PATH)/include
# Fix for : ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
LOCAL_CFLAGS := '-Wno-error=implicit-function-declaration'
LOCAL_LDFLAGS := -llog
include $(BUILD_SHARED_LIBRARY)
+1 -6
View File
@@ -7,10 +7,5 @@
<!-- Remove licensing permission since we don't license our app and it blocks F-Droid submissions. -->
<uses-permission tools:node="remove" android:name="com.android.vending.CHECK_LICENSE"/>
<application
tools:targetApi="28"
tools:ignore="GoogleAppIndexingWarning"
android:usesCleartextTraffic="true"
tools:replace="android:appComponentFactory"
android:appComponentFactory="androidx.core.app.CoreComponentFactory" />
<application tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" android:usesCleartextTraffic="true" />
</manifest>
+1 -2
View File
@@ -42,8 +42,7 @@
android:largeHeap="true"
android:usesCleartextTraffic="true"
android:extractNativeLibs="true"
android:requestLegacyExternalStorage="true"
android:supportsRtl="true">
android:requestLegacyExternalStorage="true">
<!-- After upgrading Android Gradle Plugin to 4.2.0 and above we must get rid of `extractNativeLibs="true"`
and use`useLegacyPackaging` flag in our app's `build.gradle`-->
<meta-data android:name="commitHash" android:value="${commitHash}"/>
@@ -6,6 +6,7 @@ import com.facebook.react.PackageList
import com.facebook.react.ReactApplication
import com.facebook.react.ReactNativeHost
import com.facebook.react.ReactPackage
import com.facebook.react.bridge.JSIModulePackage
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint
import com.facebook.react.modules.network.OkHttpClientProvider
import com.reactnativenavigation.NavigationApplication
@@ -0,0 +1,40 @@
package im.status.ethereum;
import java.io.File;
import java.io.BufferedReader;
import java.io.InputStreamReader;
/** @author Kevin Kowalewski */
public class RootUtil {
public static boolean isDeviceRooted() {
return checkRootMethod1() || checkRootMethod2() || checkRootMethod3();
}
private static boolean checkRootMethod1() {
String buildTags = android.os.Build.TAGS;
return buildTags != null && buildTags.contains("test-keys");
}
private static boolean checkRootMethod2() {
String[] paths = { "/system/app/Superuser.apk", "/sbin/su", "/system/bin/su", "/system/xbin/su", "/data/local/xbin/su", "/data/local/bin/su", "/system/sd/xbin/su",
"/system/bin/failsafe/su", "/data/local/su" };
for (String path : paths) {
if (new File(path).exists()) return true;
}
return false;
}
private static boolean checkRootMethod3() {
Process process = null;
try {
process = Runtime.getRuntime().exec(new String[] { "/system/xbin/which", "su" });
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
return in.readLine() != null;
} catch (Throwable t) {
return false;
} finally {
if (process != null) process.destroy();
}
}
}
@@ -1,42 +0,0 @@
package im.status.ethereum
import android.os.Build
import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader
object RootUtil {
fun isDeviceRooted(): Boolean =
checkRootMethod1() || checkRootMethod2() || checkRootMethod3()
private fun checkRootMethod1(): Boolean =
Build.TAGS?.contains("test-keys") ?: false
private fun checkRootMethod2(): Boolean {
val paths = arrayOf(
"/system/app/Superuser.apk",
"/sbin/su",
"/system/bin/su",
"/system/xbin/su",
"/data/local/xbin/su",
"/data/local/bin/su",
"/system/sd/xbin/su",
"/system/bin/failsafe/su",
"/data/local/su"
)
return paths.any { File(it).exists() }
}
private fun checkRootMethod3(): Boolean {
var process: Process? = null
return try {
process = Runtime.getRuntime().exec(arrayOf("/system/xbin/which", "su"))
BufferedReader(InputStreamReader(process.inputStream)).readLine() != null
} catch (t: Throwable) {
false
} finally {
process?.destroy()
}
}
}
+1 -2
View File
@@ -17,8 +17,7 @@ ext {
kotlinVersion = project.kotlinPluginVersion
kotlinPluginVersion = project.kotlinPluginVersion
kotlinToolsVersion = project.kotlinPluginVersion
// This version must match ndkVersion version inside nix/pkgs/android-sdk/compose.nix
ndkVersion = "26.1.10909125"
ndkVersion = "25.2.9519653"
}
buildscript {
+3 -2
View File
@@ -27,8 +27,8 @@ targetSdkVersion=34
buildToolsVersion=34.0.0
supportLibVersion=28.0.0
# This should match version from nix/pkgs/aapt2/default.nix
gradlePluginVersion=8.5.0
kotlinPluginVersion=1.9.24
gradlePluginVersion=7.4.2
kotlinPluginVersion=1.9.0
android.useAndroidX=true
android.enableJetifier=true
@@ -54,6 +54,7 @@ commitHash=unknown
# to write custom TurboModules/Fabric components OR use libraries that
# are providing them.
newArchEnabled=false
# Use this property to enable or disable the Hermes JS engine.
# If set to false, you will be using JSC instead.
# Disabled for debug builds to avoid 'maximum call stack exceeded' errors.
+1 -2
View File
@@ -5,11 +5,10 @@ includeBuild('../node_modules/@react-native/gradle-plugin')
gradlePluginPortal()
}
}
plugins { id("com.facebook.react.settings") }
extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() }
include ':react-native-share'
project(':react-native-share').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-share/android')
rootProject.name = 'StatusIm'
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':react-native-nfc-manager'
project(':react-native-nfc-manager').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-nfc-manager/android')
include ':app'
+2 -2
View File
@@ -1,11 +1,11 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.20'
library 'status-jenkins-lib@v1.9.13'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
pipeline {
agent { label 'linux && x86_64 && nix-2.24' }
agent { label 'linux && x86_64 && nix-2.19' }
options {
timestamps()
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.20'
library 'status-jenkins-lib@v1.9.13'
import groovy.json.JsonBuilder
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.20'
library 'status-jenkins-lib@v1.9.13'
pipeline {
agent { label 'linux' }
+2 -2
View File
@@ -1,11 +1,11 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.20'
library 'status-jenkins-lib@v1.9.13'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
pipeline {
agent { label 'macos && arm64 && nix-2.24 && xcode-16.2' }
agent { label 'macos && arm64 && nix-2.19 && xcode-15.1' }
parameters {
string(
+2 -2
View File
@@ -1,11 +1,11 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.20'
library 'status-jenkins-lib@v1.9.13'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
pipeline {
agent { label 'linux && x86_64 && nix-2.24' }
agent { label 'linux && x86_64 && nix-2.19' }
options {
timestamps()
+21 -5
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.20'
library 'status-jenkins-lib@v1.9.13'
pipeline {
@@ -73,9 +73,9 @@ pipeline {
passwordVariable: 'TESTRAIL_PASS'
),
usernamePassword(
credentialsId: 'lambda-test-api',
usernameVariable: 'LAMBDA_TEST_USERNAME',
passwordVariable: 'LAMBDA_TEST_ACCESS_KEY'
credentialsId: 'sauce-labs-api',
usernameVariable: 'SAUCE_USERNAME',
passwordVariable: 'SAUCE_ACCESS_KEY'
),
string(
credentialsId: 'etherscan-api-key',
@@ -95,7 +95,8 @@ pipeline {
sh 'cp -f $TEST_ETH_ACCOUNTS_FILE users.py'
sh """
python3 -m pytest \
--numprocesses 9 \
--numprocesses 8 \
--rerun_count=2 \
--testrail_report=True \
-m testrail_id \
-m \"nightly\" \
@@ -109,6 +110,21 @@ pipeline {
}
post {
always {
script {
sauce('sauce-labs-cred') {
saucePublisher()
}
}
}
success {
script {
junit(
testDataPublishers: [[$class: 'SauceOnDemandReportPublisher', jobVisibility: 'public']],
testResults: 'test/appium/tests/*.xml'
)
}
}
cleanup {
sh 'make purge'
}
+6 -5
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.20'
library 'status-jenkins-lib@v1.9.13'
pipeline {
@@ -111,9 +111,9 @@ pipeline {
passwordVariable: 'TESTRAIL_PASS'
),
usernamePassword(
credentialsId: 'lambda-test-api',
usernameVariable: 'LAMBDA_TEST_USERNAME',
passwordVariable: 'LAMBDA_TEST_ACCESS_KEY'
credentialsId: 'sauce-labs-api',
usernameVariable: 'SAUCE_USERNAME',
passwordVariable: 'SAUCE_ACCESS_KEY'
),
string(
credentialsId: 'etherscan-api-key',
@@ -133,7 +133,8 @@ pipeline {
sh 'cp -f $TEST_ETH_ACCOUNTS_FILE users.py'
sh """
python3 -m pytest \
--numprocesses 9 \
--numprocesses 8 \
--rerun_count=2 \
--testrail_report=True \
-k \"${params.KEYWORD_EXPRESSION}\" \
--apk=${params.APK_URL ?: apk_path} \
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.20'
library 'status-jenkins-lib@v1.9.13'
pipeline {
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.20'
library 'status-jenkins-lib@v1.9.13'
pipeline {
agent { label 'macos' }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.20'
library 'status-jenkins-lib@v1.9.13'
pipeline {
agent { label params.AGENT_LABEL }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.20'
library 'status-jenkins-lib@v1.9.13'
pipeline {
agent { label 'linux' }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.20'
library 'status-jenkins-lib@v1.9.13'
pipeline {
agent {
-1
View File
@@ -16,7 +16,6 @@
- [Patching](patching.md)
- [Creating a pixel perfect UI](pixel-perfection.md)
- [Contributing to status-go](status-go-changes.md)
- [Status Backend Server](use-status-backend-server.md)
- [Malli schemas (recorded demo)](https://www.youtube.com/watch?v=SlRio70aYVI) ([slides](files/forging-code-with-schemas-sep-2023-slides.pdf))
## Testing
+1 -1
View File
@@ -150,7 +150,7 @@ This one is straightforward, just evaluate a navigation dispatch form from anywh
#### REPL-ing a component
This is also straightforward, but there are some small differences. Just like above, we only have to evaluate a dispatch form, as follows:
This is also straighforward, but there are some small differences. Just like above, we only have to evaluate a dispatch form, as follows:
```cljs
;; example debugging a quo component, although it could be any other component e.g. from the `status-im2` ns.
+1 -1
View File
@@ -26,7 +26,7 @@ export STATUS_BACKEND_SERVER_HOST="127.0.0.1:60000"
export STATUS_BACKEND_SERVER_ROOT_DATA_DIR="/path/to/your/root/data/dir"
```
You need to change `STATUS_BACKEND_SERVER_ROOT_DATA_DIR` to your preferred directory and ensure it exists, it should be in absolute path.
All the db files and log files(api.log/geth.log) and keystore files etc will be stored in this directory.
All the db files and log files(requests.log/geth.log) and keystore files etc will be stored in this directory.
### Start the status backend server:
```shell
+70 -76
View File
@@ -1,51 +1,48 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.7)
base64
nkf
CFPropertyList (3.0.6)
rexml
activesupport (7.0.8.7)
activesupport (7.0.8)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
artifactory (3.0.17)
addressable (2.8.6)
public_suffix (>= 2.0.2, < 6.0)
artifactory (3.0.15)
atomos (0.1.3)
aws-eventstream (1.3.0)
aws-partitions (1.1032.0)
aws-sdk-core (3.214.1)
aws-partitions (1.872.0)
aws-sdk-core (3.190.1)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.992.0)
aws-sigv4 (~> 1.9)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.8)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.96.0)
aws-sdk-core (~> 3, >= 3.210.0)
aws-sigv4 (~> 1.5)
aws-sdk-s3 (1.177.0)
aws-sdk-core (~> 3, >= 3.210.0)
aws-sdk-kms (1.75.0)
aws-sdk-core (~> 3, >= 3.188.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.141.0)
aws-sdk-core (~> 3, >= 3.189.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.5)
aws-sigv4 (1.10.1)
aws-sigv4 (~> 1.8)
aws-sigv4 (1.8.0)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
base64 (0.2.0)
claide (1.1.0)
colored (1.2)
colored2 (3.1.2)
commander (4.6.0)
highline (~> 2.0.0)
concurrent-ruby (1.3.4)
concurrent-ruby (1.2.2)
declarative (0.0.20)
digest-crc (0.6.5)
rake (>= 12.0.0, < 14.0.0)
domain_name (0.6.20240107)
domain_name (0.6.20231109)
dotenv (2.8.1)
emoji_regex (3.2.3)
excon (0.112.0)
faraday (1.10.4)
excon (0.108.0)
faraday (1.10.3)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
@@ -64,24 +61,24 @@ GEM
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-httpclient (1.0.1)
faraday-multipart (1.1.0)
multipart-post (~> 2.0)
faraday-net_http (1.0.2)
faraday-multipart (1.0.4)
multipart-post (~> 2)
faraday-net_http (1.0.1)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
faraday-rack (1.0.0)
faraday-retry (1.0.3)
faraday_middleware (1.2.1)
faraday_middleware (1.2.0)
faraday (~> 1.0)
fastimage (2.4.0)
fastlane (2.226.0)
fastimage (2.2.7)
fastlane (2.217.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.8, < 3.0.0)
artifactory (~> 3.0)
aws-sdk-s3 (~> 1.0)
babosa (>= 1.0.3, < 2.0.0)
bundler (>= 1.12.0, < 3.0.0)
colored (~> 1.2)
colored
commander (~> 4.6)
dotenv (>= 2.1.1, < 3.0.0)
emoji_regex (>= 0.1, < 4.0)
@@ -90,11 +87,9 @@ GEM
faraday-cookie_jar (~> 0.0.6)
faraday_middleware (~> 1.0)
fastimage (>= 2.1.0, < 3.0.0)
fastlane-sirp (>= 1.0.0)
gh_inspector (>= 1.1.2, < 2.0.0)
google-apis-androidpublisher_v3 (~> 0.3)
google-apis-playcustomapp_v1 (~> 0.1)
google-cloud-env (>= 1.6.0, < 2.0.0)
google-cloud-storage (~> 1.31)
highline (~> 2.0)
http-cookie (~> 1.0.5)
@@ -103,10 +98,10 @@ GEM
mini_magick (>= 4.9.4, < 5.0.0)
multipart-post (>= 2.0.0, < 3.0.0)
naturally (~> 2.2)
optparse (>= 0.1.1, < 1.0.0)
optparse (~> 0.1.1)
plist (>= 3.1.0, < 4.0.0)
rubyzip (>= 2.0.0, < 3.0.0)
security (= 0.1.5)
security (= 0.1.3)
simctl (~> 1.6.3)
terminal-notifier (>= 2.0.0, < 3.0.0)
terminal-table (~> 3)
@@ -114,14 +109,12 @@ GEM
tty-spinner (>= 0.8.0, < 1.0.0)
word_wrap (~> 1.0.0)
xcodeproj (>= 1.13.0, < 2.0.0)
xcpretty (~> 0.4.0)
xcpretty-travis-formatter (>= 0.0.3, < 2.0.0)
fastlane-sirp (1.0.0)
sysrandom (~> 1.0)
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3)
gh_inspector (1.1.3)
google-apis-androidpublisher_v3 (0.54.0)
google-apis-core (>= 0.11.0, < 2.a)
google-apis-core (0.11.3)
google-apis-core (0.11.2)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.16.2, < 2.a)
httpclient (>= 2.8.1, < 3.a)
@@ -129,66 +122,66 @@ GEM
representable (~> 3.0)
retriable (>= 2.0, < 4.a)
rexml
webrick
google-apis-iamcredentials_v1 (0.17.0)
google-apis-core (>= 0.11.0, < 2.a)
google-apis-playcustomapp_v1 (0.13.0)
google-apis-core (>= 0.11.0, < 2.a)
google-apis-storage_v1 (0.31.0)
google-apis-storage_v1 (0.29.0)
google-apis-core (>= 0.11.0, < 2.a)
google-cloud-core (1.7.1)
google-cloud-core (1.6.1)
google-cloud-env (>= 1.0, < 3.a)
google-cloud-errors (~> 1.0)
google-cloud-env (1.6.0)
faraday (>= 0.17.3, < 3.0)
google-cloud-errors (1.4.0)
google-cloud-storage (1.47.0)
google-cloud-env (2.1.0)
faraday (>= 1.0, < 3.a)
google-cloud-errors (1.3.1)
google-cloud-storage (1.45.0)
addressable (~> 2.8)
digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1)
google-apis-storage_v1 (~> 0.31.0)
google-apis-storage_v1 (~> 0.29.0)
google-cloud-core (~> 1.6)
googleauth (>= 0.16.2, < 2.a)
mini_mime (~> 1.0)
googleauth (1.8.1)
faraday (>= 0.17.3, < 3.a)
googleauth (1.9.1)
faraday (>= 1.0, < 3.a)
google-cloud-env (~> 2.1)
jwt (>= 1.4, < 3.0)
multi_json (~> 1.11)
os (>= 0.9, < 2.0)
signet (>= 0.16, < 2.a)
highline (2.0.3)
http-cookie (1.0.8)
http-cookie (1.0.5)
domain_name (~> 0.5)
httpclient (2.8.3)
i18n (1.14.6)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
jmespath (1.6.2)
json (2.9.1)
jwt (2.10.1)
base64
mini_magick (4.13.2)
json (2.7.1)
jwt (2.7.1)
mini_magick (4.12.0)
mini_mime (1.1.5)
minitest (5.25.4)
minitest (5.20.0)
multi_json (1.15.0)
multipart-post (2.4.1)
nanaimo (0.4.0)
multipart-post (2.3.0)
nanaimo (0.3.0)
naturally (2.2.1)
nkf (0.2.0)
optparse (0.6.0)
optparse (0.1.1)
os (1.1.4)
plist (3.7.2)
public_suffix (6.0.1)
rake (13.2.1)
plist (3.7.0)
public_suffix (5.0.4)
rake (13.1.0)
representable (3.2.0)
declarative (< 0.1.0)
trailblazer-option (>= 0.1.1, < 0.2.0)
uber (< 0.2.0)
retriable (3.1.2)
rexml (3.4.0)
rouge (3.28.0)
rexml (3.2.6)
rouge (2.0.7)
ruby2_keywords (0.0.5)
rubyzip (2.4.1)
security (0.1.5)
signet (0.19.0)
rubyzip (2.3.2)
security (0.1.3)
signet (0.18.0)
addressable (~> 2.8)
faraday (>= 0.17.5, < 3.a)
jwt (>= 1.5, < 3.0)
@@ -196,7 +189,6 @@ GEM
simctl (1.6.10)
CFPropertyList
naturally
sysrandom (1.0.5)
terminal-notifier (2.0.0)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
@@ -208,27 +200,29 @@ GEM
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
uber (0.1.0)
unicode-display_width (2.6.0)
unicode-display_width (2.5.0)
webrick (1.8.1)
word_wrap (1.0.0)
xcodeproj (1.27.0)
xcodeproj (1.23.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.4.0)
rexml (>= 3.3.6, < 4.0)
xcpretty (0.4.0)
rouge (~> 3.28.0)
nanaimo (~> 0.3.0)
rexml (~> 3.2.4)
xcpretty (0.3.0)
rouge (~> 2.0.7)
xcpretty-travis-formatter (1.0.1)
xcpretty (~> 0.2, >= 0.0.7)
PLATFORMS
arm64-darwin-22
arm64-darwin-23
ruby
x86_64-darwin-22
DEPENDENCIES
activesupport (>= 6.1.7.3, < 7.1.0)
fastlane (>= 2.131.0)
BUNDLED WITH
2.5.16
2.4.13
+104 -136
View File
@@ -5,10 +5,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1zq4f834my1z6yh05rfr1dzl3i8padh33j092zlal979blvh4iyz";
sha256 = "188kbwkn1lbhz40ala8ykp20jzqphgc68g3d8flin8cqa2xid0s5";
type = "gem";
};
version = "7.0.8.7";
version = "7.0.8";
};
addressable = {
dependencies = ["public_suffix"];
@@ -16,20 +16,20 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0cl2qpvwiffym62z991ynks7imsm87qmgxf0yfsmlwzkgi9qcaa6";
sha256 = "0irbdwkkjwzajq1ip6ba46q49sxnrl2cw7ddkdhsfhb6aprnm3vr";
type = "gem";
};
version = "2.8.7";
version = "2.8.6";
};
artifactory = {
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0qzj389l2a3zig040h882mf6cxfa71pm2nk51l4p85n3ck4xa8rh";
sha256 = "0wify8rhjwr5bw5y6ary61vba290vk766cxw9a9mg05yswmaisls";
type = "gem";
};
version = "3.0.17";
version = "3.0.15";
};
atomos = {
groups = ["default"];
@@ -56,10 +56,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1b7fjl7cixz099ncdr6il1gb41dxhgz0jbczk195y4cy22yhvqla";
sha256 = "1ddbcz8p3abbw8d8pn796z1ry1mbapl6ayhh37ziwal6bd047kvm";
type = "gem";
};
version = "1.1032.0";
version = "1.872.0";
};
aws-sdk-core = {
dependencies = ["aws-eventstream" "aws-partitions" "aws-sigv4" "jmespath"];
@@ -67,10 +67,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1za95pl089xarrqr23vafs1w43b36k0jwhkwifgs2dnp0xs336s1";
sha256 = "1ansagfl5irx1y6b9xf4xpi9j6q6k5pbd2aw80hn0p4m3ycafamh";
type = "gem";
};
version = "3.214.1";
version = "3.190.1";
};
aws-sdk-kms = {
dependencies = ["aws-sdk-core" "aws-sigv4"];
@@ -78,10 +78,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0xd3ddd9jiapkgv8im4pl9dcdy2ps7qjsssf2nz3q6sd1ca8x0di";
sha256 = "1qzxqfgrhnl5rdc39a1gl2pgrdxgnsj12zycpxnsx8lg6arfmnr1";
type = "gem";
};
version = "1.96.0";
version = "1.75.0";
};
aws-sdk-s3 = {
dependencies = ["aws-sdk-core" "aws-sdk-kms" "aws-sigv4"];
@@ -89,10 +89,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "10ziy8zslfjs0ihls7wiq6zvsncq89azh36rshmlylry1hhxjbxz";
sha256 = "0bnhpmi0iiaj88rqc5lhhnp2gyrk4fs8xz51lj36wwzng94qinya";
type = "gem";
};
version = "1.177.0";
version = "1.141.0";
};
aws-sigv4 = {
dependencies = ["aws-eventstream"];
@@ -100,10 +100,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1fq3lbvkgm1vk5wa8l7vdnq3vjnlmsnyf4bbd0jq3qadyd9hf54a";
sha256 = "1g3w27wzjy4si6kp49w10as6ml6g6zl3xrfqs5ikpfciidv9kpc4";
type = "gem";
};
version = "1.10.1";
version = "1.8.0";
};
babosa = {
groups = ["default"];
@@ -115,26 +115,16 @@
};
version = "1.0.4";
};
base64 = {
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "01qml0yilb9basf7is2614skjp8384h2pycfx86cr8023arfj98g";
type = "gem";
};
version = "0.2.0";
};
CFPropertyList = {
dependencies = ["base64" "nkf" "rexml"];
dependencies = ["rexml"];
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0k1w5i4lb1z941m7ds858nly33f3iv12wvr1zav5x3fa99hj2my4";
sha256 = "1a36zn77yyibqsfpka0i8vgf3yv98ic2b9wwlbc29566y8wpa2bq";
type = "gem";
};
version = "3.0.7";
version = "3.0.6";
};
claide = {
groups = ["default"];
@@ -182,10 +172,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0chwfdq2a6kbj6xz9l6zrdfnyghnh32si82la1dnpa5h75ir5anl";
sha256 = "0krcwb6mn0iklajwngwsg850nk8k9b35dhmc2qkbdqvmifdi2y9q";
type = "gem";
};
version = "1.3.4";
version = "1.2.2";
};
declarative = {
groups = ["default"];
@@ -213,10 +203,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0cyr2xm576gqhqicsyqnhanni47408w2pgvrfi8pd13h2li3nsaz";
sha256 = "1gpciaifmxql8h01ci12qq08dnqrdlzkkz6fmia9v9yc3r9a29si";
type = "gem";
};
version = "0.6.20240107";
version = "0.6.20231109";
};
dotenv = {
groups = ["default"];
@@ -243,10 +233,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1w7098hnyby5sn2315qy26as6kxlxivxlcrs714amj9g9hxaryfs";
sha256 = "1q9yz7x36mpzpz04bg6hdyrzzk4bri9jg3h2ygw26bf6v3axq53q";
type = "gem";
};
version = "0.112.0";
version = "0.108.0";
};
faraday = {
dependencies = ["faraday-em_http" "faraday-em_synchrony" "faraday-excon" "faraday-httpclient" "faraday-multipart" "faraday-net_http" "faraday-net_http_persistent" "faraday-patron" "faraday-rack" "faraday-retry" "ruby2_keywords"];
@@ -254,10 +244,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "069gmdh5j90v06rbwlqvlhzhq45lxhx74mahz25xd276rm0wb153";
sha256 = "1c760q0ks4vj4wmaa7nh1dgvgqiwaw0mjr7v8cymy7i3ffgjxx90";
type = "gem";
};
version = "1.10.4";
version = "1.10.3";
};
faraday-cookie_jar = {
dependencies = ["faraday" "http-cookie"];
@@ -316,20 +306,20 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0l87r9jg06nsh24gwwd1jdnxb1zq89ffybnxab0dd90nfcf0ysw5";
sha256 = "09871c4hd7s5ws1wl4gs7js1k2wlby6v947m2bbzg43pnld044lh";
type = "gem";
};
version = "1.1.0";
version = "1.0.4";
};
faraday-net_http = {
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "10n6wikd442mfm15hd6gzm0qb527161w1wwch4h5m4iclkz2x6b3";
sha256 = "1fi8sda5hc54v1w3mqfl5yz09nhx35kglyx72w7b8xxvdr0cwi9j";
type = "gem";
};
version = "1.0.2";
version = "1.0.1";
};
faraday-net_http_persistent = {
groups = ["default"];
@@ -377,42 +367,31 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1s990pnapb3vci9c00bklqc7jjix4i2zhxn2zf1lfk46xv47hnyl";
sha256 = "1bw8mfh4yin2xk7138rg3fhb2p5g2dlmdma88k82psah9mbmvlfy";
type = "gem";
};
version = "1.2.1";
version = "1.2.0";
};
fastimage = {
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1s67b9n7ki3iaycypq8sh02377gjkaxadg4dq53bpgfk4xg3gkjz";
sha256 = "1pd7pamzhdz2w0fbcvsfn2nyslznvphnwj16zw35g2b28zd2xyzx";
type = "gem";
};
version = "2.4.0";
version = "2.2.7";
};
fastlane = {
dependencies = ["CFPropertyList" "addressable" "artifactory" "aws-sdk-s3" "babosa" "colored" "commander" "dotenv" "emoji_regex" "excon" "faraday" "faraday-cookie_jar" "faraday_middleware" "fastimage" "fastlane-sirp" "gh_inspector" "google-apis-androidpublisher_v3" "google-apis-playcustomapp_v1" "google-cloud-env" "google-cloud-storage" "highline" "http-cookie" "json" "jwt" "mini_magick" "multipart-post" "naturally" "optparse" "plist" "rubyzip" "security" "simctl" "terminal-notifier" "terminal-table" "tty-screen" "tty-spinner" "word_wrap" "xcodeproj" "xcpretty" "xcpretty-travis-formatter"];
dependencies = ["CFPropertyList" "addressable" "artifactory" "aws-sdk-s3" "babosa" "colored" "commander" "dotenv" "emoji_regex" "excon" "faraday" "faraday-cookie_jar" "faraday_middleware" "fastimage" "gh_inspector" "google-apis-androidpublisher_v3" "google-apis-playcustomapp_v1" "google-cloud-storage" "highline" "http-cookie" "json" "jwt" "mini_magick" "multipart-post" "naturally" "optparse" "plist" "rubyzip" "security" "simctl" "terminal-notifier" "terminal-table" "tty-screen" "tty-spinner" "word_wrap" "xcodeproj" "xcpretty" "xcpretty-travis-formatter"];
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0v3w69j9nc98p4jdr81bx0mdyab0b5v93kq3bixsy14q5v92flp6";
sha256 = "0p2b92csayzlj60v15fz3mq4h23kvvr7swhaavi6fpaqzf70iafi";
type = "gem";
};
version = "2.226.0";
};
fastlane-sirp = {
dependencies = ["sysrandom"];
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0hg6ql3g25f96fsmwr9xlxpn8afa7wvjampnrh1fqffhphjqyiv6";
type = "gem";
};
version = "1.0.0";
version = "2.217.0";
};
gh_inspector = {
groups = ["default"];
@@ -436,15 +415,15 @@
version = "0.54.0";
};
google-apis-core = {
dependencies = ["addressable" "googleauth" "httpclient" "mini_mime" "representable" "retriable" "rexml"];
dependencies = ["addressable" "googleauth" "httpclient" "mini_mime" "representable" "retriable" "rexml" "webrick"];
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "15ycm7al9dizabbqmri5xmiz8mbcci343ygb64ndbmr9n49p08a3";
sha256 = "1cly6ycryjhk15d60v3nqvhqpjk9f0nznnslbdnin90f5r54sbpd";
type = "gem";
};
version = "0.11.3";
version = "0.11.2";
};
google-apis-iamcredentials_v1 = {
dependencies = ["google-apis-core"];
@@ -474,10 +453,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "13yvc9r8bhs16vq3fjc93qlffmq9p6zx97c9g1c3wh0jbrvwrs03";
sha256 = "1k432qgxf41c4m6d68rascm0gyj18r7ypmrnyzmxh7k7nh543awx";
type = "gem";
};
version = "0.31.0";
version = "0.29.0";
};
google-cloud-core = {
dependencies = ["google-cloud-env" "google-cloud-errors"];
@@ -485,10 +464,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0bh1yzv26mqn2qmzkqa0qwzmq4w0dcphjla4w5m2f2qlkj583wjs";
sha256 = "00wfvdvdv9m4l5ydn6xp65n68mgmpqr3n09hzvxs7gp8fly3j17v";
type = "gem";
};
version = "1.7.1";
version = "1.6.1";
};
google-cloud-env = {
dependencies = ["faraday"];
@@ -496,20 +475,20 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "05gshdqscg4kil6ppfzmikyavsx449bxyj47j33r4n4p8swsqyb1";
sha256 = "056r1p8vhjswnx2cy3mzhwc5gj03whmpz8m4p2ph37gag5bpnxmf";
type = "gem";
};
version = "1.6.0";
version = "2.1.0";
};
google-cloud-errors = {
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "056yw9cg771c1xqvw15wpdfdw9lz3m13fh5b6a3p1c9xaq7jwkhb";
sha256 = "0flpj7v196c3xsqx4yjb7rjcj8p0by4rhj6qf5zanw4p1i41ssf0";
type = "gem";
};
version = "1.4.0";
version = "1.3.1";
};
google-cloud-storage = {
dependencies = ["addressable" "digest-crc" "google-apis-iamcredentials_v1" "google-apis-storage_v1" "google-cloud-core" "googleauth" "mini_mime"];
@@ -517,21 +496,21 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0xpb3s7zr7g647xg66y2mavdargk5ixsfbfdmi4m2jc3khdd0hxm";
sha256 = "0033bi8qwm0ksxsv5zhz4nzwsiaapq3xk79z8f8rx3v09vdap07j";
type = "gem";
};
version = "1.47.0";
version = "1.45.0";
};
googleauth = {
dependencies = ["faraday" "jwt" "multi_json" "os" "signet"];
dependencies = ["faraday" "google-cloud-env" "jwt" "multi_json" "os" "signet"];
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1ry9v23kndgx2pxq9v31l68k9lnnrcz1w4v75bkxq88jmbddljl1";
sha256 = "0spv89di017rg25psiv4w3pn6f67y2w6vv8w910i83b5yii84rl1";
type = "gem";
};
version = "1.8.1";
version = "1.9.1";
};
highline = {
groups = ["default"];
@@ -549,10 +528,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "19hsskzk5zpv14mnf07pq71hfk1fsjwfjcw616pgjjzjbi2f0kxi";
sha256 = "13rilvlv8kwbzqfb644qp6hrbsj82cbqmnzcvqip1p6vqx36sxbk";
type = "gem";
};
version = "1.0.8";
version = "1.0.5";
};
httpclient = {
groups = ["default"];
@@ -570,10 +549,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0k31wcgnvcvd14snz0pfqj976zv6drfsnq6x8acz10fiyms9l8nw";
sha256 = "0qaamqsh5f3szhcakkak8ikxlzxqnv49n2p7504hcz2l0f4nj0wx";
type = "gem";
};
version = "1.14.6";
version = "1.14.1";
};
jmespath = {
groups = ["default"];
@@ -590,31 +569,30 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "048danb0x10mpch6mf88mky35zjn6wk4hpbqq68ssbq58i3fzgfj";
sha256 = "0r9jmjhg2ly3l736flk7r2al47b5c8cayh0gqkq0yhjqzc9a6zhq";
type = "gem";
};
version = "2.9.1";
version = "2.7.1";
};
jwt = {
dependencies = ["base64"];
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1i8wmzgb5nfhvkx1f6bhdwfm7v772172imh439v3xxhkv3hllhp6";
sha256 = "16z11alz13vfc4zs5l3fk6n51n2jw9lskvc4h4prnww0y797qd87";
type = "gem";
};
version = "2.10.1";
version = "2.7.1";
};
mini_magick = {
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1nfxjpmka12ihbwd87d5k2hh7d2pv3aq95x0l2lh8gca1s72bmki";
sha256 = "0slh78f9z6n0l1i2km7m48yz7l4fjrk88sj1f4mh1wb39sl2yc37";
type = "gem";
};
version = "4.13.2";
version = "4.12.0";
};
mini_mime = {
groups = ["default"];
@@ -631,10 +609,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0izrg03wn2yj3gd76ck7ifbm9h2kgy8kpg4fk06ckpy4bbicmwlw";
sha256 = "0bkmfi9mb49m0fkdhl2g38i3xxa02d411gg0m8x0gvbwfmmg5ym3";
type = "gem";
};
version = "5.25.4";
version = "5.20.0";
};
multi_json = {
groups = ["default"];
@@ -651,20 +629,20 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1a5lrlvmg2kb2dhw3lxcsv6x276bwgsxpnka1752082miqxd0wlq";
sha256 = "0lgyysrpl50wgcb9ahg29i4p01z0irb3p9lirygma0kkfr5dgk9x";
type = "gem";
};
version = "2.4.1";
version = "2.3.0";
};
nanaimo = {
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "08q73nchv8cpk28h1sdnf5z6a862fcf4mxy1d58z25xb3dankw7s";
sha256 = "0xi36h3f7nm8bc2k0b6svpda1lyank2gf872lxjbhw3h95hdrbma";
type = "gem";
};
version = "0.4.0";
version = "0.3.0";
};
naturally = {
groups = ["default"];
@@ -676,25 +654,15 @@
};
version = "2.2.1";
};
nkf = {
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "09piyp2pd74klb9wcn0zw4mb5l0k9wzwppxggxi1yi95l2ym3hgv";
type = "gem";
};
version = "0.2.0";
};
optparse = {
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1306kdvq0xr333xma4452zvvvw6mx7fw20fwi6508i6dq5lh9s95";
sha256 = "0j9l5a1zszvrlggp1ldx82i4kkqx34g4g3amwp488s499w5l1cvj";
type = "gem";
};
version = "0.6.0";
version = "0.1.1";
};
os = {
groups = ["default"];
@@ -711,30 +679,30 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0hlaf4b3d8grxm9fqbnam5gwd55wvghl0jyzjd1hc5hirhklaynk";
sha256 = "0wzhnbzraz60paxhm48c50fp9xi7cqka4gfhxmiq43mhgh5ajg3h";
type = "gem";
};
version = "3.7.2";
version = "3.7.0";
};
public_suffix = {
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0vqcw3iwby3yc6avs1vb3gfd0vcp2v7q310665dvxfswmcf4xm31";
sha256 = "1bni4qjrsh2q49pnmmd6if4iv3ak36bd2cckrs6npl111n769k9m";
type = "gem";
};
version = "6.0.1";
version = "5.0.4";
};
rake = {
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "17850wcwkgi30p7yqh60960ypn7yibacjjha0av78zaxwvd3ijs6";
sha256 = "1ilr853hawi09626axx0mps4rkkmxcs54mapz9jnqvpnlwd3wsmy";
type = "gem";
};
version = "13.2.1";
version = "13.1.0";
};
representable = {
dependencies = ["declarative" "trailblazer-option" "uber"];
@@ -762,20 +730,20 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1ch4k2y80r4glr579kxliqnxld2qa91ydq8fiqam38bzpbps3gpg";
sha256 = "05i8518ay14kjbma550mv0jm8a6di8yp5phzrd8rj44z9qnrlrp0";
type = "gem";
};
version = "3.4.0";
version = "3.2.6";
};
rouge = {
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "080fswzii68wnbsg7pgq55ba7p289sqjlxwp4vch0h32qy1f8v8d";
sha256 = "0sfikq1q8xyqqx690iiz7ybhzx87am4w50w8f2nq36l3asw4x89d";
type = "gem";
};
version = "3.28.0";
version = "2.0.7";
};
ruby2_keywords = {
groups = ["default"];
@@ -792,20 +760,20 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "05an0wz87vkmqwcwyh5rjiaavydfn5f4q1lixcsqkphzvj7chxw5";
sha256 = "0grps9197qyxakbpw02pda59v45lfgbgiyw48i0mq9f2bn9y6mrz";
type = "gem";
};
version = "2.4.1";
version = "2.3.2";
};
security = {
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1drkm2wgjazwzj09db1szrllkag036bdvc3dr42fh1kpr877m5rs";
sha256 = "1ryjxs0j66wrbky2c08yf0mllwalvpg12rpxzbdx2rdhj3cbrlxa";
type = "gem";
};
version = "0.1.5";
version = "0.1.3";
};
signet = {
dependencies = ["addressable" "faraday" "jwt" "multi_json"];
@@ -813,10 +781,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0cfxa11wy1nv9slmnzjczkdgld0gqizajsb03rliy53zylwkjzsk";
sha256 = "0fzakk5y7zzii76zlkynpp1c764mzkkfg4mpj18f5pf2xp1aikb6";
type = "gem";
};
version = "0.19.0";
version = "0.18.0";
};
simctl = {
dependencies = ["CFPropertyList" "naturally"];
@@ -829,16 +797,6 @@
};
version = "1.6.10";
};
sysrandom = {
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0x8yryf6migjnkfwr8dxgx1qyzhvajgha60hr5mgfkn65qyarhas";
type = "gem";
};
version = "1.0.5";
};
terminal-notifier = {
groups = ["default"];
platforms = [];
@@ -927,10 +885,20 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0nkz7fadlrdbkf37m0x7sw8bnz8r355q3vwcfb9f9md6pds9h9qj";
sha256 = "1d0azx233nags5jx3fqyr23qa2rhgzbhv8pxp46dgbg1mpf82xky";
type = "gem";
};
version = "2.6.0";
version = "2.5.0";
};
webrick = {
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "13qm7s0gr2pmfcl7dxrmq38asaza4w0i2n9my4yzs499j731wh8r";
type = "gem";
};
version = "1.8.1";
};
word_wrap = {
groups = ["default"];
@@ -948,10 +916,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1lslz1kfb8jnd1ilgg02qx0p0y6yiq8wwk84mgg2ghh58lxsgiwc";
sha256 = "176ndahc5fssyx04q176vy6wngs1av4vrsdrkdpjij700hqll8hn";
type = "gem";
};
version = "1.27.0";
version = "1.23.0";
};
xcpretty = {
dependencies = ["rouge"];
@@ -959,10 +927,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1lbwk77g28jjhin3qjrh7ldfsgf7aszi9j60mp8yz10i3wyqgvqj";
sha256 = "1xq47q2h5llj7b54rws4796904vnnjz7qqnacdv7wlp3gdbwrivm";
type = "gem";
};
version = "0.4.0";
version = "0.3.0";
};
xcpretty-travis-formatter = {
dependencies = ["xcpretty"];
+1 -1
View File
@@ -1 +1 @@
Status: محفظة إيثريوم كريبتو
Status: محفظة تشفير اجتماعية
@@ -6,13 +6,13 @@ SECURE ETHEREUM WALLET
The Status crypto wallet allows you to securely send, store, and exchange Ethereum assets such as ETH, SNT, stable coins such as DAI, as well as collectibles. Confidently take control of your cryptocurrency and digital assets with our multichain Ethereum wallet app, supporting mainnet, Arbitrum, and Optimism. The Status blockchain wallet currently only supports ETH, ERC-20, ERC-721, and ERC-1155 assets; it does not support Bitcoin.
PRIVATE MESSENGER
Send private 1:1 and private group chats without anyone snooping on your communications. Status is a messenger app that eliminates centralized message relays for greater privacy and secure messaging. All messages are encrypted with end-to-end encryption. Additionally, no message exposes who the author or the intended recipient is, so nobody, not even Status, knows who is talking to who or what was said.
Send private 1:1 and private group chats without anyone snooping on your communications. Status is a messenger app that eliminates centralised message relays for greater privacy and secure messaging. All messages are encrypted with end-to-end encryption. Additionally, no message exposes who the author or the intended recipient is, so nobody, not even Status, knows who is talking to who or what was said.
EARN WITH DEFI
Put your crypto to work with the latest decentralized finance apps and decentralized exchanges (DEX) such as Maker, Aave, Uniswap, Synthetix, PoolTogether, Zerion, Kyber, and more.
Put your crypto to work with the latest decentralised finance apps and decentralised exchanges (DEX) such as Maker, Aave, Uniswap, Synthetix, PoolTogether, Zerion, Kyber, and more.
CONNECT WITH YOUR COMMUNITY
Explore, connect, and chat with your favorite communities and friends. Whether it is a small group of friends, an artist collective, crypto traders, or the next big organization - text and communicate with Status communities.
Explore, connect, and chat with your favourite communities and friends. Whether it is a small group of friends, an artist collective, crypto traders, or the next big organization - text and communicate with Status communities.
PRIVATE ACCOUNT CREATION
Stay private with pseudo-anonymous account creation. When creating your free account, you will NEVER have to enter a phone number, email address, or bank account. Your wallet private keys are locally generated and securely stored to ensure only you have access to your funds and financial transactions.

Before

Width:  |  Height:  |  Size: 192 KiB

After

Width:  |  Height:  |  Size: 192 KiB

Before

Width:  |  Height:  |  Size: 272 KiB

After

Width:  |  Height:  |  Size: 272 KiB

Before

Width:  |  Height:  |  Size: 263 KiB

After

Width:  |  Height:  |  Size: 263 KiB

Before

Width:  |  Height:  |  Size: 396 KiB

After

Width:  |  Height:  |  Size: 396 KiB

Before

Width:  |  Height:  |  Size: 222 KiB

After

Width:  |  Height:  |  Size: 222 KiB

Before

Width:  |  Height:  |  Size: 262 KiB

After

Width:  |  Height:  |  Size: 262 KiB

Before

Width:  |  Height:  |  Size: 202 KiB

After

Width:  |  Height:  |  Size: 202 KiB

Before

Width:  |  Height:  |  Size: 425 KiB

After

Width:  |  Height:  |  Size: 425 KiB

@@ -0,0 +1 @@
Status: Social Crypto Wallet
@@ -1 +0,0 @@
Status: Ethereum Crypto Wallet
+1 -1
View File
@@ -1 +1 @@
Status: Billetera Ethereum
Status: Billetera social cripto
+1 -1
View File
@@ -1 +1 @@
Status: Portefeuille Ethereum
Status : Portef. crypto social
+1 -1
View File
@@ -1 +1 @@
Status: イーサリアム クリプト ウォレット
Status: ソーシャル クリプト ウォレット
+1 -1
View File
@@ -1 +1 @@
Status: 이더리움 크립토 지갑
Status: 소셜 크립토 지갑
+1 -1
View File
@@ -1 +1 @@
Status: Carteira Ethereum
Status: Carteira social cripto
+1 -1
View File
@@ -1 +1 @@
Status: Ethereum Криптокошелек
Status: Криптокошелек
+1 -1
View File
@@ -1 +1 @@
Status Ethereum Kripto Cüzdanı
Status: Sosyal Kripto Cüzdanı
+1 -1
View File
@@ -1 +1 @@
Status Ethereum Криптогаманець
Status: Криптогаманець
+1 -1
View File
@@ -1 +1 @@
Status: 以太坊加密钱包
Status: 可以社交的加密货币钱包
+2 -5
View File
@@ -57,12 +57,10 @@ abstract_target 'Status' do
pod 'react-native-config', :path => '../node_modules/react-native-config'
pod 'SSZipArchive', '2.4.3'
# to fix [!] CocoaPods could not find compatible versions for pod "CryptoSwift"
pod 'CryptoSwift', git: "https://github.com/krzyzanowskim/CryptoSwift", tag: '1.8.0'
pod 'TOCropViewController', git: "https://github.com/TimOliver/TOCropViewController", tag: '2.7.4'
pod "react-native-status-keycard", path: "../node_modules/react-native-status-keycard"
pod "react-native-status", path: "../modules/react-native-status"
pod "Keycard", git: "https://github.com/status-im/Keycard.swift.git", tag: '3.1.1'
pod "Keycard", git: "https://github.com/status-im/Keycard.swift.git"
pod 'secp256k1', git: "https://github.com/status-im/secp256k1.swift.git", submodules: true
target 'StatusIm' do
@@ -83,7 +81,6 @@ abstract_target 'Status' do
installer,
config[:reactNativePath],
:mac_catalyst_enabled => false,
# :ccache_enabled => true
)
# some of libs wouldn't be build for x86_64 otherwise and that is
# necessary for ios simulators
+798 -1499
View File
File diff suppressed because it is too large Load Diff
+141 -188
View File
@@ -11,8 +11,7 @@
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
25DC9C9DC25846BD8D084888 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B9A886A2CB448B1ABA0EB62 /* libc++.tbd */; };
33589A5A91A667E83E26A8F1 /* libPods-Status-StatusImPR.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AD2A3A4FBF9C660C720333B9 /* libPods-Status-StatusImPR.a */; };
33A9649BF03D7722C8AD9A94 /* libPods-Status-StatusIm-StatusImTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 346DB175AB93E046EABA70F9 /* libPods-Status-StatusIm-StatusImTests.a */; };
2D32CCEDFF64E1C3F1FB79AF /* libPods-Status-StatusIm-StatusImTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6081A369F49E04EC54F77E1B /* libPods-Status-StatusIm-StatusImTests.a */; };
3870E1E692E24133A80B07DE /* Inter-SemiBold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 693A62DB37BC4CD5A30E5C96 /* Inter-SemiBold.otf */; };
393D26E3080B443A998F4A2F /* Inter-Italic.otf in Resources */ = {isa = PBXBuildFile; fileRef = B07176ACDAA1422E8F0A3D6B /* Inter-Italic.otf */; };
3A2626CF245C3F2200D5F94B /* Dummy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A2626CE245C3F2200D5F94B /* Dummy.swift */; };
@@ -41,13 +40,11 @@
65F6941925780A4F00A45E76 /* Bridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F6941825780A4F00A45E76 /* Bridge.swift */; };
65F6941A25780A4F00A45E76 /* Bridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F6941825780A4F00A45E76 /* Bridge.swift */; };
65F6941B25780A4F00A45E76 /* Bridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F6941825780A4F00A45E76 /* Bridge.swift */; };
6DBB6F41C55D0644766866AF /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 67FDD6C432DA668DFEBF5680 /* PrivacyInfo.xcprivacy */; };
70ADBB5ECF934DCF8A0E4919 /* Inter-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 1426DF592BA248FC81D955CB /* Inter-Regular.otf */; };
715D8132290BE850006F5C88 /* UbuntuMono-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 715D8131290BE850006F5C88 /* UbuntuMono-Regular.ttf */; };
715D8133290BE850006F5C88 /* UbuntuMono-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 715D8131290BE850006F5C88 /* UbuntuMono-Regular.ttf */; };
74B758FC20D7C00B003343C3 /* launch-image-universal.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 74B758FB20D7C00B003343C3 /* launch-image-universal.storyboard */; };
8391E8E0E93C41A98AAA6631 /* Inter-SemiBoldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = A4F2BBE8D4DD4140A6CCAC39 /* Inter-SemiBoldItalic.otf */; };
8FDFD85E9A738F5987881331 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = DE9F1F0F747EAF43F5B4200D /* PrivacyInfo.xcprivacy */; };
B24FC7FD1DE7195700D694FF /* Social.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B24FC7FC1DE7195700D694FF /* Social.framework */; };
B24FC7FF1DE7195F00D694FF /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B24FC7FE1DE7195F00D694FF /* MessageUI.framework */; };
B2F2D1BC1D9D531B00B7B453 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B2F2D1BB1D9D531B00B7B453 /* Images.xcassets */; };
@@ -59,10 +56,11 @@
C1715FFB29C0BCE50088FA8B /* launch-icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = C14C5F8C29C0A149005C58A7 /* launch-icon@3x.png */; };
C1715FFC29C0BCE80088FA8B /* launch-icon.png in Resources */ = {isa = PBXBuildFile; fileRef = C14C5F9229C0ADB5005C58A7 /* launch-icon.png */; };
CE4E31B31D8695250033ED64 /* Statusgo.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE4E31B21D8695250033ED64 /* Statusgo.xcframework */; };
CFCC1602CE7DA2FD62562C83 /* libPods-Status-StatusIm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E01C76163FA5943BA4FCED5 /* libPods-Status-StatusIm.a */; };
D1786306E0184916B11F4C37 /* Inter-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = B2A38FC3D3954DE7B2B171F8 /* Inter-Medium.otf */; };
D791AB0467C983D226FF5713 /* libPods-Status-StatusIm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E42DDCDBECE60E763EAA5042 /* libPods-Status-StatusIm.a */; };
D84616FB563A48EBB1678699 /* Inter-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = CD4A2C27D6D5473184DC1F7E /* Inter-Bold.otf */; };
D99C50E5E18942A39C8DDF61 /* Inter-BoldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = B321D25F4493470980039457 /* Inter-BoldItalic.otf */; };
F9C9188A9398D58C286A2F4B /* libPods-Status-StatusImPR.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C929A693823978C12D329338 /* libPods-Status-StatusImPR.a */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -116,48 +114,46 @@
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = StatusIm/Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = StatusIm/main.m; sourceTree = "<group>"; };
1426DF592BA248FC81D955CB /* Inter-Regular.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-Regular.otf"; path = "../resources/fonts/Inter-Regular.otf"; sourceTree = "<group>"; };
346DB175AB93E046EABA70F9 /* libPods-Status-StatusIm-StatusImTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Status-StatusIm-StatusImTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
203C46547A6E99D27529A8AA /* Pods-Status-StatusIm-StatusImTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusIm-StatusImTests.release.xcconfig"; path = "Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests.release.xcconfig"; sourceTree = "<group>"; };
24F63BCFEB33B4C969305A46 /* Pods-Status-StatusIm.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusIm.debug.xcconfig"; path = "Target Support Files/Pods-Status-StatusIm/Pods-Status-StatusIm.debug.xcconfig"; sourceTree = "<group>"; };
344F43B59CCE090C3271FF08 /* Pods-Status-StatusIm.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusIm.release.xcconfig"; path = "Target Support Files/Pods-Status-StatusIm/Pods-Status-StatusIm.release.xcconfig"; sourceTree = "<group>"; };
3A2626CE245C3F2200D5F94B /* Dummy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dummy.swift; sourceTree = "<group>"; };
3A6406FB24A3ADF90046ED37 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
3A8F8EA924A4D31600BF206D /* GameKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameKit.framework; path = System/Library/Frameworks/GameKit.framework; sourceTree = SDKROOT; };
3AAD2ADC24A3A60E0075D594 /* Status PR.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Status PR.app"; sourceTree = BUILT_PRODUCTS_DIR; };
3AB1C3AD245C043900098F67 /* StatusIm-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "StatusIm-Bridging-Header.h"; sourceTree = "<group>"; };
415E72A662B5ABF086AB7D7B /* Pods-Status-StatusImPR.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusImPR.release.xcconfig"; path = "Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR.release.xcconfig"; sourceTree = "<group>"; };
4C16DE0B1F89508700AA10DB /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
4E586E1B0E544F64AA9F5BD1 /* libz.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
59C3DE709E21DF59F3163C5B /* Pods-Status-StatusIm-StatusImTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusIm-StatusImTests.debug.xcconfig"; path = "Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests.debug.xcconfig"; sourceTree = "<group>"; };
6081A369F49E04EC54F77E1B /* libPods-Status-StatusIm-StatusImTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Status-StatusIm-StatusImTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
65F693BD2578002500A45E76 /* CoreNFC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreNFC.framework; path = System/Library/Frameworks/CoreNFC.framework; sourceTree = SDKROOT; };
65F693BF2578003600A45E76 /* CoreNFC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreNFC.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk/System/iOSSupport/System/Library/Frameworks/CoreNFC.framework; sourceTree = DEVELOPER_DIR; };
65F6941725780A4E00A45E76 /* StatusImTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "StatusImTests-Bridging-Header.h"; sourceTree = "<group>"; };
65F6941825780A4F00A45E76 /* Bridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bridge.swift; sourceTree = "<group>"; };
67FDD6C432DA668DFEBF5680 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = StatusIm/PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
693A62DB37BC4CD5A30E5C96 /* Inter-SemiBold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-SemiBold.otf"; path = "../resources/fonts/Inter-SemiBold.otf"; sourceTree = "<group>"; };
70748FF05FFD3CACB6F64CE0 /* Pods-Status-StatusImPR.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusImPR.debug.xcconfig"; path = "Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR.debug.xcconfig"; sourceTree = "<group>"; };
715D8131290BE850006F5C88 /* UbuntuMono-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "UbuntuMono-Regular.ttf"; path = "../resources/fonts/UbuntuMono-Regular.ttf"; sourceTree = "<group>"; };
74B758FB20D7C00B003343C3 /* launch-image-universal.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = "launch-image-universal.storyboard"; sourceTree = "<group>"; };
8B9A886A2CB448B1ABA0EB62 /* libc++.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
922C4CA61F4D5F8B0033C753 /* StatusIm.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = StatusIm.entitlements; path = StatusIm/StatusIm.entitlements; sourceTree = "<group>"; };
9C76AF5A418D4D65A4CAD1D9 /* InterStatus-Regular.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "InterStatus-Regular.otf"; path = "../resources/fonts/InterStatus-Regular.otf"; sourceTree = "<group>"; };
9E01C76163FA5943BA4FCED5 /* libPods-Status-StatusIm.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Status-StatusIm.a"; sourceTree = BUILT_PRODUCTS_DIR; };
9EC0135C1E06FB1900155B5C /* RCTWKWebView.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWKWebView.xcodeproj; path = "../node_modules/react-native-wkwebview-reborn/ios/RCTWKWebView.xcodeproj"; sourceTree = "<group>"; };
A4F2BBE8D4DD4140A6CCAC39 /* Inter-SemiBoldItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-SemiBoldItalic.otf"; path = "../resources/fonts/Inter-SemiBoldItalic.otf"; sourceTree = "<group>"; };
AD2A3A4FBF9C660C720333B9 /* libPods-Status-StatusImPR.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Status-StatusImPR.a"; sourceTree = BUILT_PRODUCTS_DIR; };
AE688642BED459D924D638C9 /* Pods-Status-StatusIm.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusIm.release.xcconfig"; path = "Target Support Files/Pods-Status-StatusIm/Pods-Status-StatusIm.release.xcconfig"; sourceTree = "<group>"; };
B07176ACDAA1422E8F0A3D6B /* Inter-Italic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-Italic.otf"; path = "../resources/fonts/Inter-Italic.otf"; sourceTree = "<group>"; };
B24FC7FC1DE7195700D694FF /* Social.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Social.framework; path = System/Library/Frameworks/Social.framework; sourceTree = SDKROOT; };
B24FC7FE1DE7195F00D694FF /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; };
B2A38FC3D3954DE7B2B171F8 /* Inter-Medium.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-Medium.otf"; path = "../resources/fonts/Inter-Medium.otf"; sourceTree = "<group>"; };
B2F2D1BB1D9D531B00B7B453 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = StatusIm/Images.xcassets; sourceTree = "<group>"; };
B321D25F4493470980039457 /* Inter-BoldItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-BoldItalic.otf"; path = "../resources/fonts/Inter-BoldItalic.otf"; sourceTree = "<group>"; };
B5908EC87D7D3CF5C59076E4 /* Pods-Status-StatusIm-StatusImTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusIm-StatusImTests.release.xcconfig"; path = "Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests.release.xcconfig"; sourceTree = "<group>"; };
C14C5F8C29C0A149005C58A7 /* launch-icon@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "launch-icon@3x.png"; path = "StatusIm/launch-icon@3x.png"; sourceTree = "<group>"; };
C14C5F9029C0AD9C005C58A7 /* launch-icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "launch-icon@2x.png"; path = "StatusIm/launch-icon@2x.png"; sourceTree = "<group>"; };
C14C5F9229C0ADB5005C58A7 /* launch-icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "launch-icon.png"; path = "StatusIm/launch-icon.png"; sourceTree = "<group>"; };
C6B1215047604CD59A4C74D6 /* Inter-MediumItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-MediumItalic.otf"; path = "../resources/fonts/Inter-MediumItalic.otf"; sourceTree = "<group>"; };
C929A693823978C12D329338 /* libPods-Status-StatusImPR.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Status-StatusImPR.a"; sourceTree = BUILT_PRODUCTS_DIR; };
CD4A2C27D6D5473184DC1F7E /* Inter-Bold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-Bold.otf"; path = "../resources/fonts/Inter-Bold.otf"; sourceTree = "<group>"; };
CE4E31B21D8695250033ED64 /* Statusgo.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Statusgo.xcframework; path = "../modules/react-native-status/ios/RCTStatus/Statusgo.xcframework"; sourceTree = "<group>"; };
D4B4396706812C0485C86536 /* Pods-Status-StatusImPR.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusImPR.release.xcconfig"; path = "Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR.release.xcconfig"; sourceTree = "<group>"; };
DE9F1F0F747EAF43F5B4200D /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = ../StatusIm/PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
F73447C82A1342C8A6E3D99B /* Pods-Status-StatusImPR.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusImPR.debug.xcconfig"; path = "Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR.debug.xcconfig"; sourceTree = "<group>"; };
FF6D68169B80BA9EF9BB9FF9 /* Pods-Status-StatusIm.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusIm.debug.xcconfig"; path = "Target Support Files/Pods-Status-StatusIm/Pods-Status-StatusIm.debug.xcconfig"; sourceTree = "<group>"; };
E42DDCDBECE60E763EAA5042 /* libPods-Status-StatusIm.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Status-StatusIm.a"; sourceTree = BUILT_PRODUCTS_DIR; };
F12F9820A9DF3FE08C615B90 /* Pods-Status-StatusIm-StatusImTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusIm-StatusImTests.debug.xcconfig"; path = "Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -165,7 +161,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
33A9649BF03D7722C8AD9A94 /* libPods-Status-StatusIm-StatusImTests.a in Frameworks */,
2D32CCEDFF64E1C3F1FB79AF /* libPods-Status-StatusIm-StatusImTests.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -178,7 +174,7 @@
CE4E31B31D8695250033ED64 /* Statusgo.xcframework in Frameworks */,
25DC9C9DC25846BD8D084888 /* libc++.tbd in Frameworks */,
BA68A2377A20496EA737000D /* libz.tbd in Frameworks */,
CFCC1602CE7DA2FD62562C83 /* libPods-Status-StatusIm.a in Frameworks */,
D791AB0467C983D226FF5713 /* libPods-Status-StatusIm.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -192,7 +188,7 @@
3AAD2AC224A3A60E0075D594 /* Statusgo.xcframework in Frameworks */,
3AAD2AC524A3A60E0075D594 /* libc++.tbd in Frameworks */,
3AAD2AC624A3A60E0075D594 /* libz.tbd in Frameworks */,
33589A5A91A667E83E26A8F1 /* libPods-Status-StatusImPR.a in Frameworks */,
F9C9188A9398D58C286A2F4B /* libPods-Status-StatusImPR.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -231,7 +227,6 @@
13B07FB71A68108700A75B9A /* main.m */,
3AB1C3AD245C043900098F67 /* StatusIm-Bridging-Header.h */,
3A2626CE245C3F2200D5F94B /* Dummy.swift */,
67FDD6C432DA668DFEBF5680 /* PrivacyInfo.xcprivacy */,
);
name = StatusIm;
sourceTree = "<group>";
@@ -258,7 +253,6 @@
isa = PBXGroup;
children = (
3A6406FB24A3ADF90046ED37 /* Info.plist */,
DE9F1F0F747EAF43F5B4200D /* PrivacyInfo.xcprivacy */,
);
path = StatusImPR;
sourceTree = "<group>";
@@ -320,9 +314,9 @@
CE4E31B21D8695250033ED64 /* Statusgo.xcframework */,
8B9A886A2CB448B1ABA0EB62 /* libc++.tbd */,
4E586E1B0E544F64AA9F5BD1 /* libz.tbd */,
9E01C76163FA5943BA4FCED5 /* libPods-Status-StatusIm.a */,
346DB175AB93E046EABA70F9 /* libPods-Status-StatusIm-StatusImTests.a */,
AD2A3A4FBF9C660C720333B9 /* libPods-Status-StatusImPR.a */,
E42DDCDBECE60E763EAA5042 /* libPods-Status-StatusIm.a */,
6081A369F49E04EC54F77E1B /* libPods-Status-StatusIm-StatusImTests.a */,
C929A693823978C12D329338 /* libPods-Status-StatusImPR.a */,
);
name = Frameworks;
sourceTree = "<group>";
@@ -330,12 +324,12 @@
D0D5C8D06825D33BA2D2121E /* Pods */ = {
isa = PBXGroup;
children = (
FF6D68169B80BA9EF9BB9FF9 /* Pods-Status-StatusIm.debug.xcconfig */,
AE688642BED459D924D638C9 /* Pods-Status-StatusIm.release.xcconfig */,
59C3DE709E21DF59F3163C5B /* Pods-Status-StatusIm-StatusImTests.debug.xcconfig */,
B5908EC87D7D3CF5C59076E4 /* Pods-Status-StatusIm-StatusImTests.release.xcconfig */,
F73447C82A1342C8A6E3D99B /* Pods-Status-StatusImPR.debug.xcconfig */,
D4B4396706812C0485C86536 /* Pods-Status-StatusImPR.release.xcconfig */,
24F63BCFEB33B4C969305A46 /* Pods-Status-StatusIm.debug.xcconfig */,
344F43B59CCE090C3271FF08 /* Pods-Status-StatusIm.release.xcconfig */,
F12F9820A9DF3FE08C615B90 /* Pods-Status-StatusIm-StatusImTests.debug.xcconfig */,
203C46547A6E99D27529A8AA /* Pods-Status-StatusIm-StatusImTests.release.xcconfig */,
70748FF05FFD3CACB6F64CE0 /* Pods-Status-StatusImPR.debug.xcconfig */,
415E72A662B5ABF086AB7D7B /* Pods-Status-StatusImPR.release.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
@@ -347,12 +341,12 @@
isa = PBXNativeTarget;
buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "StatusImTests" */;
buildPhases = (
F676C31E1D44D1BD4576B503 /* [CP] Check Pods Manifest.lock */,
D357C5313A85261FF3DAB74E /* [CP] Check Pods Manifest.lock */,
00E356EA1AD99517003FC87E /* Sources */,
00E356EB1AD99517003FC87E /* Frameworks */,
00E356EC1AD99517003FC87E /* Resources */,
80152ACDD81CE8E1680DDE4F /* [CP] Embed Pods Frameworks */,
1BEC29FB652F8E038962FCF8 /* [CP] Copy Pods Resources */,
36051AE6B742BD851884AB9D /* [CP] Embed Pods Frameworks */,
3506F0F77B5DE03815A5414A /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -368,15 +362,15 @@
isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "StatusIm" */;
buildPhases = (
F711D2C4BC11EA6E45C3CE7A /* [CP] Check Pods Manifest.lock */,
D47DE8479514FAAC6B26ACD2 /* [CP] Check Pods Manifest.lock */,
13B07F871A680F5B00A75B9A /* Sources */,
13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */,
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
20B6B6891D92C42700CC5C6A /* Embed Frameworks */,
E3914A731DF919ED00EBB515 /* Run Script */,
576C124BF9B0B4545F72B9DB /* [CP] Embed Pods Frameworks */,
99E5FF43F591A0EE44848FE0 /* [CP] Copy Pods Resources */,
82219E0CC0028DA612FCC0E3 /* [CP] Embed Pods Frameworks */,
389504FC147AAF0616332C3A /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -391,15 +385,15 @@
isa = PBXNativeTarget;
buildConfigurationList = 3AAD2AD924A3A60E0075D594 /* Build configuration list for PBXNativeTarget "StatusImPR" */;
buildPhases = (
1A2DE106725880C6A07F695F /* [CP] Check Pods Manifest.lock */,
E507D5CEF6BDEB9FBEBFA1C3 /* [CP] Check Pods Manifest.lock */,
3AAD2ABB24A3A60E0075D594 /* Sources */,
3AAD2ABF24A3A60E0075D594 /* Frameworks */,
3AAD2AC924A3A60E0075D594 /* Resources */,
3AAD2AD524A3A60E0075D594 /* Bundle React Native code and images */,
3AAD2AD624A3A60E0075D594 /* Embed Frameworks */,
3AAD2AD724A3A60E0075D594 /* Run Script */,
FF3E0F53E44C187FBDB0ADE3 /* [CP] Embed Pods Frameworks */,
7DC89E6871F5A5F7A2278E03 /* [CP] Copy Pods Resources */,
13D9129EE9E3EFD2436F82FD /* [CP] Embed Pods Frameworks */,
E374B6B7AF37774C15097B39 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -511,7 +505,6 @@
3870E1E692E24133A80B07DE /* Inter-SemiBold.otf in Resources */,
8391E8E0E93C41A98AAA6631 /* Inter-SemiBoldItalic.otf in Resources */,
C14C5F8D29C0A149005C58A7 /* launch-icon@3x.png in Resources */,
6DBB6F41C55D0644766866AF /* PrivacyInfo.xcprivacy in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -534,7 +527,6 @@
3AAD2AD324A3A60E0075D594 /* Inter-SemiBold.otf in Resources */,
3AAD2AD424A3A60E0075D594 /* Inter-SemiBoldItalic.otf in Resources */,
C1715FFB29C0BCE50088FA8B /* launch-icon@3x.png in Resources */,
8FDFD85E9A738F5987881331 /* PrivacyInfo.xcprivacy in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -555,62 +547,90 @@
shellPath = "/usr/bin/env sh";
shellScript = "set -o errexit\nexport NODE_BINARY=\"${NODE_BINARY:-node}\"\nexport NODE_ARGS=\"${NODE_ARGS:- --max-old-space-size=16384 }\"\n\n\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n";
};
1A2DE106725880C6A07F695F /* [CP] Check Pods Manifest.lock */ = {
13D9129EE9E3EFD2436F82FD /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR-frameworks.sh",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Status-StatusImPR-checkManifestLockResult.txt",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
1BEC29FB652F8E038962FCF8 /* [CP] Copy Pods Resources */ = {
3506F0F77B5DE03815A5414A /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/RCT-Folly/RCT-Folly_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/RNImageCropPickerPrivacyInfo.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNPermissions/RNPermissionsPrivacyInfo.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/React-Core_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact/React-cxxreact_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/boost/boost_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/glog/glog_privacy.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCT-Folly_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNImageCropPickerPrivacyInfo.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNPermissionsPrivacyInfo.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-Core_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-cxxreact_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/boost_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/glog_privacy.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
36051AE6B742BD851884AB9D /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests-frameworks.sh",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
389504FC147AAF0616332C3A /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm/Pods-Status-StatusIm-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNPermissions/RNPermissionsPrivacyInfo.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNPermissionsPrivacyInfo.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm/Pods-Status-StatusIm-resources.sh\"\n";
showEnvVarsInLog = 0;
};
3AAD2AD524A3A60E0075D594 /* Bundle React Native code and images */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -639,7 +659,7 @@
shellPath = "/usr/bin/env sh";
shellScript = "\"${PROJECT_DIR}/scripts/set_xcode_version.sh\" > ../logs/set_xcode_version.log 2>&1\n";
};
576C124BF9B0B4545F72B9DB /* [CP] Embed Pods Frameworks */ = {
82219E0CC0028DA612FCC0E3 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -657,107 +677,7 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm/Pods-Status-StatusIm-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
7DC89E6871F5A5F7A2278E03 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/RCT-Folly/RCT-Folly_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/RNImageCropPickerPrivacyInfo.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNPermissions/RNPermissionsPrivacyInfo.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/React-Core_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact/React-cxxreact_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/boost/boost_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/glog/glog_privacy.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCT-Folly_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNImageCropPickerPrivacyInfo.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNPermissionsPrivacyInfo.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-Core_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-cxxreact_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/boost_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/glog_privacy.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR-resources.sh\"\n";
showEnvVarsInLog = 0;
};
80152ACDD81CE8E1680DDE4F /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests-frameworks.sh",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
99E5FF43F591A0EE44848FE0 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm/Pods-Status-StatusIm-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/RCT-Folly/RCT-Folly_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/RNImageCropPickerPrivacyInfo.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNPermissions/RNPermissionsPrivacyInfo.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/React-Core_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact/React-cxxreact_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/boost/boost_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/glog/glog_privacy.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCT-Folly_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNImageCropPickerPrivacyInfo.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNPermissionsPrivacyInfo.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-Core_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-cxxreact_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/boost_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/glog_privacy.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm/Pods-Status-StatusIm-resources.sh\"\n";
showEnvVarsInLog = 0;
};
E3914A731DF919ED00EBB515 /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 8;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 1;
shellPath = "/usr/bin/env sh";
shellScript = "\"${PROJECT_DIR}/scripts/set_xcode_version.sh\" > ../logs/set_xcode_version.log 2>&1\n";
};
F676C31E1D44D1BD4576B503 /* [CP] Check Pods Manifest.lock */ = {
D357C5313A85261FF3DAB74E /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -779,7 +699,7 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
F711D2C4BC11EA6E45C3CE7A /* [CP] Check Pods Manifest.lock */ = {
D47DE8479514FAAC6B26ACD2 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -801,22 +721,64 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
FF3E0F53E44C187FBDB0ADE3 /* [CP] Embed Pods Frameworks */ = {
E374B6B7AF37774C15097B39 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR-frameworks.sh",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
"${PODS_ROOT}/Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNPermissions/RNPermissionsPrivacyInfo.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle",
);
name = "[CP] Embed Pods Frameworks";
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNPermissionsPrivacyInfo.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR-frameworks.sh\"\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR-resources.sh\"\n";
showEnvVarsInLog = 0;
};
E3914A731DF919ED00EBB515 /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 8;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 1;
shellPath = "/usr/bin/env sh";
shellScript = "\"${PROJECT_DIR}/scripts/set_xcode_version.sh\" > ../logs/set_xcode_version.log 2>&1\n";
};
E507D5CEF6BDEB9FBEBFA1C3 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Status-StatusImPR-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
@@ -866,7 +828,7 @@
/* Begin XCBuildConfiguration section */
00E356F61AD99517003FC87E /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 59C3DE709E21DF59F3163C5B /* Pods-Status-StatusIm-StatusImTests.debug.xcconfig */;
baseConfigurationReference = F12F9820A9DF3FE08C615B90 /* Pods-Status-StatusIm-StatusImTests.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_ID_SUFFIX = .debug;
@@ -903,7 +865,7 @@
};
00E356F71AD99517003FC87E /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = B5908EC87D7D3CF5C59076E4 /* Pods-Status-StatusIm-StatusImTests.release.xcconfig */;
baseConfigurationReference = 203C46547A6E99D27529A8AA /* Pods-Status-StatusIm-StatusImTests.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_ID_SUFFIX = "";
@@ -936,7 +898,7 @@
};
13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = FF6D68169B80BA9EF9BB9FF9 /* Pods-Status-StatusIm.debug.xcconfig */;
baseConfigurationReference = 24F63BCFEB33B4C969305A46 /* Pods-Status-StatusIm.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon$(BUNDLE_ID_SUFFIX)";
BUNDLE_ID_SUFFIX = .debug;
@@ -1018,7 +980,7 @@
};
13B07F951A680F5B00A75B9A /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = AE688642BED459D924D638C9 /* Pods-Status-StatusIm.release.xcconfig */;
baseConfigurationReference = 344F43B59CCE090C3271FF08 /* Pods-Status-StatusIm.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon$(BUNDLE_ID_SUFFIX)";
BUNDLE_ID_SUFFIX = "";
@@ -1093,7 +1055,7 @@
};
3AAD2ADA24A3A60E0075D594 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = F73447C82A1342C8A6E3D99B /* Pods-Status-StatusImPR.debug.xcconfig */;
baseConfigurationReference = 70748FF05FFD3CACB6F64CE0 /* Pods-Status-StatusImPR.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon$(BUNDLE_ID_SUFFIX)";
BUNDLE_ID_SUFFIX = .debug;
@@ -1173,7 +1135,7 @@
};
3AAD2ADB24A3A60E0075D594 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = D4B4396706812C0485C86536 /* Pods-Status-StatusImPR.release.xcconfig */;
baseConfigurationReference = 415E72A662B5ABF086AB7D7B /* Pods-Status-StatusImPR.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIconPR$(BUNDLE_ID_SUFFIX)";
BUNDLE_ID_SUFFIX = "";
@@ -1249,7 +1211,6 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ALWAYS_SEARCH_USER_PATHS = NO;
CC = "";
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++20";
CLANG_CXX_LIBRARY = "libc++";
@@ -1278,7 +1239,6 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
COPY_PHASE_STRIP = NO;
CXX = "";
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 8B5X2M6H2Y;
ENABLE_BITCODE = NO;
@@ -1318,8 +1278,6 @@
"$(SRCROOT)/../node_modules/react-native-lottie-splash-screen/ios/**",
);
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
LD = "";
LDPLUSPLUS = "";
LIBRARY_SEARCH_PATHS = (
"$(SDKROOT)/usr/lib/swift",
"\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
@@ -1342,7 +1300,6 @@
OTHER_LDFLAGS = "$(inherited)";
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG";
USE_HERMES = true;
VALID_ARCHS = arm64;
"VALID_ARCHS[sdk=iphonesimulator*]" = x86_64;
@@ -1354,7 +1311,6 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ALWAYS_SEARCH_USER_PATHS = NO;
CC = "";
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++20";
CLANG_CXX_LIBRARY = "libc++";
@@ -1383,7 +1339,6 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
COPY_PHASE_STRIP = YES;
CXX = "";
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 8B5X2M6H2Y;
ENABLE_BITCODE = NO;
@@ -1414,8 +1369,6 @@
"$(SRCROOT)/../node_modules/react-native-lottie-splash-screen/ios/**",
);
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
LD = "";
LDPLUSPLUS = "";
LIBRARY_SEARCH_PATHS = (
"$(SDKROOT)/usr/lib/swift",
"\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
+2 -2
View File
@@ -107,10 +107,10 @@ extern "C" NSString* StatusgoImageServerTLSCert();
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
return [self bundleURL];
return [self getBundleURL];
}
- (NSURL *)bundleURL
- (NSURL *)getBundleURL
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
+1 -1
View File
@@ -117,7 +117,7 @@
<string>launch-image-universal</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
-38
View File
@@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>3B52.1</string>
<string>C617.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>35F9.1</string>
</array>
</dict>
</array>
<key>NSPrivacyCollectedDataTypes</key>
<array/>
<key>NSPrivacyTracking</key>
<false/>
</dict>
</plist>
+1 -1
View File
@@ -26,4 +26,4 @@ These log files are uploaded to Jenkins as CI job artifacts on failure using `ar
* `set_xcode_version.log` - Output from `node_modules/react-native/scripts/react-native-xcode.sh`.
- Created by redirecting output of `shellScript` in `ios/StatusIm.xcodeproj/project.pbxproj` for "Run Script" build Phase.
* `Status PR-StatusImPR.log - Created by [Fastlane Gym](https://docs.fastlane.tools/actions/gym/).
- Configured via [`Fastfile`](../Fastfile) using `buildlog_path` argument for `build_ios_app`.
- Configred via [`Fastfile`](../Fastfile) using `buildlog_path` argument for `build_ios_app`.
+1 -1
View File
@@ -1,7 +1,7 @@
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
/**
* Metro configuration
* https://reactnative.dev/docs/metro
* https://facebook.github.io/metro/docs/configuration
*
* @type {import('metro-config').MetroConfig}
*/
@@ -203,6 +203,24 @@ class AccountManager(private val reactContext: ReactApplicationContext) : ReactC
)
}
@ReactMethod
fun verify(address: String, password: String, callback: Callback) {
val absRootDirPath = utils.getNoBackupDirectory()
val newKeystoreDir = utils.pathCombine(absRootDirPath, "keystore")
val jsonParams = JSONObject()
jsonParams.put("keyStoreDir", newKeystoreDir)
jsonParams.put("address", address)
jsonParams.put("password", password)
StatusBackendClient.executeStatusGoRequestWithCallback(
endpoint = "VerifyAccountPasswordV2",
requestBody = jsonParams.toString(),
statusgoFunction = { Statusgo.verifyAccountPasswordV2(jsonParams.toString()) },
callback
)
}
@ReactMethod
fun verifyDatabasePassword(keyUID: String, password: String, callback: Callback) {
val jsonParams = JSONObject()
@@ -230,14 +248,10 @@ class AccountManager(private val reactContext: ReactApplicationContext) : ReactC
@ReactMethod
private fun initializeApplication(request: String, callback: Callback) {
Log.d(TAG, "initializeApplication")
val jsonParams = JSONObject(request)
// for ios, the log dir will be the same as the root data dir, status-go will default to root data dir if logDir is not provided
jsonParams.put("logDir", utils.getPublicStorageDirectory()?.absolutePath)
val jsonString = jsonParams.toString()
StatusBackendClient.executeStatusGoRequestWithCallback(
"InitializeApplication",
jsonString,
{ Statusgo.initializeApplication(jsonString) },
request,
{ Statusgo.initializeApplication(request) },
callback
)
}
@@ -0,0 +1,297 @@
package im.status.ethereum.module;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.Callback;
import android.util.Log;
import statusgo.Statusgo;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.function.Function;
import android.app.Activity;
import android.view.WindowManager;
import android.os.Build;
import android.view.Window;
import android.preference.PreferenceManager;
import android.content.SharedPreferences;
public class EncryptionUtils extends ReactContextBaseJavaModule {
private static final String TAG = "EncryptionUtils";
private ReactApplicationContext reactContext;
private Utils utils;
public EncryptionUtils(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
this.utils = new Utils(reactContext);
}
@Override
public String getName() {
return "EncryptionUtils";
}
@ReactMethod
private void initKeystore(final String keyUID, final Callback callback) throws JSONException {
Log.d(TAG, "initKeystore");
final String commonKeydir = this.utils.pathCombine(this.utils.getNoBackupDirectory(), "/keystore");
final String keydir = this.utils.pathCombine(commonKeydir, keyUID);
StatusBackendClient.executeStatusGoRequestWithCallback(
"InitKeystore",
keydir,
() -> Statusgo.initKeystore(keydir),
callback
);
}
@ReactMethod
public void reEncryptDbAndKeystore(final String keyUID, final String password, final String newPassword, final Callback callback) throws JSONException {
JSONObject params = new JSONObject();
params.put("keyUID", keyUID);
params.put("oldPassword", password);
params.put("newPassword", newPassword);
String jsonParams = params.toString();
StatusBackendClient.executeStatusGoRequestWithCallback(
"ChangeDatabasePasswordV2",
jsonParams,
() -> Statusgo.changeDatabasePasswordV2(jsonParams),
callback
);
}
@ReactMethod
public void convertToKeycardAccount(final String keyUID, final String accountData, final String options, final String keycardUID, final String password,
final String newPassword, final Callback callback) throws JSONException {
final String keyStoreDir = this.utils.getKeyStorePath(keyUID);
JSONObject params = new JSONObject();
params.put("keyUID", keyUID);
params.put("account", new JSONObject(accountData));
params.put("settings", new JSONObject(options));
params.put("keycardUID", keycardUID);
params.put("oldPassword", password);
params.put("newPassword", newPassword);
final String jsonParams = params.toString();
StatusBackendClient.executeStatusGoRequest(
"InitKeystore",
keyStoreDir,
() -> Statusgo.initKeystore(keyStoreDir)
);
StatusBackendClient.executeStatusGoRequestWithCallback(
"ConvertToKeycardAccountV2",
jsonParams,
() -> Statusgo.convertToKeycardAccountV2(jsonParams),
callback
);
}
@ReactMethod(isBlockingSynchronousMethod = true)
public String encodeTransfer(final String to, final String value) {
try {
JSONObject params = new JSONObject();
params.put("to", to);
params.put("value", value);
String jsonParams = params.toString();
return StatusBackendClient.executeStatusGoRequestWithResult(
"EncodeTransferV2",
jsonParams,
() -> Statusgo.encodeTransferV2(jsonParams)
);
} catch (JSONException e) {
Log.e(TAG, "Error creating JSON for encodeTransfer: " + e.getMessage());
return null;
}
}
@ReactMethod(isBlockingSynchronousMethod = true)
public String encodeFunctionCall(final String method, final String paramsJSON) {
try {
JSONObject params = new JSONObject();
params.put("method", method);
params.put("paramsJSON", new JSONObject(paramsJSON));
String jsonString = params.toString();
return StatusBackendClient.executeStatusGoRequestWithResult(
"EncodeFunctionCallV2",
jsonString,
() -> Statusgo.encodeFunctionCallV2(jsonString)
);
} catch (JSONException e) {
Log.e(TAG, "Error creating JSON for encodeFunctionCall: " + e.getMessage());
return null;
}
}
@ReactMethod(isBlockingSynchronousMethod = true)
public String decodeParameters(final String decodeParamJSON) {
return StatusBackendClient.executeStatusGoRequestWithResult(
"DecodeParameters",
decodeParamJSON,
() -> Statusgo.decodeParameters(decodeParamJSON)
);
}
@ReactMethod(isBlockingSynchronousMethod = true)
public String hexToNumber(final String hex) {
return StatusBackendClient.executeStatusGoRequestWithResult(
"HexToNumber",
hex,
() -> Statusgo.hexToNumber(hex)
);
}
@ReactMethod(isBlockingSynchronousMethod = true)
public String numberToHex(final String numString) {
return StatusBackendClient.executeStatusGoRequestWithResult(
"NumberToHex",
numString,
() -> Statusgo.numberToHex(numString)
);
}
@ReactMethod(isBlockingSynchronousMethod = true)
public String sha3(final String str) {
return StatusBackendClient.executeStatusGoRequestWithResult(
"Sha3",
str,
() -> Statusgo.sha3(str)
);
}
@ReactMethod(isBlockingSynchronousMethod = true)
public String utf8ToHex(final String str) {
return StatusBackendClient.executeStatusGoRequestWithResult(
"Utf8ToHex",
str,
() -> Statusgo.utf8ToHex(str)
);
}
@ReactMethod(isBlockingSynchronousMethod = true)
public String hexToUtf8(final String str) {
return StatusBackendClient.executeStatusGoRequestWithResult(
"HexToUtf8",
str,
() -> Statusgo.hexToUtf8(str)
);
}
@ReactMethod(isBlockingSynchronousMethod = true)
public String serializeLegacyKey(final String publicKey) {
return StatusBackendClient.executeStatusGoRequestWithResult(
"SerializeLegacyKey",
publicKey,
() -> Statusgo.serializeLegacyKey(publicKey)
);
}
@ReactMethod
public void setBlankPreviewFlag(final Boolean blankPreview) {
final SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this.reactContext);
sharedPrefs.edit().putBoolean("BLANK_PREVIEW", blankPreview).commit();
setSecureFlag();
}
private void setSecureFlag() {
final SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this.reactContext);
final boolean setSecure = sharedPrefs.getBoolean("BLANK_PREVIEW", true);
final Activity activity = this.reactContext.getCurrentActivity();
if (activity != null) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
final Window window = activity.getWindow();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && setSecure) {
window.addFlags(WindowManager.LayoutParams.FLAG_SECURE);
} else {
window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
}
}
});
}
}
@ReactMethod
public void hashTransaction(final String txArgsJSON, final Callback callback) throws JSONException {
StatusBackendClient.executeStatusGoRequestWithCallback(
"HashTransaction",
txArgsJSON,
() -> Statusgo.hashTransaction(txArgsJSON),
callback
);
}
@ReactMethod
public void hashMessage(final String message, final Callback callback) throws JSONException {
StatusBackendClient.executeStatusGoRequestWithCallback(
"HashMessage",
message,
() -> Statusgo.hashMessage(message),
callback
);
}
@ReactMethod
public void multiformatDeserializePublicKey(final String multiCodecKey, final String base58btc, final Callback callback) throws JSONException {
JSONObject params = new JSONObject();
params.put("key", multiCodecKey);
params.put("outBase", base58btc);
String jsonParams = params.toString();
StatusBackendClient.executeStatusGoRequestWithCallback(
"MultiformatDeserializePublicKeyV2",
jsonParams,
() -> Statusgo.multiformatDeserializePublicKeyV2(jsonParams),
callback
);
}
@ReactMethod
public void deserializeAndCompressKey(final String desktopKey, final Callback callback) throws JSONException {
StatusBackendClient.executeStatusGoRequestWithCallback(
"DeserializeAndCompressKey",
desktopKey,
() -> Statusgo.deserializeAndCompressKey(desktopKey),
callback
);
}
@ReactMethod
public void hashTypedData(final String data, final Callback callback) throws JSONException {
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.hashTypedData(data), callback);
}
@ReactMethod
public void hashTypedDataV4(final String data, final Callback callback) throws JSONException {
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.hashTypedDataV4(data), callback);
}
@ReactMethod
public void signMessage(final String rpcParams, final Callback callback) throws JSONException {
StatusBackendClient.executeStatusGoRequestWithCallback(
"SignMessage",
rpcParams,
() -> Statusgo.signMessage(rpcParams),
callback
);
}
@ReactMethod
public void signTypedData(final String data, final String account, final String password, final Callback callback) throws JSONException {
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.signTypedData(data, account, password), callback);
}
@ReactMethod
public void signTypedDataV4(final String data, final String account, final String password, final Callback callback) throws JSONException {
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.signTypedDataV4(data, account, password), callback);
}
@ReactMethod
public void signGroupMembership(final String content, final Callback callback) throws JSONException {
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.signGroupMembership(content), callback);
}
}
@@ -1,258 +0,0 @@
package im.status.ethereum.module
import android.app.Activity
import android.os.Build
import android.preference.PreferenceManager
import android.util.Log
import android.view.WindowManager
import com.facebook.react.bridge.*
import org.json.JSONException
import org.json.JSONObject
import statusgo.Statusgo
import java.lang.Exception
import java.lang.RuntimeException
class EncryptionUtils(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
private val utils = Utils(reactContext)
companion object {
private const val TAG = "EncryptionUtils"
}
override fun getName(): String = "EncryptionUtils"
@ReactMethod
@Throws(Exception::class)
private fun initKeystore(keyUID: String, callback: Callback) {
Log.d(TAG, "initKeystore")
val commonKeydir = utils.pathCombine(utils.getNoBackupDirectory(), "/keystore")
val keydir = utils.pathCombine(commonKeydir, keyUID)
StatusBackendClient.executeStatusGoRequestWithCallback(
"InitKeystore",
keydir,
{ Statusgo.initKeystore(keydir) },
callback
)
}
@ReactMethod
@Throws(Exception::class)
fun reEncryptDbAndKeystore(keyUID: String, password: String, newPassword: String, callback: Callback) {
val params = JSONObject().apply {
put("keyUID", keyUID)
put("oldPassword", password)
put("newPassword", newPassword)
}
StatusBackendClient.executeStatusGoRequestWithCallback(
"ChangeDatabasePasswordV2",
params.toString(),
{ Statusgo.changeDatabasePasswordV2(params.toString()) },
callback
)
}
@ReactMethod
@Throws(Exception::class)
fun convertToKeycardAccount(
keyUID: String,
accountData: String,
options: String,
keycardUID: String,
password: String,
newPassword: String,
callback: Callback
) {
val keyStoreDir = utils.getKeyStorePath(keyUID)
val params = JSONObject().apply {
put("keyUID", keyUID)
put("account", JSONObject(accountData))
put("settings", JSONObject(options))
put("keycardUID", keycardUID)
put("oldPassword", password)
put("newPassword", newPassword)
}
val jsonParams = params.toString()
StatusBackendClient.executeStatusGoRequest(
"InitKeystore",
keyStoreDir,
{ Statusgo.initKeystore(keyStoreDir) }
)
StatusBackendClient.executeStatusGoRequestWithCallback(
"ConvertToKeycardAccountV2",
jsonParams,
{ Statusgo.convertToKeycardAccountV2(jsonParams) },
callback
)
}
@ReactMethod(isBlockingSynchronousMethod = true)
fun decodeParameters(decodeParamJSON: String): String =
StatusBackendClient.executeStatusGoRequestWithResult(
"DecodeParameters",
decodeParamJSON,
{ Statusgo.decodeParameters(decodeParamJSON) }
)
@ReactMethod(isBlockingSynchronousMethod = true)
fun hexToNumber(hex: String): String =
StatusBackendClient.executeStatusGoRequestWithResult(
"HexToNumber",
hex,
{ Statusgo.hexToNumber(hex) }
)
@ReactMethod(isBlockingSynchronousMethod = true)
fun numberToHex(numString: String): String =
StatusBackendClient.executeStatusGoRequestWithResult(
"NumberToHex",
numString,
{ Statusgo.numberToHex(numString) }
)
@ReactMethod(isBlockingSynchronousMethod = true)
fun sha3(str: String): String =
StatusBackendClient.executeStatusGoRequestWithResult(
"Sha3",
str,
{ Statusgo.sha3(str) }
)
@ReactMethod(isBlockingSynchronousMethod = true)
fun utf8ToHex(str: String): String =
StatusBackendClient.executeStatusGoRequestWithResult(
"Utf8ToHex",
str,
{ Statusgo.utf8ToHex(str) }
)
@ReactMethod(isBlockingSynchronousMethod = true)
fun hexToUtf8(str: String): String =
StatusBackendClient.executeStatusGoRequestWithResult(
"HexToUtf8",
str,
{ Statusgo.hexToUtf8(str) }
)
@ReactMethod(isBlockingSynchronousMethod = true)
fun serializeLegacyKey(publicKey: String): String =
StatusBackendClient.executeStatusGoRequestWithResult(
"SerializeLegacyKey",
publicKey,
{ Statusgo.serializeLegacyKey(publicKey) }
)
@ReactMethod
fun setBlankPreviewFlag(blankPreview: Boolean) {
PreferenceManager.getDefaultSharedPreferences(reactContext)
.edit()
.putBoolean("BLANK_PREVIEW", blankPreview)
.commit()
setSecureFlag()
}
private fun setSecureFlag() {
val sharedPrefs = PreferenceManager.getDefaultSharedPreferences(reactContext)
val setSecure = sharedPrefs.getBoolean("BLANK_PREVIEW", true)
reactContext.currentActivity?.run {
runOnUiThread {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && setSecure) {
window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
} else {
window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
}
}
}
}
@ReactMethod
@Throws(Exception::class)
fun hashTransaction(txArgsJSON: String, callback: Callback) {
StatusBackendClient.executeStatusGoRequestWithCallback(
"HashTransaction",
txArgsJSON,
{ Statusgo.hashTransaction(txArgsJSON) },
callback
)
}
@ReactMethod
@Throws(Exception::class)
fun hashMessage(message: String, callback: Callback) {
StatusBackendClient.executeStatusGoRequestWithCallback(
"HashMessage",
message,
{ Statusgo.hashMessage(message) },
callback
)
}
@ReactMethod
@Throws(Exception::class)
fun multiformatDeserializePublicKey(multiCodecKey: String, base58btc: String, callback: Callback) {
val params = JSONObject().apply {
put("key", multiCodecKey)
put("outBase", base58btc)
}
StatusBackendClient.executeStatusGoRequestWithCallback(
"MultiformatDeserializePublicKeyV2",
params.toString(),
{ Statusgo.multiformatDeserializePublicKeyV2(params.toString()) },
callback
)
}
@ReactMethod
@Throws(Exception::class)
fun deserializeAndCompressKey(desktopKey: String, callback: Callback) {
StatusBackendClient.executeStatusGoRequestWithCallback(
"DeserializeAndCompressKey",
desktopKey,
{ Statusgo.deserializeAndCompressKey(desktopKey) },
callback
)
}
@ReactMethod
@Throws(Exception::class)
fun hashTypedData(data: String, callback: Callback) {
utils.executeRunnableStatusGoMethod({ Statusgo.hashTypedData(data) }, callback)
}
@ReactMethod
@Throws(Exception::class)
fun hashTypedDataV4(data: String, callback: Callback) {
utils.executeRunnableStatusGoMethod({ Statusgo.hashTypedDataV4(data) }, callback)
}
@ReactMethod
@Throws(Exception::class)
fun signMessage(rpcParams: String, callback: Callback) {
StatusBackendClient.executeStatusGoRequestWithCallback(
"SignMessage",
rpcParams,
{ Statusgo.signMessage(rpcParams) },
callback
)
}
@ReactMethod
@Throws(Exception::class)
fun signTypedData(data: String, account: String, password: String, callback: Callback) {
utils.executeRunnableStatusGoMethod({ Statusgo.signTypedData(data, account, password) }, callback)
}
@ReactMethod
@Throws(Exception::class)
fun signTypedDataV4(data: String, account: String, password: String, callback: Callback) {
utils.executeRunnableStatusGoMethod({ Statusgo.signTypedDataV4(data, account, password) }, callback)
}
@ReactMethod
@Throws(Exception::class)
fun signGroupMembership(content: String, callback: Callback) {
utils.executeRunnableStatusGoMethod({ Statusgo.signGroupMembership(content) }, callback)
}
}
@@ -35,11 +35,6 @@ class LogManager(private val reactContext: ReactApplicationContext) : ReactConte
return File(pubDirectory, gethLogFileName)
}
private fun getPreLoginLogFile(): File {
val pubDirectory = utils.getPublicStorageDirectory()
return File(pubDirectory, preLoginLogFileName)
}
fun prepareLogsFile(context: Context): File? {
val logFile = getGethLogFile()
@@ -161,7 +156,6 @@ class LogManager(private val reactContext: ReactApplicationContext) : ReactConte
val statusLogFile = File(logsTempDir, statusLogFileName)
val gethLogFile = getGethLogFile()
val requestLogFile = getRequestLogFile()
val preLoginLogFile = getPreLoginLogFile()
try {
if (zipFile.exists() || zipFile.createNewFile()) {
@@ -181,9 +175,6 @@ class LogManager(private val reactContext: ReactApplicationContext) : ReactConte
if (requestLogFile.exists()) {
filesToZip.add(requestLogFile)
}
if (preLoginLogFile.exists()) {
filesToZip.add(preLoginLogFile)
}
val zipped = zip(filesToZip.toTypedArray(), zipFile, errorList)
if (zipped && zipFile.exists()) {
zipFile.setReadable(true, false)
@@ -204,6 +195,25 @@ class LogManager(private val reactContext: ReactApplicationContext) : ReactConte
}
}
@ReactMethod
fun initLogging(enabled: Boolean, mobileSystem: Boolean, logLevel: String, logRequestGo: Boolean, callback: Callback) {
val jsonConfig = JSONObject().apply {
put("Enabled", enabled)
put("MobileSystem", mobileSystem)
put("Level", logLevel)
put("File", getGethLogFile().absolutePath)
put("LogRequestGo", logRequestGo)
put("LogRequestFile", getRequestLogFile().absolutePath)
}
val config = jsonConfig.toString()
StatusBackendClient.executeStatusGoRequestWithCallback(
endpoint = "InitLogging",
requestBody = config,
statusgoFunction = { Statusgo.initLogging(config) },
callback = callback
)
}
@ReactMethod(isBlockingSynchronousMethod = true)
fun logFileDirectory(): String? {
return utils.getPublicStorageDirectory()?.absolutePath
@@ -213,8 +223,7 @@ class LogManager(private val reactContext: ReactApplicationContext) : ReactConte
private const val TAG = "LogManager"
private const val gethLogFileName = "geth.log"
private const val statusLogFileName = "Status.log"
private const val requestsLogFileName = "api.log"
private const val preLoginLogFileName = "pre_login.log"
private const val requestsLogFileName = "requests.log"
private const val logsZipFileName = "Status-debug-logs.zip"
}
}
@@ -0,0 +1,124 @@
package im.status.ethereum.module;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import android.app.Activity;
import android.util.Log;
import android.os.Build;
import android.webkit.WebView;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.WebStorage;
import android.view.WindowManager;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.UIBlock;
import com.facebook.react.uimanager.NativeViewHierarchyManager;
import android.view.inputmethod.InputMethodManager;
import android.view.View;
import android.widget.EditText;
import android.content.Context;
public class UIHelper extends ReactContextBaseJavaModule {
private static final String TAG = "UIHelper";
private ReactApplicationContext reactContext;
public UIHelper(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
}
@Override
public String getName() {
return "UIHelper";
}
@ReactMethod
public void setSoftInputMode(final int mode) {
Log.d(TAG, "setSoftInputMode");
final Activity activity = getCurrentActivity();
if (activity == null) {
return;
}
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
activity.getWindow().setSoftInputMode(mode);
}
});
}
@SuppressWarnings("deprecation")
@ReactMethod
public void clearCookies() {
Log.d(TAG, "clearCookies");
final Activity activity = getCurrentActivity();
if (activity == null) {
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
CookieManager.getInstance().removeAllCookies(null);
CookieManager.getInstance().flush();
} else {
CookieSyncManager cookieSyncManager = CookieSyncManager.createInstance(activity);
cookieSyncManager.startSync();
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.removeAllCookie();
cookieManager.removeSessionCookie();
cookieSyncManager.stopSync();
cookieSyncManager.sync();
}
}
@ReactMethod
public void toggleWebviewDebug(final boolean val) {
Log.d(TAG, "toggleWebviewDebug");
final Activity activity = getCurrentActivity();
if (activity == null) {
return;
}
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
WebView.setWebContentsDebuggingEnabled(val);
}
});
}
@ReactMethod
public void clearStorageAPIs() {
Log.d(TAG, "clearStorageAPIs");
final Activity activity = getCurrentActivity();
if (activity == null) {
return;
}
WebStorage storage = WebStorage.getInstance();
if (storage != null) {
storage.deleteAllData();
}
}
@ReactMethod
public void resetKeyboardInputCursor(final int reactTagToReset, final int selection) {
UIManagerModule uiManager = getReactApplicationContext().getNativeModule(UIManagerModule.class);
uiManager.addUIBlock(new UIBlock() {
@Override
public void execute(NativeViewHierarchyManager nativeViewHierarchyManager) {
InputMethodManager imm = (InputMethodManager) getReactApplicationContext().getBaseContext().getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
View viewToReset = nativeViewHierarchyManager.resolveView(reactTagToReset);
imm.restartInput(viewToReset);
try {
EditText textView = (EditText) viewToReset;
textView.setSelection(selection);
} catch (Exception e) {}
}
}
});
}
}
@@ -1,97 +0,0 @@
package im.status.ethereum.module
import android.app.Activity
import android.content.Context
import android.os.Build
import android.util.Log
import android.view.View
import android.view.WindowManager
import android.view.inputmethod.InputMethodManager
import android.webkit.CookieManager
import android.webkit.CookieSyncManager
import android.webkit.WebStorage
import android.webkit.WebView
import android.widget.EditText
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.uimanager.NativeViewHierarchyManager
import com.facebook.react.uimanager.UIBlock
import com.facebook.react.uimanager.UIManagerModule
class UIHelper(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
companion object {
private const val TAG = "UIHelper"
}
override fun getName(): String = "UIHelper"
@ReactMethod
fun setSoftInputMode(mode: Int) {
Log.d(TAG, "setSoftInputMode")
getCurrentActivity()?.run {
runOnUiThread {
window.setSoftInputMode(mode)
}
}
}
@Suppress("DEPRECATION")
@ReactMethod
fun clearCookies() {
Log.d(TAG, "clearCookies")
getCurrentActivity()?.let { activity ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
CookieManager.getInstance().apply {
removeAllCookies(null)
flush()
}
} else {
CookieSyncManager.createInstance(activity).also { cookieSyncManager ->
cookieSyncManager.startSync()
CookieManager.getInstance().apply {
removeAllCookie()
removeSessionCookie()
}
cookieSyncManager.stopSync()
cookieSyncManager.sync()
}
}
}
}
@ReactMethod
fun toggleWebviewDebug(enabled: Boolean) {
Log.d(TAG, "toggleWebviewDebug")
getCurrentActivity()?.run {
runOnUiThread {
WebView.setWebContentsDebuggingEnabled(enabled)
}
}
}
@ReactMethod
fun clearStorageAPIs() {
Log.d(TAG, "clearStorageAPIs")
getCurrentActivity()?.let {
WebStorage.getInstance()?.deleteAllData()
}
}
@ReactMethod
fun resetKeyboardInputCursor(reactTagToReset: Int, selection: Int) {
reactApplicationContext.getNativeModule(UIManagerModule::class.java)?.addUIBlock(object : UIBlock {
override fun execute(nativeViewHierarchyManager: NativeViewHierarchyManager) {
(reactApplicationContext.baseContext.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager)?.let { imm ->
val viewToReset = nativeViewHierarchyManager.resolveView(reactTagToReset)
imm.restartInput(viewToReset)
try {
(viewToReset as? EditText)?.setSelection(selection)
} catch (e: Exception) {
// Ignore exceptions during selection setting
}
}
}
})
}
}
@@ -0,0 +1,109 @@
package im.status.ethereum.pushnotifications;
import android.content.Context;
import android.content.Intent;
import android.app.Service;
import android.content.pm.ServiceInfo;
import android.os.IBinder;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.provider.Settings;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import android.os.Build;
import im.status.ethereum.module.R;
public class ForegroundService extends Service {
private static final String CHANNEL_ID = "status-service";
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent i, int flags, int startId) {
// NOTE: recent versions of Android require the service to display
// a sticky notification to inform the user that the service is running
Context context = getApplicationContext();
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
Intent intent = null;
String notificationContentText = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager notificationManager =
context.getSystemService(NotificationManager.class);
NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
context.getResources().getString(R.string.status_service),
NotificationManager.IMPORTANCE_HIGH);
channel.setShowBadge(false);
notificationManager.createNotificationChannel(channel);
// Create intent that takes the user to the notification channel settings so they can hide it
intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
intent.putExtra(Settings.EXTRA_CHANNEL_ID, CHANNEL_ID);
notificationContentText = context.getResources().getString(R.string.tap_to_hide_notification);
} else {
// For older versions of android intent takes the user to the Status app
Class intentClass;
String packageName = context.getPackageName();
Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(packageName);
String className = launchIntent.getComponent().getClassName();
try {
intentClass = Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
return 0;
}
intent = new Intent(context, intentClass);
intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.setAction(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
notificationContentText = context.getResources().getString(R.string.keep_status_running);
}
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE);
Intent stopIntent = new Intent(PushNotificationHelper.ACTION_TAP_STOP);
PendingIntent stopPendingIntent = PendingIntent.getBroadcast(context, 0, stopIntent,
PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
Notification notification = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_stat_notify_status)
.setContentTitle(context.getResources().getString(R.string.background_service_opened))
.setContentText(notificationContentText)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
.setContentIntent(pendingIntent)
.setNumber(0)
.addAction(R.drawable.ic_stat_notify_status,
context.getResources().getString(R.string.stop),
stopPendingIntent)
.build();
// the id of the foreground notification MUST NOT be 0
if (Build.VERSION.SDK_INT >= 33) {
startForeground(1, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE);
} else {
startForeground(1, notification);
}
return START_STICKY;
}
}
@@ -1,122 +0,0 @@
package im.status.ethereum.pushnotifications
import android.content.Context
import android.content.Intent
import android.app.Service
import android.content.pm.ServiceInfo
import android.os.IBinder
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.provider.Settings
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import android.os.Build
import im.status.ethereum.module.R
class ForegroundService : Service() {
companion object {
private const val CHANNEL_ID = "status-service"
}
override fun onBind(intent: Intent?): IBinder? {
return null
}
override fun onStartCommand(i: Intent?, flags: Int, startId: Int): Int {
// NOTE: recent versions of Android require the service to display
// a sticky notification to inform the user that the service is running
val context = applicationContext
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
// Create notification channel for Android O and above
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationManager = context.getSystemService(NotificationManager::class.java)
val channel = NotificationChannel(
CHANNEL_ID,
context.resources.getString(R.string.status_service),
NotificationManager.IMPORTANCE_HIGH
).apply {
setShowBadge(false)
}
notificationManager.createNotificationChannel(channel)
}
// Initialize intent and notification text based on Android version
val notificationIntent = createNotificationIntent(context)
val notificationText = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.resources.getString(R.string.tap_to_hide_notification)
} else {
context.resources.getString(R.string.keep_status_running)
}
val pendingIntent = PendingIntent.getActivity(
this,
0,
notificationIntent,
PendingIntent.FLAG_IMMUTABLE
)
val stopIntent = Intent(PushNotificationHelper.ACTION_TAP_STOP)
val stopPendingIntent = PendingIntent.getBroadcast(
context,
0,
stopIntent,
PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
val notification = NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_stat_notify_status)
.setContentTitle(context.resources.getString(R.string.background_service_opened))
.setContentText(notificationText)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
.setContentIntent(pendingIntent)
.setNumber(0)
.addAction(
R.drawable.ic_stat_notify_status,
context.resources.getString(R.string.stop),
stopPendingIntent
)
.build()
// the id of the foreground notification MUST NOT be 0
if (Build.VERSION.SDK_INT >= 33) {
startForeground(1, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE)
} else {
startForeground(1, notification)
}
return START_STICKY
}
private fun createNotificationIntent(context: Context): Intent {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Create intent that takes the user to the notification channel settings
Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS).apply {
putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
putExtra(Settings.EXTRA_CHANNEL_ID, CHANNEL_ID)
}
} else {
// For older versions of android, intent takes the user to the Status app
val packageName = context.packageName
val launchIntent = context.packageManager.getLaunchIntentForPackage(packageName)
val className = launchIntent?.component?.className
try {
val intentClass = Class.forName(className!!)
Intent(context, intentClass).apply {
addCategory(Intent.CATEGORY_BROWSABLE)
action = Intent.ACTION_VIEW
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
}
} catch (e: ClassNotFoundException) {
e.printStackTrace()
// Return an empty intent as fallback
Intent()
}
}
}
}
@@ -0,0 +1,146 @@
package im.status.ethereum.pushnotifications;
import android.app.Activity;
import android.app.Application;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.core.app.NotificationManagerCompat;
import java.security.SecureRandom;
import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import android.util.Log;
import im.status.ethereum.pushnotifications.PushNotificationJsDelivery;
public class PushNotification extends ReactContextBaseJavaModule implements ActivityEventListener {
public static final String LOG_TAG = "PushNotification";
private final SecureRandom mRandomNumberGenerator = new SecureRandom();
private PushNotificationHelper pushNotificationHelper;
private PushNotificationJsDelivery delivery;
private ReactApplicationContext reactContext;
private boolean started;
public PushNotification(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
reactContext.addActivityEventListener(this);
Application applicationContext = (Application) reactContext.getApplicationContext();
IntentFilter intentFilter = new IntentFilter();
pushNotificationHelper = new PushNotificationHelper(applicationContext, intentFilter);
delivery = new PushNotificationJsDelivery(reactContext);
}
@Override
public String getName() {
return "PushNotification";
}
// removed @Override temporarily just to get it working on different versions of RN
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
onActivityResult(requestCode, resultCode, data);
}
// removed @Override temporarily just to get it working on different versions of RN
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// Ignored, required to implement ActivityEventListener for RN 0.33
}
private Bundle getBundleFromIntent(Intent intent) {
Bundle bundle = null;
if (intent.hasExtra("notification")) {
bundle = intent.getBundleExtra("notification");
} else if (intent.hasExtra("google.message_id")) {
bundle = new Bundle();
bundle.putBundle("data", intent.getExtras());
}
if(null != bundle && !bundle.getBoolean("foreground", false) && !bundle.containsKey("userInteraction")) {
bundle.putBoolean("userInteraction", true);
}
return bundle;
}
@Override
public void onNewIntent(Intent intent) {
Bundle bundle = this.getBundleFromIntent(intent);
if (bundle != null) {
delivery.notifyNotification(bundle);
}
}
@ReactMethod
/**
* Creates a channel if it does not already exist. Returns whether the channel was created.
*/
public void createChannel(ReadableMap channelInfo, Callback callback) {
boolean created = pushNotificationHelper.createChannel(channelInfo);
if(callback != null) {
callback.invoke(created);
}
}
@ReactMethod
public void presentLocalNotification(ReadableMap details) {
if (!this.started) {
return;
}
Bundle bundle = Arguments.toBundle(details);
// If notification ID is not provided by the user, generate one at random
if (bundle.getString("id") == null) {
bundle.putString("id", String.valueOf(mRandomNumberGenerator.nextInt()));
}
pushNotificationHelper.sendToNotificationCentre(bundle);
}
@ReactMethod
public void clearMessageNotifications(String conversationId) {
if (this.started) {
pushNotificationHelper.clearMessageNotifications(conversationId);
}
}
@ReactMethod
public void clearAllMessageNotifications() {
pushNotificationHelper.clearAllMessageNotifications();
}
@ReactMethod
public void enableNotifications() {
this.started = true;
this.pushNotificationHelper.start();
}
@ReactMethod
public void disableNotifications() {
if (this.started) {
this.started = false;
this.pushNotificationHelper.stop();
}
}
}
@@ -1,118 +0,0 @@
package im.status.ethereum.pushnotifications
import android.app.Activity
import android.app.Application
import android.app.NotificationManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import android.util.Log
import androidx.annotation.NonNull
import androidx.core.app.NotificationManagerCompat
import com.facebook.react.bridge.*
import im.status.ethereum.pushnotifications.PushNotificationJsDelivery
import java.security.SecureRandom
class PushNotification(reactContext: ReactApplicationContext) :
ReactContextBaseJavaModule(reactContext), ActivityEventListener {
companion object {
const val LOG_TAG = "PushNotification"
}
private val mRandomNumberGenerator = SecureRandom()
private val pushNotificationHelper: PushNotificationHelper
private val delivery: PushNotificationJsDelivery
private val reactContext: ReactApplicationContext = reactContext
private var started: Boolean = false
init {
reactContext.addActivityEventListener(this)
val applicationContext = reactContext.applicationContext as Application
val intentFilter = IntentFilter()
pushNotificationHelper = PushNotificationHelper(applicationContext, intentFilter)
delivery = PushNotificationJsDelivery(reactContext)
}
override fun getName(): String = "PushNotification"
// Primary implementation of ActivityEventListener interface
override fun onActivityResult(activity: Activity, requestCode: Int, resultCode: Int, data: Intent?) {
// Call the helper method with the correct parameter order
handleActivityResult(requestCode, resultCode, data)
}
// Private helper method for handling activity results
private fun handleActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
// Ignored, required to implement ActivityEventListener for RN 0.33
}
private fun getBundleFromIntent(intent: Intent): Bundle? {
return when {
intent.hasExtra("notification") -> intent.getBundleExtra("notification")
intent.hasExtra("google.message_id") -> Bundle().apply {
putBundle("data", intent.extras)
}
else -> null
}?.apply {
if (!getBoolean("foreground", false) && !containsKey("userInteraction")) {
putBoolean("userInteraction", true)
}
}
}
override fun onNewIntent(intent: Intent) {
getBundleFromIntent(intent)?.let { bundle ->
delivery.notifyNotification(bundle)
}
}
@ReactMethod
fun createChannel(channelInfo: ReadableMap, callback: Callback?) {
val created = pushNotificationHelper.createChannel(channelInfo)
callback?.invoke(created)
}
@ReactMethod
fun presentLocalNotification(details: ReadableMap) {
if (!started) return
Arguments.toBundle(details)?.apply {
// If notification ID is not provided by the user, generate one at random
if (getString("id") == null) {
putString("id", mRandomNumberGenerator.nextInt().toString())
}
pushNotificationHelper.sendToNotificationCentre(this)
}
}
@ReactMethod
fun clearMessageNotifications(conversationId: String) {
if (started) {
pushNotificationHelper.clearMessageNotifications(conversationId)
}
}
@ReactMethod
fun clearAllMessageNotifications() {
pushNotificationHelper.clearAllMessageNotifications()
}
@ReactMethod
fun enableNotifications() {
started = true
pushNotificationHelper.start()
}
@ReactMethod
fun disableNotifications() {
if (started) {
started = false
pushNotificationHelper.stop()
}
}
}
@@ -0,0 +1,93 @@
package im.status.ethereum.pushnotifications;
import android.os.Build;
import android.app.Application;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.bridge.ReactContext;
import im.status.ethereum.pushnotifications.PushNotificationJsDelivery;
import static im.status.ethereum.pushnotifications.PushNotification.LOG_TAG;
public class PushNotificationActions extends BroadcastReceiver {
@Override
public void onReceive(final Context context, Intent intent) {
String intentActionPrefix = context.getPackageName() + ".ACTION_";
Log.i(LOG_TAG, "PushNotificationBootEventReceiver loading scheduled notifications");
if (null == intent.getAction() || !intent.getAction().startsWith(intentActionPrefix)) {
return;
}
final Bundle bundle = intent.getBundleExtra("notification");
// Dismiss the notification popup.
NotificationManager manager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
int notificationID = Integer.parseInt(bundle.getString("id"));
boolean autoCancel = bundle.getBoolean("autoCancel", true);
if(autoCancel) {
if (bundle.containsKey("tag")) {
String tag = bundle.getString("tag");
manager.cancel(tag, notificationID);
} else {
manager.cancel(notificationID);
}
}
boolean invokeApp = bundle.getBoolean("invokeApp", true);
// Notify the action.
if(invokeApp) {
IntentFilter intentFilter = new IntentFilter();
PushNotificationHelper helper = new PushNotificationHelper((Application) context.getApplicationContext(), intentFilter);
helper.invokeApp(bundle);
} else {
// We need to run this on the main thread, as the React code assumes that is true.
// Namely, DevServerHelper constructs a Handler() without a Looper, which triggers:
// "Can't create handler inside thread that has not called Looper.prepare()"
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
public void run() {
// Construct and load our normal React JS code bundle
final ReactInstanceManager mReactInstanceManager = ((ReactApplication) context.getApplicationContext()).getReactNativeHost().getReactInstanceManager();
ReactContext context = mReactInstanceManager.getCurrentReactContext();
PushNotificationJsDelivery delivery = new PushNotificationJsDelivery(context);
// If it's constructed, send a notification
if (context != null) {
delivery.notifyNotificationAction(bundle);
} else {
// Otherwise wait for construction, then send the notification
mReactInstanceManager.addReactInstanceEventListener(new ReactInstanceManager.ReactInstanceEventListener() {
public void onReactContextInitialized(ReactContext context) {
PushNotificationJsDelivery delivery = new PushNotificationJsDelivery(context);
delivery.notifyNotificationAction(bundle);
mReactInstanceManager.removeReactInstanceEventListener(this);
}
});
if (!mReactInstanceManager.hasStartedCreatingInitialContext()) {
// Construct it in the background
mReactInstanceManager.createReactContextInBackground();
}
}
}
});
}
}
}
@@ -1,100 +0,0 @@
package im.status.ethereum.pushnotifications
import android.os.Build
import android.app.Application
import android.app.NotificationManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.Log
import com.facebook.react.ReactApplication
import com.facebook.react.ReactInstanceManager
import com.facebook.react.bridge.ReactContext
import im.status.ethereum.pushnotifications.PushNotificationJsDelivery
import im.status.ethereum.pushnotifications.PushNotification.Companion.LOG_TAG
/**
* BroadcastReceiver responsible for handling push notification actions.
* This class processes notification interactions and manages their lifecycle.
*/
class PushNotificationActions : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val intentActionPrefix = "${context.packageName}.ACTION_"
Log.i(LOG_TAG, "PushNotificationBootEventReceiver loading scheduled notifications")
if (intent.action == null || !intent.action!!.startsWith(intentActionPrefix)) {
return
}
val bundle = intent.getBundleExtra("notification") ?: return
val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val notificationID = bundle.getString("id")?.toInt() ?: return
// Dismiss the notification popup.
val autoCancel = bundle.getBoolean("autoCancel", true)
if (autoCancel) {
bundle.getString("tag")?.let { tag ->
manager.cancel(tag, notificationID)
} ?: run {
manager.cancel(notificationID)
}
}
// Notify the action.
val invokeApp = bundle.getBoolean("invokeApp", true)
if (invokeApp) {
val intentFilter = IntentFilter()
val helper = PushNotificationHelper(
context.applicationContext as Application,
intentFilter
)
helper.invokeApp(bundle)
} else {
// We need to run this on the main thread, as the React code assumes that is true.
// Namely, DevServerHelper constructs a Handler() without a Looper, which triggers:
// "Can't create handler inside thread that has not called Looper.prepare()"
Handler(Looper.getMainLooper()).post {
// Construct and load our normal React JS code bundle
val reactInstanceManager = (context.applicationContext as ReactApplication)
.reactNativeHost
.reactInstanceManager
val currentContext = reactInstanceManager.currentReactContext
when {
// If context exists, deliver notification immediately
currentContext != null -> {
PushNotificationJsDelivery(currentContext)
.notifyNotificationAction(bundle)
}
// Otherwise wait for construction, then send the notification
else -> {
val listener = object : ReactInstanceManager.ReactInstanceEventListener {
override fun onReactContextInitialized(reactContext: ReactContext) {
PushNotificationJsDelivery(reactContext)
.notifyNotificationAction(bundle)
reactInstanceManager.removeReactInstanceEventListener(this)
}
}
// Add the listener and create context if needed
reactInstanceManager.addReactInstanceEventListener(listener)
if (!reactInstanceManager.hasStartedCreatingInitialContext()) {
// Construct it in the background
reactInstanceManager.createReactContextInBackground()
}
}
}
}
}
}
}
@@ -0,0 +1,890 @@
// https://github.com/zo0r/react-native-push-notification/blob/bedc8f646aab67d594f291449fbfa24e07b64fe8/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationHelper.java Copy-Paste with removed firebase
package im.status.ethereum.pushnotifications;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.AlarmManager;
import android.app.Application;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.BroadcastReceiver;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.media.AudioAttributes;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.service.notification.StatusBarNotification;
import android.util.Log;
import android.util.Base64;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import androidx.core.app.Person;
import androidx.core.graphics.drawable.IconCompat;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import org.json.JSONArray;
import org.json.JSONException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import im.status.ethereum.module.R;
import static im.status.ethereum.pushnotifications.PushNotification.LOG_TAG;
public class PushNotificationHelper {
private Context context;
private static final long DEFAULT_VIBRATION = 300L;
private static final String CHANNEL_ID = "status-im-notifications";
public static final String ACTION_DELETE_NOTIFICATION = "im.status.ethereum.module.DELETE_NOTIFICATION";
public static final String ACTION_TAP_STOP = "im.status.ethereum.module.TAP_STOP";
final int flag = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE : PendingIntent.FLAG_CANCEL_CURRENT;
private NotificationManager notificationManager;
private HashMap<String, Person> persons;
private HashMap<String, StatusMessageGroup> messageGroups;
private IntentFilter intentFilter;
public PushNotificationHelper(Application context, IntentFilter intentFilter) {
this.context = context;
this.intentFilter = intentFilter;
this.persons = new HashMap<String, Person>();
this.messageGroups = new HashMap<String, StatusMessageGroup>();
this.notificationManager = context.getSystemService(NotificationManager.class);
this.registerBroadcastReceiver();
}
public Intent getOpenAppIntent(String deepLink) {
Class intentClass;
String packageName = context.getPackageName();
Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(packageName);
String className = launchIntent.getComponent().getClassName();
try {
intentClass = Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
}
Intent intent = new Intent(context, intentClass);
intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.setAction(Intent.ACTION_VIEW);
//NOTE: you might wonder, why the heck did he decide to set these flags in particular. Well,
//the answer is a simple as it can get in the Android native development world. I noticed
//that my initial setup was opening the app but wasn't triggering any events on the js side, like
//the links do from the browser. So I compared both intents and noticed that the link from
//the browser produces an intent with the flag 0x14000000. I found out that it was the following
//flags in this link:
//https://stackoverflow.com/questions/52390129/android-intent-setflags-issue
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
if (deepLink != null) {
intent.setData(Uri.parse(deepLink));
}
return intent;
}
//NOTE: we use a dynamically created BroadcastReceiver here so that we can capture
//intents from notifications and act on them. For instance when tapping/dismissing
//a chat notification we want to clear the chat so that next messages don't show
//the messages that we have seen again
private final BroadcastReceiver notificationActionReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction() == ACTION_DELETE_NOTIFICATION) {
String groupId = intent.getExtras().getString("im.status.ethereum.groupId");
if (groupId != null) {
cleanGroup(groupId);
}
}
if (intent.getAction() == ACTION_TAP_STOP) {
stop();
System.exit(0);
}
Log.e(LOG_TAG, "intent received: " + intent.getAction());
}
};
public void registerBroadcastReceiver() {
this.intentFilter.addAction(ACTION_DELETE_NOTIFICATION);
this.intentFilter.addAction(ACTION_TAP_STOP);
context.registerReceiver(notificationActionReceiver, this.intentFilter, Context.RECEIVER_EXPORTED);
Log.e(LOG_TAG, "Broadcast Receiver registered");
}
private NotificationManager notificationManager() {
return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
}
public void invokeApp(Bundle bundle) {
String packageName = context.getPackageName();
Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(packageName);
String className = launchIntent.getComponent().getClassName();
try {
Class<?> activityClass = Class.forName(className);
Intent activityIntent = new Intent(context, activityClass);
if(bundle != null) {
activityIntent.putExtra("notification", bundle);
}
activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(activityIntent);
} catch(Exception e) {
Log.e(LOG_TAG, "Class not found", e);
return;
}
}
public void sendToNotificationCentre(final Bundle bundle) {
PushNotificationPicturesAggregator aggregator = new PushNotificationPicturesAggregator(new PushNotificationPicturesAggregator.Callback() {
public void call(Bitmap largeIconImage, Bitmap bigPictureImage) {
sendToNotificationCentreWithPicture(bundle, largeIconImage, bigPictureImage);
}
});
aggregator.setLargeIconUrl(context, bundle.getString("largeIconUrl"));
aggregator.setBigPictureUrl(context, bundle.getString("bigPictureUrl"));
}
public void handleConversation(final Bundle bundle) {
if (bundle.getBoolean("deleted")){
this.removeStatusMessage(bundle);
} else {
this.addStatusMessage(bundle);
}
}
public void clearMessageNotifications(String conversationId) {
notificationManager.cancel(conversationId.hashCode());
cleanGroup(conversationId);
}
public void clearAllMessageNotifications() {
notificationManager.cancelAll();
}
public void sendToNotificationCentreWithPicture(final Bundle bundle, Bitmap largeIconBitmap, Bitmap bigPictureBitmap) {
try {
Class intentClass = getMainActivityClass();
if (intentClass == null) {
Log.e(LOG_TAG, "No activity class found for the notification");
return;
}
if (bundle.getBoolean("isConversation")) {
this.handleConversation(bundle);
return;
}
if (bundle.getString("message") == null) {
// this happens when a 'data' notification is received - we do not synthesize a local notification in this case
Log.d(LOG_TAG, "Ignore this message if you sent data-only notification. Cannot send to notification centre because there is no 'message' field in: " + bundle);
return;
}
String notificationIdString = bundle.getString("id");
if (notificationIdString == null) {
Log.e(LOG_TAG, "No notification ID specified for the notification");
return;
}
Resources res = context.getResources();
String packageName = context.getPackageName();
String title = bundle.getString("title");
if (title == null) {
ApplicationInfo appInfo = context.getApplicationInfo();
title = context.getPackageManager().getApplicationLabel(appInfo).toString();
}
int priority = NotificationCompat.PRIORITY_HIGH;
final String priorityString = bundle.getString("priority");
if (priorityString != null) {
switch (priorityString.toLowerCase()) {
case "max":
priority = NotificationCompat.PRIORITY_MAX;
break;
case "high":
priority = NotificationCompat.PRIORITY_HIGH;
break;
case "low":
priority = NotificationCompat.PRIORITY_LOW;
break;
case "min":
priority = NotificationCompat.PRIORITY_MIN;
break;
case "default":
priority = NotificationCompat.PRIORITY_DEFAULT;
break;
default:
priority = NotificationCompat.PRIORITY_HIGH;
}
}
int visibility = NotificationCompat.VISIBILITY_PRIVATE;
final String visibilityString = bundle.getString("visibility");
if (visibilityString != null) {
switch (visibilityString.toLowerCase()) {
case "private":
visibility = NotificationCompat.VISIBILITY_PRIVATE;
break;
case "public":
visibility = NotificationCompat.VISIBILITY_PUBLIC;
break;
case "secret":
visibility = NotificationCompat.VISIBILITY_SECRET;
break;
default:
visibility = NotificationCompat.VISIBILITY_PRIVATE;
}
}
String channel_id = bundle.getString("channelId");
if(channel_id == null) {
channel_id = this.getNotificationDefaultChannelId();
}
NotificationCompat.Builder notification = new NotificationCompat.Builder(context, channel_id)
.setContentTitle(title)
.setTicker(bundle.getString("ticker"))
.setVisibility(visibility)
.setPriority(priority)
.setAutoCancel(bundle.getBoolean("autoCancel", true))
.setOnlyAlertOnce(bundle.getBoolean("onlyAlertOnce", false));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // API 24 and higher
// Restore showing timestamp on Android 7+
// Source: https://developer.android.com/reference/android/app/Notification.Builder.html#setShowWhen(boolean)
boolean showWhen = bundle.getBoolean("showWhen", true);
notification.setShowWhen(showWhen);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // API 26 and higher
// Changing Default mode of notification
notification.setDefaults(Notification.DEFAULT_LIGHTS);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) { // API 20 and higher
String group = bundle.getString("group");
if (group != null) {
notification.setGroup(group);
}
if (bundle.containsKey("groupSummary") || bundle.getBoolean("groupSummary")) {
notification.setGroupSummary(bundle.getBoolean("groupSummary"));
}
}
String numberString = bundle.getString("number");
if (numberString != null) {
notification.setNumber(Integer.parseInt(numberString));
}
// Small icon
int smallIconResId = 0;
String smallIcon = bundle.getString("smallIcon");
if (smallIcon != null && !smallIcon.isEmpty()) {
smallIconResId = res.getIdentifier(smallIcon, "mipmap", packageName);
} else if(smallIcon == null) {
smallIconResId = res.getIdentifier("ic_stat_notify_status", "drawable", packageName);
}
if (smallIconResId == 0) {
smallIconResId = res.getIdentifier("ic_launcher", "mipmap", packageName);
if (smallIconResId == 0) {
smallIconResId = android.R.drawable.ic_dialog_info;
}
}
notification.setSmallIcon(smallIconResId);
// Large icon
if(largeIconBitmap == null) {
int largeIconResId = 0;
String largeIcon = bundle.getString("largeIcon");
if (largeIcon != null && !largeIcon.isEmpty()) {
largeIconResId = res.getIdentifier(largeIcon, "mipmap", packageName);
} else if(largeIcon == null) {
largeIconResId = res.getIdentifier("ic_launcher", "mipmap", packageName);
}
// Before Lolipop there was no large icon for notifications.
if (largeIconResId != 0 && (largeIcon != null || Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)) {
largeIconBitmap = BitmapFactory.decodeResource(res, largeIconResId);
}
}
Bundle author = bundle.getBundle("notificationAuthor");
if (largeIconBitmap == null && author != null) {
String base64Image = author.getString("icon").split(",")[1];
byte[] decodedString = Base64.decode(base64Image, Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
notification.setLargeIcon(getCircleBitmap(decodedByte));
} else if (largeIconBitmap != null){
notification.setLargeIcon(largeIconBitmap);
}
String message = bundle.getString("message");
notification.setContentText(message);
String subText = bundle.getString("subText");
if (subText != null) {
notification.setSubText(subText);
}
String bigText = bundle.getString("bigText");
if (bigText == null) {
bigText = message;
}
NotificationCompat.Style style;
if(bigPictureBitmap != null) {
style = new NotificationCompat.BigPictureStyle()
.bigPicture(bigPictureBitmap)
.setBigContentTitle(title)
.setSummaryText(message);
} else {
style = new NotificationCompat.BigTextStyle().bigText(bigText);
}
notification.setStyle(style);
Intent intent = new Intent(context, intentClass);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
bundle.putBoolean("foreground", this.isApplicationInForeground());
bundle.putBoolean("userInteraction", true);
intent.putExtra("notification", bundle);
Uri soundUri = null;
if (!bundle.containsKey("playSound") || bundle.getBoolean("playSound")) {
String soundName = bundle.getString("soundName");
if (soundName == null) {
soundName = "default";
}
soundUri = getSoundUri(soundName);
notification.setSound(soundUri);
}
if (soundUri == null || Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
notification.setSound(null);
}
if (bundle.containsKey("ongoing") || bundle.getBoolean("ongoing")) {
notification.setOngoing(bundle.getBoolean("ongoing"));
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
notification.setCategory(NotificationCompat.CATEGORY_CALL);
String color = bundle.getString("color");
int defaultColor = -1;
if (color != null) {
notification.setColor(Color.parseColor(color));
} else if (defaultColor != -1) {
notification.setColor(defaultColor);
}
}
int notificationID = notificationIdString.hashCode();
notification.setContentIntent(createOnTapIntent(context, notificationID, bundle.getString("deepLink")))
.setDeleteIntent(createOnDismissedIntent(context, notificationID, bundle.getString("deepLink")));
NotificationManager notificationManager = notificationManager();
long[] vibratePattern = new long[]{0};
if (!bundle.containsKey("vibrate") || bundle.getBoolean("vibrate")) {
long vibration = bundle.containsKey("vibration") ? (long) bundle.getDouble("vibration") : DEFAULT_VIBRATION;
if (vibration == 0)
vibration = DEFAULT_VIBRATION;
vibratePattern = new long[]{0, vibration};
notification.setVibrate(vibratePattern);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Define the shortcutId
String shortcutId = bundle.getString("shortcutId");
if (shortcutId != null) {
notification.setShortcutId(shortcutId);
}
Long timeoutAfter = (long) bundle.getDouble("timeoutAfter");
if (timeoutAfter != null && timeoutAfter >= 0) {
notification.setTimeoutAfter(timeoutAfter);
}
}
Long when = (long) bundle.getDouble("when");
if (when != null && when >= 0) {
notification.setWhen(when);
}
notification.setUsesChronometer(bundle.getBoolean("usesChronometer", false));
notification.setChannelId(channel_id);
JSONArray actionsArray = null;
try {
actionsArray = bundle.getString("actions") != null ? new JSONArray(bundle.getString("actions")) : null;
} catch (JSONException e) {
Log.e(LOG_TAG, "Exception while converting actions to JSON object.", e);
}
if (actionsArray != null) {
// No icon for now. The icon value of 0 shows no icon.
int icon = 0;
// Add button for each actions.
for (int i = 0; i < actionsArray.length(); i++) {
String action;
try {
action = actionsArray.getString(i);
} catch (JSONException e) {
Log.e(LOG_TAG, "Exception while getting action from actionsArray.", e);
continue;
}
Intent actionIntent = new Intent(context, PushNotificationActions.class);
actionIntent.setAction(packageName + ".ACTION_" + i);
actionIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
// Add "action" for later identifying which button gets pressed.
bundle.putString("action", action);
actionIntent.putExtra("notification", bundle);
actionIntent.setPackage(packageName);
PendingIntent pendingActionIntent = PendingIntent.getBroadcast(context, notificationID, actionIntent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
notification.addAction(new NotificationCompat.Action.Builder(icon, action, pendingActionIntent).build());
} else {
notification.addAction(icon, action, pendingActionIntent);
}
}
}
if (!(this.isApplicationInForeground() && bundle.getBoolean("ignoreInForeground"))) {
Notification info = notification.build();
info.defaults |= Notification.DEFAULT_LIGHTS;
if (bundle.containsKey("tag")) {
String tag = bundle.getString("tag");
notificationManager.notify(tag, notificationID, info);
} else {
notificationManager.notify(notificationID, info);
}
}
} catch (Exception e) {
Log.e(LOG_TAG, "failed to send push notification", e);
}
}
private boolean checkOrCreateChannel(NotificationManager manager, String channel_id, String channel_name, String channel_description, Uri soundUri, int importance, long[] vibratePattern, boolean showBadge) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
return false;
if (manager == null)
return false;
NotificationChannel channel = manager.getNotificationChannel(channel_id);
if (
channel == null && channel_name != null && channel_description != null ||
channel != null &&
(
channel_name != null && !channel.getName().equals(channel_name) ||
channel_description != null && !channel.getDescription().equals(channel_description)
)
) {
// If channel doesn't exist create a new one.
// If channel name or description is updated then update the existing channel.
channel = new NotificationChannel(channel_id, channel_name, importance);
channel.setDescription(channel_description);
channel.enableLights(true);
channel.enableVibration(vibratePattern != null);
channel.setVibrationPattern(vibratePattern);
channel.setShowBadge(showBadge);
if (soundUri != null) {
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.build();
channel.setSound(soundUri, audioAttributes);
} else {
channel.setSound(null, null);
}
manager.createNotificationChannel(channel);
return true;
}
return false;
}
public boolean createChannel(ReadableMap channelInfo) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
return false;
String channelId = channelInfo.getString("channelId");
String channelName = channelInfo.getString("channelName");
String channelDescription = channelInfo.hasKey("channelDescription") ? channelInfo.getString("channelDescription") : "";
String soundName = channelInfo.hasKey("soundName") ? channelInfo.getString("soundName") : "default";
int importance = channelInfo.hasKey("importance") ? channelInfo.getInt("importance") : 4;
boolean vibrate = channelInfo.hasKey("vibrate") && channelInfo.getBoolean("vibrate");
long[] vibratePattern = vibrate ? new long[] { DEFAULT_VIBRATION } : null;
boolean showBadge = channelInfo.hasKey("showBadge") && channelInfo.getBoolean("showBadge");
NotificationManager manager = notificationManager();
Uri soundUri = getSoundUri(soundName);
return checkOrCreateChannel(manager, channelId, channelName, channelDescription, soundUri, importance, vibratePattern, showBadge);
}
public String getNotificationDefaultChannelId() {
return this.CHANNEL_ID;
}
private Uri getSoundUri(String soundName) {
if (soundName == null || "default".equalsIgnoreCase(soundName)) {
return RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
} else {
// sound name can be full filename, or just the resource name.
// So the strings 'my_sound.mp3' AND 'my_sound' are accepted
// The reason is to make the iOS and android javascript interfaces compatible
int resId;
if (context.getResources().getIdentifier(soundName, "raw", context.getPackageName()) != 0) {
resId = context.getResources().getIdentifier(soundName, "raw", context.getPackageName());
} else {
soundName = soundName.substring(0, soundName.lastIndexOf('.'));
resId = context.getResources().getIdentifier(soundName, "raw", context.getPackageName());
}
return Uri.parse("android.resource://" + context.getPackageName() + "/" + resId);
}
}
public Class getMainActivityClass() {
String packageName = context.getPackageName();
Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(packageName);
String className = launchIntent.getComponent().getClassName();
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}
public boolean isApplicationInForeground() {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningAppProcessInfo> processInfos = activityManager.getRunningAppProcesses();
if (processInfos != null) {
for (RunningAppProcessInfo processInfo : processInfos) {
if (processInfo.processName.equals(context.getPackageName())
&& processInfo.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND
&& processInfo.pkgList.length > 0) {
return true;
}
}
}
return false;
}
private Bitmap getCircleBitmap(Bitmap bitmap) {
final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(output);
final int color = Color.RED;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawOval(rectF, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
bitmap.recycle();
return output;
}
private Person getPerson(Bundle bundle) {
String name = bundle.getString("name");
return new Person.Builder().setName(name).build();
}
private StatusMessage createMessage(Bundle data) {
Person author = getPerson(data.getBundle("notificationAuthor"));
long timeStampLongValue = (long) data.getDouble("timestamp");
return new StatusMessage(data.getString("id"), author, timeStampLongValue, data.getString("message"));
}
private PendingIntent createGroupOnDismissedIntent(Context context, int notificationId, String groupId, String deepLink) {
Intent intent = new Intent(ACTION_DELETE_NOTIFICATION);
intent.putExtra("im.status.ethereum.deepLink", deepLink);
intent.putExtra("im.status.ethereum.groupId", groupId);
return PendingIntent.getBroadcast(context.getApplicationContext(), notificationId, intent, flag);
}
private PendingIntent createGroupOnTapIntent(Context context, int notificationId, String groupId, String deepLink) {
Intent intent = getOpenAppIntent(deepLink);
return PendingIntent.getActivity(context.getApplicationContext(), notificationId, intent, flag);
}
private PendingIntent createOnTapIntent(Context context, int notificationId, String deepLink) {
Intent intent = getOpenAppIntent(deepLink);
return PendingIntent.getActivity(context.getApplicationContext(), notificationId, intent, flag);
}
private PendingIntent createOnDismissedIntent(Context context, int notificationId, String deepLink) {
Intent intent = new Intent(ACTION_DELETE_NOTIFICATION);
intent.putExtra("im.status.ethereum.deepLink", deepLink);
return PendingIntent.getBroadcast(context.getApplicationContext(), notificationId, intent, flag);
}
public void removeStatusMessage(Bundle bundle) {
String conversationId = bundle.getString("conversationId");
StatusMessageGroup group = this.messageGroups.get(conversationId);
NotificationManager notificationManager = notificationManager();
if (group == null) {
group = new StatusMessageGroup(conversationId);
}
this.messageGroups.put(conversationId, group);
String id = bundle.getString("id");
group.removeMessage(id);
this.showMessages(bundle);
}
public StatusMessageGroup getMessageGroup(String conversationId) {
return this.messageGroups.get(conversationId);
}
public void addStatusMessage(Bundle bundle) {
String conversationId = bundle.getString("conversationId");
StatusMessageGroup group = this.messageGroups.get(conversationId);
NotificationManager notificationManager = notificationManager();
if (group == null) {
group = new StatusMessageGroup(conversationId);
}
this.messageGroups.put(conversationId, group);
group.addMessage(createMessage(bundle));
this.showMessages(bundle);
}
public void showMessages(Bundle bundle) {
String conversationId = bundle.getString("conversationId");
StatusMessageGroup group = this.messageGroups.get(conversationId);
NotificationManager notificationManager = notificationManager();
NotificationCompat.MessagingStyle messagingStyle = new NotificationCompat.MessagingStyle("Me");
ArrayList<StatusMessage> messages = group.getMessages();
if (messages.size() == 0) {
notificationManager.cancel(conversationId.hashCode());
return;
}
for (int i = 0; i < messages.size(); i++) {
StatusMessage message = messages.get(i);
messagingStyle.addMessage(message.getText(),
message.getTimestamp(),
message.getAuthor());
}
if (bundle.getString("title") != null) {
messagingStyle.setConversationTitle(bundle.getString("title"));
}
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_stat_notify_status)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
.setStyle(messagingStyle)
.setGroup(conversationId)
.setOnlyAlertOnce(true)
.setGroupSummary(true)
.setContentIntent(createGroupOnTapIntent(context, conversationId.hashCode(), conversationId, bundle.getString("deepLink")))
.setDeleteIntent(createGroupOnDismissedIntent(context, conversationId.hashCode(), conversationId, bundle.getString("deepLink")))
.setNumber(messages.size() + 1)
.setAutoCancel(true);
if (Build.VERSION.SDK_INT >= 21) {
builder.setVibrate(new long[0]);
}
notificationManager.notify(conversationId.hashCode(), builder.build());
}
class StatusMessageGroup {
private ArrayList<StatusMessage> messages;
private String id;
StatusMessageGroup(String id) {
this.id = id;
this.messages = new ArrayList<StatusMessage>();
}
public ArrayList<StatusMessage> getMessages() {
return messages;
}
public void addMessage(StatusMessage message) {
this.messages.add(message);
}
public void removeMessage(String id) {
ArrayList<StatusMessage> newMessages = new ArrayList<StatusMessage>();
for(StatusMessage message: this.messages) {
if(!message.id.equals(id)) {
newMessages.add(message);
}
}
this.messages = newMessages;
}
public String getId() {
return this.id;
}
}
class StatusMessage {
public Person getAuthor() {
return author;
}
public long getTimestamp() {
return timestamp;
}
public String getText() {
return text;
}
private String id;
private Person author;
private long timestamp;
private String text;
StatusMessage(String id, Person author, long timestamp, String text) {
this.id = id;
this.author = author;
this.timestamp = timestamp;
this.text = text;
}
}
private void removeGroup(String groupId) {
this.messageGroups.remove(groupId);
}
private void cleanGroup(String groupId) {
removeGroup(groupId);
if (messageGroups.size() == 0) {
notificationManager.cancelAll();
}
}
public void start() {
Log.e(LOG_TAG, "Starting Foreground Service");
Intent serviceIntent = new Intent(context, ForegroundService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(serviceIntent);
} else {
context.startService(serviceIntent);
}
this.registerBroadcastReceiver();
}
public void stop() {
Log.e(LOG_TAG, "Stopping Foreground Service");
//NOTE: we cancel all the current notifications, because the intents can't be used anymore
//since the broadcast receiver will be killed as well and won't be able to handle any intent
notificationManager.cancelAll();
Intent serviceIntent = new Intent(context, ForegroundService.class);
context.stopService(serviceIntent);
context.unregisterReceiver(notificationActionReceiver);
}
}
@@ -1,750 +0,0 @@
// https://github.com/zo0r/react-native-push-notification/blob/bedc8f646aab67d594f291449fbfa24e07b64fe8/android/src/main/
// java/com/dieam/reactnativepushnotification/modules/RNPushNotificationHelper.java Copy-Paste with removed firebase
package im.status.ethereum.pushnotifications
import android.app.ActivityManager
import android.app.ActivityManager.RunningAppProcessInfo
import android.app.AlarmManager
import android.app.Application
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.BroadcastReceiver
import android.content.SharedPreferences
import android.content.pm.ApplicationInfo
import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Color
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.PorterDuff
import android.graphics.PorterDuffXfermode
import android.graphics.Rect
import android.graphics.RectF
import android.media.AudioAttributes
import android.media.RingtoneManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.service.notification.StatusBarNotification
import android.util.Log
import android.util.Base64
import androidx.annotation.RequiresApi
import androidx.core.app.NotificationCompat
import androidx.core.app.Person
import androidx.core.graphics.drawable.IconCompat
import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.ReadableArray
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.bridge.WritableArray
import com.facebook.react.bridge.WritableMap
import org.json.JSONArray
import org.json.JSONException
import im.status.ethereum.module.R
import im.status.ethereum.pushnotifications.PushNotification.Companion.LOG_TAG
class PushNotificationHelper(private val context: Application, private val intentFilter: IntentFilter) {
companion object {
private const val DEFAULT_VIBRATION: Long = 300L
private const val CHANNEL_ID = "status-im-notifications"
const val ACTION_DELETE_NOTIFICATION = "im.status.ethereum.module.DELETE_NOTIFICATION"
const val ACTION_TAP_STOP = "im.status.ethereum.module.TAP_STOP"
}
private val flag: Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE
} else {
PendingIntent.FLAG_CANCEL_CURRENT
}
private val notificationManager: NotificationManager by lazy {
context.getSystemService(NotificationManager::class.java)
}
private val persons: MutableMap<String, Person> = mutableMapOf()
private val messageGroups: MutableMap<String, StatusMessageGroup> = mutableMapOf()
init {
registerBroadcastReceiver()
}
private val notificationActionReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
when (intent.action) {
ACTION_DELETE_NOTIFICATION -> {
intent.extras?.getString("im.status.ethereum.groupId")?.let { groupId ->
cleanGroup(groupId)
}
}
ACTION_TAP_STOP -> {
stop()
System.exit(0)
}
}
Log.e(LOG_TAG, "intent received: ${intent.action}")
}
}
private fun registerBroadcastReceiver() {
intentFilter.apply {
addAction(ACTION_DELETE_NOTIFICATION)
addAction(ACTION_TAP_STOP)
}
context.registerReceiver(notificationActionReceiver, intentFilter, Context.RECEIVER_EXPORTED)
Log.e(LOG_TAG, "Broadcast Receiver registered")
}
fun getOpenAppIntent(deepLink: String?): Intent? {
val packageName = context.packageName
val launchIntent = context.packageManager.getLaunchIntentForPackage(packageName)
val className = launchIntent?.component?.className ?: return null
return try {
val intentClass = Class.forName(className)
Intent(context, intentClass).apply {
addCategory(Intent.CATEGORY_BROWSABLE)
action = Intent.ACTION_VIEW
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
deepLink?.let { data = Uri.parse(it) }
}
} catch (e: ClassNotFoundException) {
e.printStackTrace()
null
}
}
fun invokeApp(bundle: Bundle?) {
val packageName = context.packageName
val launchIntent = context.packageManager.getLaunchIntentForPackage(packageName)
val className = launchIntent?.component?.className ?: return
try {
val activityClass = Class.forName(className)
Intent(context, activityClass).apply {
bundle?.let { putExtra("notification", it) }
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(this)
}
} catch (e: ClassNotFoundException) {
Log.e(LOG_TAG, "Class not found", e)
}
}
fun getMainActivityClass(): Class<*>? {
val packageName = context.packageName
val launchIntent = context.packageManager.getLaunchIntentForPackage(packageName)
val className = launchIntent?.component?.className ?: return null
return try {
Class.forName(className)
} catch (e: ClassNotFoundException) {
e.printStackTrace()
null
}
}
fun isApplicationInForeground(): Boolean {
val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
val processInfos = activityManager.runningAppProcesses ?: return false
return processInfos.any { processInfo ->
processInfo.processName == context.packageName &&
processInfo.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND &&
processInfo.pkgList.isNotEmpty()
}
}
private fun getCircleBitmap(bitmap: Bitmap): Bitmap {
val output = Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(output)
val paint = Paint().apply {
isAntiAlias = true
color = Color.RED
}
val rect = Rect(0, 0, bitmap.width, bitmap.height)
val rectF = RectF(rect)
canvas.drawARGB(0, 0, 0, 0)
canvas.drawOval(rectF, paint)
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
canvas.drawBitmap(bitmap, rect, rect, paint)
bitmap.recycle()
return output
}
// Represents a message in a Status conversation
data class StatusMessage(
val id: String,
val author: Person,
val timestamp: Long,
val text: String
)
// Represents a group of messages in a Status conversation
inner class StatusMessageGroup(val id: String) {
private val _messages = mutableListOf<StatusMessage>()
val messages: List<StatusMessage> get() = _messages.toList()
fun addMessage(message: StatusMessage) {
_messages.add(message)
}
fun removeMessage(id: String) {
_messages.removeAll { it.id == id }
}
}
private fun getPerson(bundle: Bundle): Person {
return Person.Builder()
.setName(bundle.getString("name"))
.build()
}
private fun createMessage(data: Bundle): StatusMessage {
val author = getPerson(data.getBundle("notificationAuthor") ?: Bundle())
val timeStampLongValue = data.getDouble("timestamp").toLong()
return StatusMessage(
id = data.getString("id") ?: "",
author = author,
timestamp = timeStampLongValue,
text = data.getString("message") ?: ""
)
}
private fun createGroupOnDismissedIntent(
context: Context,
notificationId: Int,
groupId: String,
deepLink: String?
): PendingIntent {
return Intent(ACTION_DELETE_NOTIFICATION).apply {
putExtra("im.status.ethereum.deepLink", deepLink)
putExtra("im.status.ethereum.groupId", groupId)
}.let { intent ->
PendingIntent.getBroadcast(
context.applicationContext,
notificationId,
intent,
flag
)
}
}
private fun createGroupOnTapIntent(
context: Context,
notificationId: Int,
groupId: String,
deepLink: String?
): PendingIntent {
return getOpenAppIntent(deepLink)?.let { intent ->
PendingIntent.getActivity(
context.applicationContext,
notificationId,
intent,
flag
)
} ?: throw IllegalStateException("Could not create open app intent")
}
private fun createOnTapIntent(
context: Context,
notificationId: Int,
deepLink: String?
): PendingIntent {
return getOpenAppIntent(deepLink)?.let { intent ->
PendingIntent.getActivity(
context.applicationContext,
notificationId,
intent,
flag
)
} ?: throw IllegalStateException("Could not create open app intent")
}
private fun createOnDismissedIntent(
context: Context,
notificationId: Int,
deepLink: String?
): PendingIntent {
return Intent(ACTION_DELETE_NOTIFICATION).apply {
putExtra("im.status.ethereum.deepLink", deepLink)
}.let { intent ->
PendingIntent.getBroadcast(
context.applicationContext,
notificationId,
intent,
flag
)
}
}
fun removeStatusMessage(bundle: Bundle) {
val conversationId = bundle.getString("conversationId") ?: return
val group = messageGroups.getOrPut(conversationId) {
StatusMessageGroup(conversationId)
}
bundle.getString("id")?.let { id ->
group.removeMessage(id)
}
showMessages(bundle)
}
fun getMessageGroup(conversationId: String): StatusMessageGroup? {
return messageGroups[conversationId]
}
fun addStatusMessage(bundle: Bundle) {
val conversationId = bundle.getString("conversationId") ?: return
val group = messageGroups.getOrPut(conversationId) {
StatusMessageGroup(conversationId)
}
group.addMessage(createMessage(bundle))
showMessages(bundle)
}
fun showMessages(bundle: Bundle) {
val conversationId = bundle.getString("conversationId") ?: return
val group = messageGroups[conversationId] ?: return
val messagingStyle = NotificationCompat.MessagingStyle("Me")
// If there are no messages, cancel the notification and return
if (group.messages.isEmpty()) {
notificationManager.cancel(conversationId.hashCode())
return
}
group.messages.forEach { message ->
messagingStyle.addMessage(
message.text,
message.timestamp,
message.author
)
}
// Set conversation title if available
bundle.getString("title")?.let { title ->
messagingStyle.conversationTitle = title
}
val builder = NotificationCompat.Builder(context, CHANNEL_ID).apply {
setSmallIcon(R.drawable.ic_stat_notify_status)
setPriority(NotificationCompat.PRIORITY_HIGH)
setCategory(NotificationCompat.CATEGORY_MESSAGE)
setStyle(messagingStyle)
setGroup(conversationId)
setOnlyAlertOnce(true)
setGroupSummary(true)
setContentIntent(createGroupOnTapIntent(context, conversationId.hashCode(), conversationId, bundle.getString("deepLink")))
setDeleteIntent(createGroupOnDismissedIntent(context, conversationId.hashCode(), conversationId, bundle.getString("deepLink")))
setNumber(group.messages.size + 1)
setAutoCancel(true)
// Set empty vibration pattern for Android 5.0 and above
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
setVibrate(LongArray(0))
}
}
// Show the notification
notificationManager.notify(conversationId.hashCode(), builder.build())
}
fun checkOrCreateChannel(
manager: NotificationManager?,
channelId: String,
channelName: String?,
channelDescription: String?,
soundUri: Uri?,
importance: Int,
vibratePattern: LongArray?,
showBadge: Boolean
): Boolean {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O || manager == null) {
return false
}
val existingChannel = manager.getNotificationChannel(channelId)
val shouldCreateOrUpdate = when {
// Channel doesn't exist and we have required info
existingChannel == null && channelName != null && channelDescription != null -> true
// Channel exists but needs update
existingChannel != null && (
(channelName != null && existingChannel.name != channelName) ||
(channelDescription != null && existingChannel.description != channelDescription)
) -> true
else -> false
}
if (shouldCreateOrUpdate) {
NotificationChannel(channelId, channelName, importance).apply {
description = channelDescription
enableLights(true)
enableVibration(vibratePattern != null)
vibrationPattern = vibratePattern
setShowBadge(showBadge)
// Configure sound
if (soundUri != null) {
val audioAttributes = AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.build()
setSound(soundUri, audioAttributes)
} else {
setSound(null, null)
}
manager.createNotificationChannel(this)
}
return true
}
return false
}
fun createChannel(channelInfo: ReadableMap): Boolean {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
return false
}
return checkOrCreateChannel(
manager = notificationManager,
channelId = channelInfo.getString("channelId") ?: return false,
channelName = channelInfo.getString("channelName"),
channelDescription = if (channelInfo.hasKey("channelDescription")) {
channelInfo.getString("channelDescription")
} else "",
soundUri = getSoundUri(
if (channelInfo.hasKey("soundName")) {
channelInfo.getString("soundName")
} else "default"
),
importance = if (channelInfo.hasKey("importance")) {
channelInfo.getInt("importance")
} else 4,
vibratePattern = if (channelInfo.hasKey("vibrate") && channelInfo.getBoolean("vibrate")) {
longArrayOf(DEFAULT_VIBRATION)
} else null,
showBadge = channelInfo.hasKey("showBadge") && channelInfo.getBoolean("showBadge")
)
}
fun getNotificationDefaultChannelId(): String = CHANNEL_ID
private fun getSoundUri(soundName: String?): Uri {
return when {
soundName == null || soundName.equals("default", ignoreCase = true) -> {
RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
}
else -> {
val resources = context.resources
val packageName = context.packageName
val resId = when {
// Try to find the resource as is
resources.getIdentifier(soundName, "raw", packageName) != 0 -> {
resources.getIdentifier(soundName, "raw", packageName)
}
// Try without file extension
else -> {
val nameWithoutExtension = soundName.substringBeforeLast('.')
resources.getIdentifier(nameWithoutExtension, "raw", packageName)
}
}
Uri.parse("android.resource://$packageName/$resId")
}
}
}
private fun removeGroup(groupId: String) {
messageGroups.remove(groupId)
}
private fun cleanGroup(groupId: String) {
removeGroup(groupId)
if (messageGroups.isEmpty()) {
notificationManager.cancelAll()
}
}
fun start() {
Log.e(LOG_TAG, "Starting Foreground Service")
Intent(context, ForegroundService::class.java).also { serviceIntent ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(serviceIntent)
} else {
context.startService(serviceIntent)
}
}
registerBroadcastReceiver()
}
fun stop() {
Log.e(LOG_TAG, "Stopping Foreground Service")
// Cancel all current notifications since their intents won't be valid
// after the broadcast receiver is killed
notificationManager.cancelAll()
Intent(context, ForegroundService::class.java).also { serviceIntent ->
context.stopService(serviceIntent)
}
context.unregisterReceiver(notificationActionReceiver)
}
fun sendToNotificationCentre(bundle: Bundle) {
val aggregator = PushNotificationPicturesAggregator { largeIconImage, bigPictureImage ->
sendToNotificationCentreWithPicture(bundle, largeIconImage, bigPictureImage)
}
aggregator.apply {
setLargeIconUrl(context, bundle.getString("largeIconUrl"))
setBigPictureUrl(context, bundle.getString("bigPictureUrl"))
}
}
fun handleConversation(bundle: Bundle) {
if (bundle.getBoolean("deleted")) {
removeStatusMessage(bundle)
} else {
addStatusMessage(bundle)
}
}
fun clearMessageNotifications(conversationId: String) {
notificationManager.cancel(conversationId.hashCode())
cleanGroup(conversationId)
}
fun clearAllMessageNotifications() {
notificationManager.cancelAll()
}
fun sendToNotificationCentreWithPicture(
bundle: Bundle,
largeIconBitmap: Bitmap?,
bigPictureBitmap: Bitmap?
) {
try {
val intentClass = getMainActivityClass() ?: run {
Log.e(LOG_TAG, "No activity class found for the notification")
return
}
if (bundle.getBoolean("isConversation")) {
handleConversation(bundle)
return
}
if (bundle.getString("message") == null) {
Log.d(LOG_TAG, "Ignore this message if you sent data-only notification. " +
"Cannot send to notification centre because there is no 'message' field in: $bundle")
return
}
val notificationIdString = bundle.getString("id") ?: run {
Log.e(LOG_TAG, "No notification ID specified for the notification")
return
}
val resources = context.resources
val packageName = context.packageName
val title = bundle.getString("title") ?: run {
val appInfo = context.applicationInfo
context.packageManager.getApplicationLabel(appInfo).toString()
}
val priority = when (bundle.getString("priority")?.toLowerCase()) {
"max" -> NotificationCompat.PRIORITY_MAX
"high" -> NotificationCompat.PRIORITY_HIGH
"low" -> NotificationCompat.PRIORITY_LOW
"min" -> NotificationCompat.PRIORITY_MIN
"default" -> NotificationCompat.PRIORITY_DEFAULT
else -> NotificationCompat.PRIORITY_HIGH
}
val visibility = when (bundle.getString("visibility")?.toLowerCase()) {
"private" -> NotificationCompat.VISIBILITY_PRIVATE
"public" -> NotificationCompat.VISIBILITY_PUBLIC
"secret" -> NotificationCompat.VISIBILITY_SECRET
else -> NotificationCompat.VISIBILITY_PRIVATE
}
val channelId = bundle.getString("channelId") ?: getNotificationDefaultChannelId()
NotificationCompat.Builder(context, channelId).apply {
setContentTitle(title)
setTicker(bundle.getString("ticker"))
setVisibility(visibility)
setPriority(priority)
setAutoCancel(bundle.getBoolean("autoCancel", true))
setOnlyAlertOnce(bundle.getBoolean("onlyAlertOnce", false))
// Configure notification based on Android version
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
setShowWhen(bundle.getBoolean("showWhen", true))
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
setDefaults(Notification.DEFAULT_LIGHTS)
}
// Handle group settings for Android KitKat Watch and above
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
bundle.getString("group")?.let { group ->
setGroup(group)
}
if (bundle.containsKey("groupSummary") || bundle.getBoolean("groupSummary")) {
setGroupSummary(bundle.getBoolean("groupSummary"))
}
}
// Set notification number if provided
bundle.getString("number")?.toIntOrNull()?.let { number ->
setNumber(number)
}
val smallIconResId = findSmallIconResourceId(resources, packageName, bundle)
setSmallIcon(smallIconResId)
configureLargeIcon(this, largeIconBitmap, bundle, resources, packageName)
val message = bundle.getString("message") ?: ""
setContentText(message)
bundle.getString("subText")?.let { subText ->
setSubText(subText)
}
val bigText = bundle.getString("bigText") ?: message
val style = when {
bigPictureBitmap != null -> NotificationCompat.BigPictureStyle()
.bigPicture(bigPictureBitmap)
.setBigContentTitle(title)
.setSummaryText(message)
else -> NotificationCompat.BigTextStyle().bigText(bigText)
}
setStyle(style)
val notificationId = notificationIdString.hashCode()
setContentIntent(createOnTapIntent(context, notificationId, bundle.getString("deepLink")))
setDeleteIntent(createOnDismissedIntent(context, notificationId, bundle.getString("deepLink")))
configureSoundAndVibration(this, bundle)
setOngoing(bundle.getBoolean("ongoing", false))
// Handle color for Lollipop and above
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
setCategory(NotificationCompat.CATEGORY_CALL)
bundle.getString("color")?.let { color ->
setColor(Color.parseColor(color))
}
}
// Finally show the notification if conditions are met
if (!(isApplicationInForeground() && bundle.getBoolean("ignoreInForeground"))) {
val notification = build()
notification.defaults = notification.defaults or Notification.DEFAULT_LIGHTS
if (bundle.containsKey("tag")) {
notificationManager.notify(bundle.getString("tag"), notificationId, notification)
} else {
notificationManager.notify(notificationId, notification)
}
}
}
} catch (e: Exception) {
Log.e(LOG_TAG, "Failed to send push notification", e)
}
}
private fun findSmallIconResourceId(resources: Resources, packageName: String, bundle: Bundle): Int {
val smallIcon = bundle.getString("smallIcon")
return when {
!smallIcon.isNullOrEmpty() ->
resources.getIdentifier(smallIcon, "mipmap", packageName)
smallIcon == null ->
resources.getIdentifier("ic_stat_notify_status", "drawable", packageName)
else -> {
val defaultIcon = resources.getIdentifier("ic_launcher", "mipmap", packageName)
defaultIcon.takeIf { it != 0 } ?: android.R.drawable.ic_dialog_info
}
}
}
private fun configureLargeIcon(
builder: NotificationCompat.Builder,
largeIconBitmap: Bitmap?,
bundle: Bundle,
resources: Resources,
packageName: String
) {
var finalLargeIcon = largeIconBitmap
if (finalLargeIcon == null) {
val largeIcon = bundle.getString("largeIcon")
val largeIconResId = when {
!largeIcon.isNullOrEmpty() ->
resources.getIdentifier(largeIcon, "mipmap", packageName)
largeIcon == null ->
resources.getIdentifier("ic_launcher", "mipmap", packageName)
else -> 0
}
if (largeIconResId != 0 && (largeIcon != null || Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)) {
finalLargeIcon = BitmapFactory.decodeResource(resources, largeIconResId)
}
}
bundle.getBundle("notificationAuthor")?.getString("icon")?.let { icon ->
val base64Image = icon.split(",")[1]
val decodedString = Base64.decode(base64Image, Base64.DEFAULT)
val decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.size)
builder.setLargeIcon(getCircleBitmap(decodedByte))
} ?: finalLargeIcon?.let { icon ->
builder.setLargeIcon(icon)
}
}
private fun configureSoundAndVibration(
builder: NotificationCompat.Builder,
bundle: Bundle
) {
var soundUri: Uri? = null
if (!bundle.containsKey("playSound") || bundle.getBoolean("playSound")) {
val soundName = bundle.getString("soundName") ?: "default"
soundUri = getSoundUri(soundName)
builder.setSound(soundUri)
}
if (soundUri == null || Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder.setSound(null)
}
if (!bundle.containsKey("vibrate") || bundle.getBoolean("vibrate")) {
val vibration = if (bundle.containsKey("vibration")) {
bundle.getDouble("vibration").toLong()
} else DEFAULT_VIBRATION
val finalVibration = if (vibration == 0L) DEFAULT_VIBRATION else vibration
builder.setVibrate(longArrayOf(0, finalVibration))
}
}
}
@@ -0,0 +1,86 @@
package im.status.ethereum.pushnotifications;
import android.os.Build;
import android.app.Application;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Set;
import static im.status.ethereum.pushnotifications.PushNotification.LOG_TAG;
class PushNotificationJsDelivery {
private ReactContext reactContext;
PushNotificationJsDelivery(ReactContext context){
reactContext = context;
}
String convertJSON(Bundle bundle) {
try {
JSONObject json = convertJSONObject(bundle);
return json.toString();
} catch (JSONException e) {
return null;
}
}
// a Bundle is not a map, so we have to convert it explicitly
private JSONObject convertJSONObject(Bundle bundle) throws JSONException {
JSONObject json = new JSONObject();
Set<String> keys = bundle.keySet();
for (String key : keys) {
Object value = bundle.get(key);
if (value instanceof Bundle) {
json.put(key, convertJSONObject((Bundle)value));
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
json.put(key, JSONObject.wrap(value));
} else {
json.put(key, value);
}
}
return json;
}
void notifyNotification(Bundle bundle) {
String bundleString = convertJSON(bundle);
WritableMap params = Arguments.createMap();
params.putString("dataJSON", bundleString);
sendEvent("remoteNotificationReceived", params);
}
void notifyNotificationAction(Bundle bundle) {
String bundleString = convertJSON(bundle);
WritableMap params = Arguments.createMap();
params.putString("dataJSON", bundleString);
sendEvent("notificationActionReceived", params);
}
void sendEvent(String eventName, Object params) {
if (reactContext.hasActiveCatalystInstance()) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}
}
}
@@ -1,93 +0,0 @@
package im.status.ethereum.pushnotifications
import android.os.Build
import android.app.Application
import android.app.NotificationManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.Log
import com.facebook.react.bridge.ReactContext
import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.WritableMap
import com.facebook.react.modules.core.DeviceEventManagerModule
import org.json.JSONException
import org.json.JSONObject
import im.status.ethereum.pushnotifications.PushNotification.Companion.LOG_TAG
class PushNotificationJsDelivery(
private val reactContext: ReactContext
) {
/**
* Converts a Bundle to its JSON string representation.
* Returns null if conversion fails.
*/
fun convertJSON(bundle: Bundle): String? {
return try {
convertJSONObject(bundle).toString()
} catch (e: JSONException) {
null
}
}
/**
* Converts a Bundle to a JSONObject, handling nested bundles and different value types.
* This explicit conversion is necessary because Bundle is not a standard map.
*/
@Throws(JSONException::class)
private fun convertJSONObject(bundle: Bundle): JSONObject {
return JSONObject().apply {
// Using Kotlin's for loop syntax and 'apply' scope function
bundle.keySet().forEach { key ->
bundle.get(key)?.let { value ->
when (value) {
is Bundle -> put(key, convertJSONObject(value))
else -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
put(key, JSONObject.wrap(value))
} else {
put(key, value)
}
}
}
}
}
}
/**
* Notifies about a received remote notification by sending an event to JavaScript
*/
fun notifyNotification(bundle: Bundle) {
convertJSON(bundle)?.let { bundleString ->
Arguments.createMap().apply {
putString("dataJSON", bundleString)
sendEvent("remoteNotificationReceived", this)
}
}
}
/**
* Notifies about a notification action by sending an event to JavaScript
*/
fun notifyNotificationAction(bundle: Bundle) {
convertJSON(bundle)?.let { bundleString ->
Arguments.createMap().apply {
putString("dataJSON", bundleString)
sendEvent("notificationActionReceived", this)
}
}
}
/**
* Sends an event to JavaScript if there's an active Catalyst instance
*/
fun sendEvent(eventName: String, params: Any) {
if (reactContext.hasActiveCatalystInstance()) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit(eventName, params)
}
}
}
@@ -0,0 +1,27 @@
package im.status.ethereum.pushnotifications;
import im.status.ethereum.pushnotifications.PushNotification;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.Collections;
import java.util.List;
public class PushNotificationPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Collections.<NativeModule>singletonList(new PushNotification(reactContext));
}
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
@@ -1,24 +0,0 @@
package im.status.ethereum.pushnotifications
import im.status.ethereum.pushnotifications.PushNotification
import com.facebook.react.ReactPackage
import com.facebook.react.bridge.JavaScriptModule
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.uimanager.ViewManager
class PushNotificationPackage : ReactPackage {
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
return listOf(PushNotification(reactContext))
}
// Note: This function is deprecated in newer versions of React Native
// but kept for backwards compatibility
fun createJSModules(): List<Class<out JavaScriptModule>> {
return emptyList()
}
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
return emptyList()
}
}
@@ -0,0 +1,136 @@
package im.status.ethereum.pushnotifications;
import androidx.annotation.Nullable;
import com.facebook.common.executors.CallerThreadExecutor;
import com.facebook.common.references.CloseableReference;
import com.facebook.datasource.DataSource;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.imagepipeline.common.Priority;
import com.facebook.imagepipeline.core.ImagePipeline;
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber;
import com.facebook.imagepipeline.image.CloseableImage;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;
import android.util.Log;
import android.content.Context;
import android.graphics.Bitmap;
import android.net.Uri;
import java.util.concurrent.atomic.AtomicInteger;
import static im.status.ethereum.pushnotifications.PushNotification.LOG_TAG;
public class PushNotificationPicturesAggregator {
interface Callback {
public void call(Bitmap largeIconImage, Bitmap bigPictureImage);
}
private AtomicInteger count = new AtomicInteger(0);
private Bitmap largeIconImage;
private Bitmap bigPictureImage;
private Callback callback;
public PushNotificationPicturesAggregator(Callback callback) {
this.callback = callback;
}
public void setBigPicture(Bitmap bitmap) {
this.bigPictureImage = bitmap;
this.finished();
}
public void setBigPictureUrl(Context context, String url) {
if(null == url) {
this.setBigPicture(null);
return;
}
Uri uri = null;
try {
uri = Uri.parse(url);
} catch(Exception ex) {
Log.e(LOG_TAG, "Failed to parse bigPictureUrl", ex);
this.setBigPicture(null);
return;
}
final PushNotificationPicturesAggregator aggregator = this;
this.downloadRequest(context, uri, new BaseBitmapDataSubscriber() {
@Override
public void onNewResultImpl(@Nullable Bitmap bitmap) {
aggregator.setBigPicture(bitmap);
}
@Override
public void onFailureImpl(DataSource dataSource) {
aggregator.setBigPicture(null);
}
});
}
public void setLargeIcon(Bitmap bitmap) {
this.largeIconImage = bitmap;
this.finished();
}
public void setLargeIconUrl(Context context, String url) {
if(null == url) {
this.setLargeIcon(null);
return;
}
Uri uri = null;
try {
uri = Uri.parse(url);
} catch(Exception ex) {
Log.e(LOG_TAG, "Failed to parse largeIconUrl", ex);
this.setLargeIcon(null);
return;
}
final PushNotificationPicturesAggregator aggregator = this;
this.downloadRequest(context, uri, new BaseBitmapDataSubscriber() {
@Override
public void onNewResultImpl(@Nullable Bitmap bitmap) {
aggregator.setLargeIcon(bitmap);
}
@Override
public void onFailureImpl(DataSource dataSource) {
aggregator.setLargeIcon(null);
}
});
}
private void downloadRequest(Context context, Uri uri, BaseBitmapDataSubscriber subscriber) {
ImageRequest imageRequest = ImageRequestBuilder
.newBuilderWithSource(uri)
.setRequestPriority(Priority.HIGH)
.setLowestPermittedRequestLevel(ImageRequest.RequestLevel.FULL_FETCH)
.build();
if(!Fresco.hasBeenInitialized()) {
Fresco.initialize(context);
}
DataSource<CloseableReference<CloseableImage>> dataSource = Fresco.getImagePipeline().fetchDecodedImage(imageRequest, context);
dataSource.subscribe(subscriber, CallerThreadExecutor.getInstance());
}
private void finished() {
synchronized(this.count) {
int val = this.count.incrementAndGet();
if(val >= 2 && this.callback != null) {
this.callback.call(this.largeIconImage, this.bigPictureImage);
}
}
}
}
@@ -1,109 +0,0 @@
package im.status.ethereum.pushnotifications
import androidx.annotation.Nullable
import com.facebook.common.executors.CallerThreadExecutor
import com.facebook.common.references.CloseableReference
import com.facebook.datasource.DataSource
import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.imagepipeline.common.Priority
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber
import com.facebook.imagepipeline.image.CloseableImage
import com.facebook.imagepipeline.request.ImageRequest
import com.facebook.imagepipeline.request.ImageRequestBuilder
import android.util.Log
import android.content.Context
import android.graphics.Bitmap
import android.net.Uri
import java.util.concurrent.atomic.AtomicInteger
import im.status.ethereum.pushnotifications.PushNotification.Companion.LOG_TAG
class PushNotificationPicturesAggregator(
private val callback: (Bitmap?, Bitmap?) -> Unit
) {
private val count = AtomicInteger(0)
private var largeIconImage: Bitmap? = null
private var bigPictureImage: Bitmap? = null
fun setBigPicture(bitmap: Bitmap?) {
bigPictureImage = bitmap
finished()
}
fun setBigPictureUrl(context: Context, url: String?) {
if (url == null) {
setBigPicture(null)
return
}
val uri = try {
Uri.parse(url)
} catch (ex: Exception) {
Log.e(LOG_TAG, "Failed to parse bigPictureUrl", ex)
setBigPicture(null)
return
}
downloadRequest(context, uri, object : BaseBitmapDataSubscriber() {
override fun onNewResultImpl(@Nullable bitmap: Bitmap?) {
setBigPicture(bitmap)
}
override fun onFailureImpl(dataSource: DataSource<CloseableReference<CloseableImage>>) {
setBigPicture(null)
}
})
}
fun setLargeIcon(bitmap: Bitmap?) {
largeIconImage = bitmap
finished()
}
fun setLargeIconUrl(context: Context, url: String?) {
if (url == null) {
setLargeIcon(null)
return
}
val uri = try {
Uri.parse(url)
} catch (ex: Exception) {
Log.e(LOG_TAG, "Failed to parse largeIconUrl", ex)
setLargeIcon(null)
return
}
downloadRequest(context, uri, object : BaseBitmapDataSubscriber() {
override fun onNewResultImpl(@Nullable bitmap: Bitmap?) {
setLargeIcon(bitmap)
}
override fun onFailureImpl(dataSource: DataSource<CloseableReference<CloseableImage>>) {
setLargeIcon(null)
}
})
}
private fun downloadRequest(context: Context, uri: Uri, subscriber: BaseBitmapDataSubscriber) {
val imageRequest = ImageRequestBuilder
.newBuilderWithSource(uri)
.setRequestPriority(Priority.HIGH)
.setLowestPermittedRequestLevel(ImageRequest.RequestLevel.FULL_FETCH)
.build()
if (!Fresco.hasBeenInitialized()) {
Fresco.initialize(context)
}
val dataSource = Fresco.getImagePipeline().fetchDecodedImage(imageRequest, context)
dataSource.subscribe(subscriber, CallerThreadExecutor.getInstance())
}
private fun finished() {
synchronized(count) {
if (count.incrementAndGet() >= 2) {
callback(largeIconImage, bigPictureImage)
}
}
}
}
@@ -0,0 +1,54 @@
package im.status.ethereum.pushnotifications;
import org.junit.Test;
import static org.junit.Assert.*;
import android.app.Application;
import android.app.NotificationManager;
import android.os.Bundle;
import android.content.Intent;
import android.app.PendingIntent;
import android.content.IntentFilter;
import static org.mockito.Mockito.*;
import org.mockito.Spy;
public class PushNotificationHelperTest {
PushNotificationHelper helper;
@Test
public void testAddStatusMessage() {
final Application context = mock(Application.class);
final NotificationManager manager = mock(NotificationManager.class);
final IntentFilter filter = mock(IntentFilter.class);
when(context.getSystemService(NotificationManager.class)).thenReturn(manager);
// Create a spy for PushNotificationHelper
PushNotificationHelper realHelper = new PushNotificationHelper(context, filter);
helper = spy(realHelper);
Bundle bundle = mock(Bundle.class);
Bundle personBundle = mock(Bundle.class);
String conversationId = "conversation-id";
String deepLink = "deep-link";
when(bundle.getString("conversationId")).thenReturn(conversationId);
when(bundle.getString("id")).thenReturn("id");
when(bundle.getString("message")).thenReturn("message");
when(bundle.getDouble("timestamp")).thenReturn(100000.0);
when(bundle.getString("deepLink")).thenReturn(deepLink);
when(personBundle.getString("name")).thenReturn("name");
when(bundle.getBundle("notificationAuthor")).thenReturn(personBundle);
doNothing().when(helper).showMessages(bundle);
helper.addStatusMessage(bundle);
assertNotNull(helper.getMessageGroup(conversationId));
}
}
@@ -1,49 +0,0 @@
package im.status.ethereum.pushnotifications
import android.app.Application
import android.app.NotificationManager
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import org.junit.Assert.assertNotNull
import org.junit.Test
import org.mockito.Mockito.*
import org.mockito.Spy
class PushNotificationHelperTest {
private lateinit var helper: PushNotificationHelper
@Test
fun testAddStatusMessage() {
val context = mock(Application::class.java)
val manager = mock(NotificationManager::class.java)
val filter = mock(IntentFilter::class.java)
`when`(context.getSystemService(NotificationManager::class.java)).thenReturn(manager)
// Create a spy for PushNotificationHelper
val realHelper = PushNotificationHelper(context, filter)
helper = spy(realHelper)
val bundle = mock(Bundle::class.java)
val personBundle = mock(Bundle::class.java)
val conversationId = "conversation-id"
val deepLink = "deep-link"
`when`(bundle.getString("conversationId")).thenReturn(conversationId)
`when`(bundle.getString("id")).thenReturn("id")
`when`(bundle.getString("message")).thenReturn("message")
`when`(bundle.getDouble("timestamp")).thenReturn(100000.0)
`when`(bundle.getString("deepLink")).thenReturn(deepLink)
`when`(personBundle.getString("name")).thenReturn("name")
`when`(bundle.getBundle("notificationAuthor")).thenReturn(personBundle)
doNothing().`when`(helper).showMessages(bundle)
helper.addStatusMessage(bundle)
assertNotNull(helper.getMessageGroup(conversationId))
}
}
@@ -195,6 +195,36 @@ RCT_EXPORT_METHOD(loginAccount:(NSString *)request) {
}];
}
RCT_EXPORT_METHOD(verify:(NSString *)address
password:(NSString *)password
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
NSLog(@"VerifyAccountPasswordV2() method called");
#endif
NSURL *rootUrl = [Utils getRootUrl];
NSString *keystorePath = [rootUrl.path stringByAppendingPathComponent:@"keystore"];
NSDictionary *params = @{
@"keyStoreDir": keystorePath,
@"address": address,
@"password": password
};
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
if (error) {
NSLog(@"Error creating JSON: %@", error);
return;
}
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
[StatusBackendClient executeStatusGoRequestWithCallback:@"VerifyAccountPasswordV2"
body:jsonString
statusgoFunction:^NSString *{
return StatusgoVerifyAccountPasswordV2(jsonString);
}
callback:callback];
}
RCT_EXPORT_METHOD(verifyDatabasePassword:(NSString *)keyUID
password:(NSString *)password
callback:(RCTResponseSenderBlock)callback) {
@@ -105,6 +105,48 @@ RCT_EXPORT_METHOD(convertToKeycardAccount:(NSString *)keyUID
callback:callback];
}
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(encodeTransfer:(NSString *)to
value:(NSString *)value) {
NSDictionary *params = @{
@"to": to,
@"value": value
};
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
if (error) {
NSLog(@"Error creating JSON: %@", [error localizedDescription]);
return nil;
}
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
return [StatusBackendClient executeStatusGoRequestWithResult:@"EncodeTransferV2"
body:jsonString
statusgoFunction:^NSString *{
return StatusgoEncodeTransferV2(jsonString);
}];
}
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(encodeFunctionCall:(NSString *)method
paramsJSON:(NSString *)paramsJSON) {
NSDictionary *params = @{
@"method": method,
@"paramsJSON": paramsJSON
};
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
if (error) {
NSLog(@"Error creating JSON: %@", [error localizedDescription]);
return nil;
}
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
return [StatusBackendClient executeStatusGoRequestWithResult:@"EncodeFunctionCallV2"
body:jsonString
statusgoFunction:^NSString *{
return StatusgoEncodeFunctionCallV2(jsonString);
}];
}
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(decodeParameters:(NSString *)decodeParamJSON) {
return [StatusBackendClient executeStatusGoRequestWithResult:@"DecodeParameters"
body:decodeParamJSON
@@ -35,9 +35,8 @@ RCT_EXPORT_METHOD(sendLogs:(NSString *)dbJson
NSURL *mainGethLogsFile = [rootUrl URLByAppendingPathComponent:@"geth.log"];
NSURL *mainLogsFile = [logsFolderName URLByAppendingPathComponent:@"geth.log"];
NSURL *preLoginLogFile = [rootUrl URLByAppendingPathComponent:@"pre_login.log"];
NSURL *requestsLogFile = [rootUrl URLByAppendingPathComponent:@"api.log"];
NSURL *requestsLogFile = [rootUrl URLByAppendingPathComponent:@"requests.log"];
[dbJson writeToFile:dbFile.path atomically:YES encoding:NSUTF8StringEncoding error:nil];
[jsLogs writeToFile:jsLogsFile.path atomically:YES encoding:NSUTF8StringEncoding error:nil];
@@ -45,11 +44,7 @@ RCT_EXPORT_METHOD(sendLogs:(NSString *)dbJson
[fileManager copyItemAtPath:mainGethLogsFile.path toPath:mainLogsFile.path error:nil];
if ([fileManager fileExistsAtPath:requestsLogFile.path]) {
[fileManager copyItemAtPath:requestsLogFile.path toPath:[logsFolderName URLByAppendingPathComponent:@"api.log"].path error:nil];
}
if ([fileManager fileExistsAtPath:preLoginLogFile.path]) {
[fileManager copyItemAtPath:preLoginLogFile.path toPath:[logsFolderName URLByAppendingPathComponent:@"pre_login.log"].path error:nil];
[fileManager copyItemAtPath:requestsLogFile.path toPath:[logsFolderName URLByAppendingPathComponent:@"requests.log"].path error:nil];
}
[SSZipArchive createZipFileAtPath:zipFile.path withContentsOfDirectory:logsFolderName.path];
@@ -58,6 +53,43 @@ RCT_EXPORT_METHOD(sendLogs:(NSString *)dbJson
callback(@[zipFile.absoluteString]);
}
RCT_EXPORT_METHOD(initLogging:(BOOL)enabled
mobileSystem:(BOOL)mobileSystem
logLevel:(NSString *)logLevel
logRequestGo:(BOOL)logRequestGo
callback:(RCTResponseSenderBlock)callback)
{
NSString *logDirectory = [self logFileDirectory];
NSString *logFilePath = [logDirectory stringByAppendingPathComponent:@"geth.log"];
NSString *logRequestFilePath = [logDirectory stringByAppendingPathComponent:@"requests.log"];
NSDictionary *config = @{
@"Enabled": @(enabled),
@"MobileSystem": @(mobileSystem),
@"Level": logLevel,
@"File": logFilePath,
@"LogRequestGo": @(logRequestGo),
@"LogRequestFile": logRequestFilePath
};
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:config options:0 error:&error];
if (error) {
NSLog(@"Error creating JSON: %@", [error localizedDescription]);
return;
}
NSString *configJson = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
[StatusBackendClient executeStatusGoRequestWithCallback:@"InitLogging"
body:configJson
statusgoFunction:^NSString *{
return StatusgoInitLogging(configJson);
}
callback:callback];
}
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(logFileDirectory) {
NSURL *rootUrl = [Utils getRootUrl];
return rootUrl.path;
@@ -8,7 +8,6 @@
NSString *_statusGoEndpoint;
NSString *_signalEndpoint;
NSString *_rootDataDir;
NSTimer *_pingTimer;
}
RCT_EXPORT_MODULE();
@@ -78,8 +77,6 @@ RCT_EXPORT_MODULE();
[self.webSocket resume];
[self receiveMessage];
[self startPingTimer];
}
- (void)receiveMessage {
@@ -112,7 +109,6 @@ RCT_EXPORT_MODULE();
}
- (void)disconnectWebSocket {
[self stopPingTimer];
if (self.webSocket) {
[self.webSocket cancel];
self.webSocket = nil;
@@ -123,7 +119,6 @@ RCT_EXPORT_MODULE();
body:(NSString *)body
callback:(void (^)(NSString *response, NSError *error))callback {
NSString *fullUrlString = [NSString stringWithFormat:@"%@%@", self.statusGoEndpoint, endpoint];
NSLog(@"StatusGo server is enabled, executing request, endpoint: %@, body: %@", fullUrlString, body);
NSURL *url = [NSURL URLWithString:fullUrlString];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
request.HTTPMethod = @"POST";
@@ -230,6 +225,7 @@ RCT_EXPORT_METHOD(configStatusBackendServer:(BOOL)serverEnabled
if (client.serverEnabled) {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
__block NSString *resultString = @"";
[client request:endpoint body:body callback:^(NSString *response, NSError *error) {
if (error) {
NSLog(@"request to %@ failed: %@", endpoint, error);
@@ -247,33 +243,4 @@ RCT_EXPORT_METHOD(configStatusBackendServer:(BOOL)serverEnabled
}
}
- (void)startPingTimer {
[self stopPingTimer];
_pingTimer = [NSTimer scheduledTimerWithTimeInterval:30.0
target:self
selector:@selector(sendPing)
userInfo:nil
repeats:YES];
}
- (void)stopPingTimer {
if (_pingTimer) {
[_pingTimer invalidate];
_pingTimer = nil;
}
}
- (void)sendPing {
if (self.webSocket) {
[self.webSocket sendPingWithPongReceiveHandler:^(NSError * _Nullable error) {
if (error) {
NSLog(@"WebSocket ping failed: %@", error);
// Reconnect on ping failure
[self disconnectWebSocket];
[self connectWebSocket];
}
}];
}
}
@end
@@ -389,6 +389,86 @@ void _StopCPUProfiling(const FunctionCallbackInfo<Value>& args) {
}
void _EncodeTransfer(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
if (args.Length() != 2) {
// Throw an Error that is passed back to JavaScript
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8Literal(isolate, "Wrong number of arguments for EncodeTransfer")));
return;
}
// Check the argument types
if (!args[0]->IsString()) {
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'to'")));
return;
}
if (!args[1]->IsString()) {
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'value'")));
return;
}
String::Utf8Value arg0Obj(isolate, args[0]->ToString(context).ToLocalChecked());
char *arg0 = *arg0Obj;
String::Utf8Value arg1Obj(isolate, args[1]->ToString(context).ToLocalChecked());
char *arg1 = *arg1Obj;
// Call exported Go function, which returns a C string
char *c = EncodeTransfer(arg0, arg1);
Local<String> ret = String::NewFromUtf8(isolate, c).ToLocalChecked();
args.GetReturnValue().Set(ret);
delete c;
}
void _EncodeFunctionCall(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
if (args.Length() != 2) {
// Throw an Error that is passed back to JavaScript
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8Literal(isolate, "Wrong number of arguments for EncodeFunctionCall")));
return;
}
// Check the argument types
if (!args[0]->IsString()) {
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'method'")));
return;
}
if (!args[1]->IsString()) {
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'paramsJSON'")));
return;
}
String::Utf8Value arg0Obj(isolate, args[0]->ToString(context).ToLocalChecked());
char *arg0 = *arg0Obj;
String::Utf8Value arg1Obj(isolate, args[1]->ToString(context).ToLocalChecked());
char *arg1 = *arg1Obj;
// Call exported Go function, which returns a C string
char *c = EncodeFunctionCall(arg0, arg1);
Local<String> ret = String::NewFromUtf8(isolate, c).ToLocalChecked();
args.GetReturnValue().Set(ret);
delete c;
}
void _DecodeParameters(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
@@ -1300,6 +1380,53 @@ void _CallPrivateRPC(const FunctionCallbackInfo<Value>& args) {
}
void _VerifyAccountPassword(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
if (args.Length() != 3) {
// Throw an Error that is passed back to JavaScript
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8Literal(isolate, "Wrong number of arguments for VerifyAccountPassword")));
return;
}
// Check the argument types
if (!args[0]->IsString()) {
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'keyStoreDir'")));
return;
}
if (!args[1]->IsString()) {
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'address'")));
return;
}
if (!args[2]->IsString()) {
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'password'")));
return;
}
String::Utf8Value arg0Obj(isolate, args[0]->ToString(context).ToLocalChecked());
char *arg0 = *arg0Obj;
String::Utf8Value arg1Obj(isolate, args[1]->ToString(context).ToLocalChecked());
char *arg1 = *arg1Obj;
String::Utf8Value arg2Obj(isolate, args[2]->ToString(context).ToLocalChecked());
char *arg2 = *arg2Obj;
// Call exported Go function, which returns a C string
char *c = VerifyAccountPassword(arg0, arg1, arg2);
Local<String> ret = String::NewFromUtf8(isolate, c).ToLocalChecked();
args.GetReturnValue().Set(ret);
delete c;
}
void _SendTransactionWithSignature(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
@@ -1819,6 +1946,35 @@ void _ConnectionChange(const FunctionCallbackInfo<Value>& args) {
ConnectionChange(arg0, arg1);
}
void _InitLogging(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
if (args.Length() != 1) {
// Throw an Error that is passed back to JavaScript
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8Literal(isolate, "Wrong number of arguments for InitLogging")));
return;
}
// Check the argument types
if (!args[0]->IsString()) {
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'logSettingsJSON'")));
return;
}
String::Utf8Value arg0Obj(isolate, args[0]->ToString(context).ToLocalChecked());
char *arg0 = *arg0Obj;
// Call exported Go function, which returns a C string
char *c = InitLogging(arg0);
Local<String> ret = String::NewFromUtf8(isolate, c).ToLocalChecked();
args.GetReturnValue().Set(ret);
delete c;
}
void _RestoreAccountAndLogin(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
@@ -1865,6 +2021,8 @@ void init(Local<Object> exports) {
NODE_SET_METHOD(exports, "acceptTerms", _AcceptTerms);
NODE_SET_METHOD(exports, "fleets", _Fleets);
NODE_SET_METHOD(exports, "stopCPUProfiling", _StopCPUProfiling);
NODE_SET_METHOD(exports, "encodeTransfer", _EncodeTransfer);
NODE_SET_METHOD(exports, "encodeFunctionCall", _EncodeFunctionCall);
NODE_SET_METHOD(exports, "decodeParameters", _DecodeParameters);
NODE_SET_METHOD(exports, "hexToNumber", _HexToNumber);
NODE_SET_METHOD(exports, "numberToHex", _NumberToHex);
@@ -1888,6 +2046,7 @@ void init(Local<Object> exports) {
NODE_SET_METHOD(exports, "openAccounts", _OpenAccounts);
NODE_SET_METHOD(exports, "extractGroupMembershipSignatures", _ExtractGroupMembershipSignatures);
NODE_SET_METHOD(exports, "callPrivateRPC", _CallPrivateRPC);
NODE_SET_METHOD(exports, "verifyAccountPassword", _VerifyAccountPassword);
NODE_SET_METHOD(exports, "sendTransactionWithSignature", _SendTransactionWithSignature);
NODE_SET_METHOD(exports, "writeHeapProfile", _WriteHeapProfile);
NODE_SET_METHOD(exports, "addPeer", _AddPeer);
@@ -1905,6 +2064,7 @@ void init(Local<Object> exports) {
NODE_SET_METHOD(exports, "hashTransaction", _HashTransaction);
NODE_SET_METHOD(exports, "connectionChange", _ConnectionChange);
NODE_SET_METHOD(exports, "pollSignal", _PollSignal);
NODE_SET_METHOD(exports, "initLogging", _InitLogging);
NODE_SET_METHOD(exports, "restoreAccountAndLogin", _RestoreAccountAndLogin);
}
+2748 -3481
View File
File diff suppressed because it is too large Load Diff
+208 -232
View File
@@ -5,13 +5,11 @@ androidx.activity:activity:1.6.0
androidx.annotation:annotation-experimental:1.1.0
androidx.annotation:annotation-experimental:1.3.0
androidx.annotation:annotation-jvm:1.6.0
androidx.annotation:annotation-jvm:1.7.0
androidx.annotation:annotation:1.0.0
androidx.annotation:annotation:1.1.0
androidx.annotation:annotation:1.2.0
androidx.annotation:annotation:1.3.0
androidx.annotation:annotation:1.6.0
androidx.annotation:annotation:1.7.0
androidx.appcompat:appcompat-resources:1.1.0-rc01
androidx.appcompat:appcompat-resources:1.2.0
androidx.appcompat:appcompat-resources:1.3.1
@@ -37,6 +35,7 @@ androidx.cardview:cardview:1.0.0
androidx.collection:collection:1.0.0
androidx.collection:collection:1.1.0
androidx.concurrent:concurrent-futures:1.0.0
androidx.concurrent:concurrent-futures:1.1.0
androidx.constraintlayout:constraintlayout-solver:2.0.4
androidx.constraintlayout:constraintlayout:2.0.4
androidx.coordinatorlayout:coordinatorlayout:1.0.0
@@ -61,8 +60,7 @@ androidx.databinding:databinding-common:7.0.4
androidx.databinding:databinding-common:7.2.1
androidx.databinding:databinding-common:7.3.1
androidx.databinding:databinding-common:7.4.2
androidx.databinding:databinding-common:8.3.1
androidx.databinding:databinding-common:8.5.0
androidx.databinding:databinding-common:8.1.1
androidx.databinding:databinding-compiler-common:3.2.1
androidx.databinding:databinding-compiler-common:3.5.3
androidx.databinding:databinding-compiler-common:4.1.0
@@ -70,18 +68,7 @@ androidx.databinding:databinding-compiler-common:7.0.4
androidx.databinding:databinding-compiler-common:7.2.1
androidx.databinding:databinding-compiler-common:7.3.1
androidx.databinding:databinding-compiler-common:7.4.2
androidx.databinding:databinding-compiler-common:8.3.1
androidx.databinding:databinding-compiler-common:8.5.0
androidx.datastore:datastore-android:1.1.1
androidx.datastore:datastore-core-android:1.1.1
androidx.datastore:datastore-core-okio-jvm:1.1.1
androidx.datastore:datastore-core-okio:1.1.1
androidx.datastore:datastore-core:1.1.1
androidx.datastore:datastore-preferences-android:1.1.1
androidx.datastore:datastore-preferences-core-jvm:1.1.1
androidx.datastore:datastore-preferences-core:1.1.1
androidx.datastore:datastore-preferences:1.1.1
androidx.datastore:datastore:1.1.1
androidx.databinding:databinding-compiler-common:8.1.1
androidx.documentfile:documentfile:1.0.0
androidx.drawerlayout:drawerlayout:1.0.0
androidx.emoji2:emoji2-views-helper:1.2.0
@@ -139,6 +126,12 @@ androidx.startup:startup-runtime:1.1.1
androidx.swiperefreshlayout:swiperefreshlayout:1.0.0
androidx.swiperefreshlayout:swiperefreshlayout:1.1.0
androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha02
androidx.test.ext:junit:1.1.4-alpha05
androidx.test.services:storage:1.4.2-alpha02
androidx.test:annotation:1.0.0
androidx.test:core:1.4.1-alpha05
androidx.test:monitor:1.6.0-alpha02
androidx.test:runner:1.5.0-alpha02
androidx.tracing:tracing:1.1.0
androidx.transition:transition:1.1.0
androidx.transition:transition:1.2.0
@@ -162,13 +155,14 @@ commons-codec:commons-codec:1.9
commons-codec:commons-codec:1.10
commons-codec:commons-codec:1.11
commons-io:commons-io:2.4
commons-io:commons-io:2.13.0
commons-logging:commons-logging:1.1.1
commons-logging:commons-logging:1.2
com.adarshr:gradle-test-logger-plugin:2.0.0
com.adobe.xmp:xmpcore:6.1.11
com.afollestad.material-dialogs:commons:0.9.6.0
com.afollestad.material-dialogs:core:0.9.6.0
com.airbnb.android:lottie:3.4.4
com.almworks.sqlite4java:sqlite4java:1.0.392
com.android.databinding:baseLibrary:1.0-rc5
com.android.databinding:baseLibrary:3.0.1
com.android.databinding:baseLibrary:3.2.1
@@ -178,8 +172,7 @@ com.android.databinding:baseLibrary:7.0.4
com.android.databinding:baseLibrary:7.2.1
com.android.databinding:baseLibrary:7.3.1
com.android.databinding:baseLibrary:7.4.2
com.android.databinding:baseLibrary:8.3.1
com.android.databinding:baseLibrary:8.5.0
com.android.databinding:baseLibrary:8.1.1
com.android.databinding:compilerCommon:1.0-rc5
com.android.databinding:compilerCommon:3.0.1
com.android.tools.analytics-library:crash:26.2.1
@@ -189,8 +182,7 @@ com.android.tools.analytics-library:crash:30.0.4
com.android.tools.analytics-library:crash:30.2.1
com.android.tools.analytics-library:crash:30.3.1
com.android.tools.analytics-library:crash:30.4.2
com.android.tools.analytics-library:crash:31.3.1
com.android.tools.analytics-library:crash:31.5.0
com.android.tools.analytics-library:crash:31.1.1
com.android.tools.analytics-library:protos:26.0.1
com.android.tools.analytics-library:protos:26.2.1
com.android.tools.analytics-library:protos:26.5.3
@@ -199,8 +191,7 @@ com.android.tools.analytics-library:protos:30.0.4
com.android.tools.analytics-library:protos:30.2.1
com.android.tools.analytics-library:protos:30.3.1
com.android.tools.analytics-library:protos:30.4.2
com.android.tools.analytics-library:protos:31.3.1
com.android.tools.analytics-library:protos:31.5.0
com.android.tools.analytics-library:protos:31.1.1
com.android.tools.analytics-library:shared:26.0.1
com.android.tools.analytics-library:shared:26.2.1
com.android.tools.analytics-library:shared:26.5.3
@@ -209,8 +200,7 @@ com.android.tools.analytics-library:shared:30.0.4
com.android.tools.analytics-library:shared:30.2.1
com.android.tools.analytics-library:shared:30.3.1
com.android.tools.analytics-library:shared:30.4.2
com.android.tools.analytics-library:shared:31.3.1
com.android.tools.analytics-library:shared:31.5.0
com.android.tools.analytics-library:shared:31.1.1
com.android.tools.analytics-library:tracker:26.0.1
com.android.tools.analytics-library:tracker:26.2.1
com.android.tools.analytics-library:tracker:26.5.3
@@ -219,8 +209,7 @@ com.android.tools.analytics-library:tracker:30.0.4
com.android.tools.analytics-library:tracker:30.2.1
com.android.tools.analytics-library:tracker:30.3.1
com.android.tools.analytics-library:tracker:30.4.2
com.android.tools.analytics-library:tracker:31.3.1
com.android.tools.analytics-library:tracker:31.5.0
com.android.tools.analytics-library:tracker:31.1.1
com.android.tools.build.jetifier:jetifier-core:1.0.0-alpha10
com.android.tools.build.jetifier:jetifier-core:1.0.0-beta04
com.android.tools.build.jetifier:jetifier-core:1.0.0-beta09
@@ -236,16 +225,14 @@ com.android.tools.build:aapt2-proto:7.0.4-7396180
com.android.tools.build:aapt2-proto:7.2.1-7984345
com.android.tools.build:aapt2-proto:7.3.1-8691043
com.android.tools.build:aapt2-proto:7.4.2-8841542
com.android.tools.build:aapt2-proto:8.3.1-10880808
com.android.tools.build:aapt2-proto:8.5.0-11315950
com.android.tools.build:aapt2-proto:8.1.1-10154469
com.android.tools.build:aapt2:8.1.1-10154469
com.android.tools.build:aaptcompiler:4.1.0
com.android.tools.build:aaptcompiler:7.0.4
com.android.tools.build:aaptcompiler:7.2.1
com.android.tools.build:aaptcompiler:7.3.1
com.android.tools.build:aaptcompiler:7.4.2
com.android.tools.build:aaptcompiler:8.3.1
com.android.tools.build:aaptcompiler:8.5.0
com.android.tools.build:aaptcompiler:8.1.1
com.android.tools.build:apksig:3.0.1
com.android.tools.build:apksig:3.2.1
com.android.tools.build:apksig:3.5.3
@@ -254,8 +241,7 @@ com.android.tools.build:apksig:7.0.4
com.android.tools.build:apksig:7.2.1
com.android.tools.build:apksig:7.3.1
com.android.tools.build:apksig:7.4.2
com.android.tools.build:apksig:8.3.1
com.android.tools.build:apksig:8.5.0
com.android.tools.build:apksig:8.1.1
com.android.tools.build:apkzlib:3.2.1
com.android.tools.build:apkzlib:3.5.3
com.android.tools.build:apkzlib:4.1.0
@@ -263,8 +249,7 @@ com.android.tools.build:apkzlib:7.0.4
com.android.tools.build:apkzlib:7.2.1
com.android.tools.build:apkzlib:7.3.1
com.android.tools.build:apkzlib:7.4.2
com.android.tools.build:apkzlib:8.3.1
com.android.tools.build:apkzlib:8.5.0
com.android.tools.build:apkzlib:8.1.1
com.android.tools.build:builder-model:1.3.1
com.android.tools.build:builder-model:1.5.0
com.android.tools.build:builder-model:3.0.1
@@ -275,8 +260,7 @@ com.android.tools.build:builder-model:7.0.4
com.android.tools.build:builder-model:7.2.1
com.android.tools.build:builder-model:7.3.1
com.android.tools.build:builder-model:7.4.2
com.android.tools.build:builder-model:8.3.1
com.android.tools.build:builder-model:8.5.0
com.android.tools.build:builder-model:8.1.1
com.android.tools.build:builder-test-api:1.3.1
com.android.tools.build:builder-test-api:1.5.0
com.android.tools.build:builder-test-api:3.0.1
@@ -287,8 +271,7 @@ com.android.tools.build:builder-test-api:7.0.4
com.android.tools.build:builder-test-api:7.2.1
com.android.tools.build:builder-test-api:7.3.1
com.android.tools.build:builder-test-api:7.4.2
com.android.tools.build:builder-test-api:8.3.1
com.android.tools.build:builder-test-api:8.5.0
com.android.tools.build:builder-test-api:8.1.1
com.android.tools.build:builder:1.3.1
com.android.tools.build:builder:1.5.0
com.android.tools.build:builder:3.0.1
@@ -299,8 +282,7 @@ com.android.tools.build:builder:7.0.4
com.android.tools.build:builder:7.2.1
com.android.tools.build:builder:7.3.1
com.android.tools.build:builder:7.4.2
com.android.tools.build:builder:8.3.1
com.android.tools.build:builder:8.5.0
com.android.tools.build:builder:8.1.1
com.android.tools.build:bundletool:0.5.0
com.android.tools.build:bundletool:0.9.0
com.android.tools.build:bundletool:0.14.0
@@ -308,8 +290,7 @@ com.android.tools.build:bundletool:1.6.0
com.android.tools.build:bundletool:1.8.2
com.android.tools.build:bundletool:1.9.0
com.android.tools.build:bundletool:1.11.4
com.android.tools.build:bundletool:1.15.6
com.android.tools.build:bundletool:1.16.0
com.android.tools.build:bundletool:1.14.0
com.android.tools.build:gradle-api:3.0.1
com.android.tools.build:gradle-api:3.2.1
com.android.tools.build:gradle-api:3.5.3
@@ -318,14 +299,12 @@ com.android.tools.build:gradle-api:7.0.4
com.android.tools.build:gradle-api:7.2.1
com.android.tools.build:gradle-api:7.3.1
com.android.tools.build:gradle-api:7.4.2
com.android.tools.build:gradle-api:8.3.1
com.android.tools.build:gradle-api:8.5.0
com.android.tools.build:gradle-api:8.1.1
com.android.tools.build:gradle-core:1.3.1
com.android.tools.build:gradle-core:1.5.0
com.android.tools.build:gradle-core:3.0.1
com.android.tools.build:gradle-settings-api:7.4.2
com.android.tools.build:gradle-settings-api:8.3.1
com.android.tools.build:gradle-settings-api:8.5.0
com.android.tools.build:gradle-settings-api:8.1.1
com.android.tools.build:gradle:1.3.1
com.android.tools.build:gradle:1.5.0
com.android.tools.build:gradle:3.0.1
@@ -336,8 +315,7 @@ com.android.tools.build:gradle:7.0.4
com.android.tools.build:gradle:7.2.1
com.android.tools.build:gradle:7.3.1
com.android.tools.build:gradle:7.4.2
com.android.tools.build:gradle:8.3.1
com.android.tools.build:gradle:8.5.0
com.android.tools.build:gradle:8.1.1
com.android.tools.build:manifest-merger:24.3.1
com.android.tools.build:manifest-merger:24.5.0
com.android.tools.build:manifest-merger:26.0.1
@@ -348,8 +326,7 @@ com.android.tools.build:manifest-merger:30.0.4
com.android.tools.build:manifest-merger:30.2.1
com.android.tools.build:manifest-merger:30.3.1
com.android.tools.build:manifest-merger:30.4.2
com.android.tools.build:manifest-merger:31.3.1
com.android.tools.build:manifest-merger:31.5.0
com.android.tools.build:manifest-merger:31.1.1
com.android.tools.build:transform-api:1.5.0
com.android.tools.build:transform-api:2.0.0-deprecated-use-gradle-api
com.android.tools.ddms:ddmlib:24.3.1
@@ -362,9 +339,8 @@ com.android.tools.ddms:ddmlib:30.0.4
com.android.tools.ddms:ddmlib:30.2.1
com.android.tools.ddms:ddmlib:30.3.1
com.android.tools.ddms:ddmlib:30.4.2
com.android.tools.ddms:ddmlib:31.3.1
com.android.tools.ddms:ddmlib:31.5.0
com.android.tools.emulator:proto:31.5.0
com.android.tools.ddms:ddmlib:31.1.1
com.android.tools.emulator:proto:31.1.1
com.android.tools.external.com-intellij:intellij-core:26.0.1
com.android.tools.external.lombok:lombok-ast:0.2.3
com.android.tools.external.org-jetbrains:uast:26.0.1
@@ -380,8 +356,7 @@ com.android.tools.layoutlib:layoutlib-api:30.0.4
com.android.tools.layoutlib:layoutlib-api:30.2.1
com.android.tools.layoutlib:layoutlib-api:30.3.1
com.android.tools.layoutlib:layoutlib-api:30.4.2
com.android.tools.layoutlib:layoutlib-api:31.3.1
com.android.tools.layoutlib:layoutlib-api:31.5.0
com.android.tools.layoutlib:layoutlib-api:31.1.1
com.android.tools.lint:lint-api:24.3.1
com.android.tools.lint:lint-api:24.5.0
com.android.tools.lint:lint-api:26.0.1
@@ -396,67 +371,55 @@ com.android.tools.lint:lint-model:30.0.4
com.android.tools.lint:lint-model:30.2.1
com.android.tools.lint:lint-model:30.3.1
com.android.tools.lint:lint-model:30.4.2
com.android.tools.lint:lint-model:31.3.1
com.android.tools.lint:lint-model:31.5.0
com.android.tools.lint:lint-model:31.1.1
com.android.tools.lint:lint-typedef-remover:30.2.1
com.android.tools.lint:lint-typedef-remover:30.3.1
com.android.tools.lint:lint-typedef-remover:30.4.2
com.android.tools.lint:lint-typedef-remover:31.3.1
com.android.tools.lint:lint-typedef-remover:31.5.0
com.android.tools.lint:lint-typedef-remover:31.1.1
com.android.tools.lint:lint:24.3.1
com.android.tools.lint:lint:24.5.0
com.android.tools.lint:lint:26.0.1
com.android.tools.utp:android-device-provider-ddmlib-proto:30.2.1
com.android.tools.utp:android-device-provider-ddmlib-proto:30.3.1
com.android.tools.utp:android-device-provider-ddmlib-proto:30.4.2
com.android.tools.utp:android-device-provider-ddmlib-proto:31.3.1
com.android.tools.utp:android-device-provider-ddmlib-proto:31.5.0
com.android.tools.utp:android-device-provider-ddmlib:31.5.0
com.android.tools.utp:android-device-provider-ddmlib-proto:31.1.1
com.android.tools.utp:android-device-provider-ddmlib:31.1.1
com.android.tools.utp:android-device-provider-gradle-proto:30.0.4
com.android.tools.utp:android-device-provider-gradle-proto:30.2.1
com.android.tools.utp:android-device-provider-gradle-proto:30.3.1
com.android.tools.utp:android-device-provider-gradle-proto:30.4.2
com.android.tools.utp:android-device-provider-gradle-proto:31.3.1
com.android.tools.utp:android-device-provider-gradle-proto:31.5.0
com.android.tools.utp:android-device-provider-gradle:31.5.0
com.android.tools.utp:android-device-provider-gradle-proto:31.1.1
com.android.tools.utp:android-device-provider-gradle:31.1.1
com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.2.1
com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.3.1
com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.4.2
com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:31.3.1
com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:31.5.0
com.android.tools.utp:android-test-plugin-host-additional-test-output:31.5.0
com.android.tools.utp:android-test-plugin-host-apk-installer-proto:31.3.1
com.android.tools.utp:android-test-plugin-host-apk-installer-proto:31.5.0
com.android.tools.utp:android-test-plugin-host-apk-installer:31.5.0
com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:31.1.1
com.android.tools.utp:android-test-plugin-host-additional-test-output:31.1.1
com.android.tools.utp:android-test-plugin-host-apk-installer-proto:31.1.1
com.android.tools.utp:android-test-plugin-host-apk-installer:31.1.1
com.android.tools.utp:android-test-plugin-host-coverage-proto:30.2.1
com.android.tools.utp:android-test-plugin-host-coverage-proto:30.3.1
com.android.tools.utp:android-test-plugin-host-coverage-proto:30.4.2
com.android.tools.utp:android-test-plugin-host-coverage-proto:31.3.1
com.android.tools.utp:android-test-plugin-host-coverage-proto:31.5.0
com.android.tools.utp:android-test-plugin-host-coverage:31.5.0
com.android.tools.utp:android-test-plugin-host-device-info-proto:31.5.0
com.android.tools.utp:android-test-plugin-host-device-info:31.5.0
com.android.tools.utp:android-test-plugin-host-emulator-control-proto:31.3.1
com.android.tools.utp:android-test-plugin-host-emulator-control-proto:31.5.0
com.android.tools.utp:android-test-plugin-host-emulator-control:31.5.0
com.android.tools.utp:android-test-plugin-host-logcat-proto:31.3.1
com.android.tools.utp:android-test-plugin-host-logcat-proto:31.5.0
com.android.tools.utp:android-test-plugin-host-logcat:31.5.0
com.android.tools.utp:android-test-plugin-host-coverage-proto:31.1.1
com.android.tools.utp:android-test-plugin-host-coverage:31.1.1
com.android.tools.utp:android-test-plugin-host-device-info-proto:31.1.1
com.android.tools.utp:android-test-plugin-host-device-info:31.1.1
com.android.tools.utp:android-test-plugin-host-emulator-control-proto:31.1.1
com.android.tools.utp:android-test-plugin-host-emulator-control:31.1.1
com.android.tools.utp:android-test-plugin-host-logcat-proto:31.1.1
com.android.tools.utp:android-test-plugin-host-logcat:31.1.1
com.android.tools.utp:android-test-plugin-host-retention-proto:30.0.4
com.android.tools.utp:android-test-plugin-host-retention-proto:30.2.1
com.android.tools.utp:android-test-plugin-host-retention-proto:30.3.1
com.android.tools.utp:android-test-plugin-host-retention-proto:30.4.2
com.android.tools.utp:android-test-plugin-host-retention-proto:31.3.1
com.android.tools.utp:android-test-plugin-host-retention-proto:31.5.0
com.android.tools.utp:android-test-plugin-host-retention:31.5.0
com.android.tools.utp:android-test-plugin-host-retention-proto:31.1.1
com.android.tools.utp:android-test-plugin-host-retention:31.1.1
com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.0.4
com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.2.1
com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.3.1
com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.4.2
com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:31.3.1
com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:31.5.0
com.android.tools.utp:android-test-plugin-result-listener-gradle:31.5.0
com.android.tools.utp:utp-common:31.5.0
com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:31.1.1
com.android.tools.utp:android-test-plugin-result-listener-gradle:31.1.1
com.android.tools:annotations:24.3.1
com.android.tools:annotations:24.5.0
com.android.tools:annotations:26.0.1
@@ -467,8 +430,7 @@ com.android.tools:annotations:30.0.4
com.android.tools:annotations:30.2.1
com.android.tools:annotations:30.3.1
com.android.tools:annotations:30.4.2
com.android.tools:annotations:31.3.1
com.android.tools:annotations:31.5.0
com.android.tools:annotations:31.1.1
com.android.tools:common:24.3.1
com.android.tools:common:24.5.0
com.android.tools:common:26.0.1
@@ -479,8 +441,7 @@ com.android.tools:common:30.0.4
com.android.tools:common:30.2.1
com.android.tools:common:30.3.1
com.android.tools:common:30.4.2
com.android.tools:common:31.3.1
com.android.tools:common:31.5.0
com.android.tools:common:31.1.1
com.android.tools:dvlib:24.3.1
com.android.tools:dvlib:24.5.0
com.android.tools:dvlib:26.0.1
@@ -491,8 +452,7 @@ com.android.tools:dvlib:30.0.4
com.android.tools:dvlib:30.2.1
com.android.tools:dvlib:30.3.1
com.android.tools:dvlib:30.4.2
com.android.tools:dvlib:31.3.1
com.android.tools:dvlib:31.5.0
com.android.tools:dvlib:31.1.1
com.android.tools:repository:26.0.1
com.android.tools:repository:26.2.1
com.android.tools:repository:26.5.3
@@ -501,8 +461,7 @@ com.android.tools:repository:30.0.4
com.android.tools:repository:30.2.1
com.android.tools:repository:30.3.1
com.android.tools:repository:30.4.2
com.android.tools:repository:31.3.1
com.android.tools:repository:31.5.0
com.android.tools:repository:31.1.1
com.android.tools:sdklib:24.3.1
com.android.tools:sdklib:24.5.0
com.android.tools:sdklib:26.0.1
@@ -513,8 +472,7 @@ com.android.tools:sdklib:30.0.4
com.android.tools:sdklib:30.2.1
com.android.tools:sdklib:30.3.1
com.android.tools:sdklib:30.4.2
com.android.tools:sdklib:31.3.1
com.android.tools:sdklib:31.5.0
com.android.tools:sdklib:31.1.1
com.android.tools:sdk-common:24.3.1
com.android.tools:sdk-common:24.5.0
com.android.tools:sdk-common:26.0.1
@@ -525,22 +483,19 @@ com.android.tools:sdk-common:30.0.4
com.android.tools:sdk-common:30.2.1
com.android.tools:sdk-common:30.3.1
com.android.tools:sdk-common:30.4.2
com.android.tools:sdk-common:31.3.1
com.android.tools:sdk-common:31.5.0
com.android.tools:sdk-common:31.1.1
com.android:signflinger:4.1.0
com.android:signflinger:7.0.4
com.android:signflinger:7.2.1
com.android:signflinger:7.3.1
com.android:signflinger:7.4.2
com.android:signflinger:8.3.1
com.android:signflinger:8.5.0
com.android:signflinger:8.1.1
com.android:zipflinger:4.1.0
com.android:zipflinger:7.0.4
com.android:zipflinger:7.2.1
com.android:zipflinger:7.3.1
com.android:zipflinger:7.4.2
com.android:zipflinger:8.3.1
com.android:zipflinger:8.5.0
com.android:zipflinger:8.1.1
com.diffplug.durian:durian-collect:1.2.0
com.diffplug.durian:durian-core:1.2.0
com.diffplug.durian:durian-io:1.2.0
@@ -552,41 +507,41 @@ com.diffplug.spotless:spotless-plugin-gradle:6.7.2
com.diffplug.spotless:spotless-plugin-gradle:6.11.0
com.drewnoakes:metadata-extractor:2.18.0
com.facebook.conceal:conceal:1.1.3
com.facebook.fbjni:fbjni:0.6.0
com.facebook.fbjni:fbjni:0.5.1
com.facebook.fresco:animated-base:2.5.0
com.facebook.fresco:animated-drawable:2.5.0
com.facebook.fresco:animated-gif:2.5.0
com.facebook.fresco:drawee:2.5.0
com.facebook.fresco:drawee:3.2.0
com.facebook.fresco:drawee:3.1.3
com.facebook.fresco:fbcore:2.5.0
com.facebook.fresco:fbcore:3.2.0
com.facebook.fresco:fbcore:3.1.3
com.facebook.fresco:fresco:2.5.0
com.facebook.fresco:fresco:3.2.0
com.facebook.fresco:fresco:3.1.3
com.facebook.fresco:imagepipeline-base:2.5.0
com.facebook.fresco:imagepipeline-base:3.2.0
com.facebook.fresco:imagepipeline-base:3.1.3
com.facebook.fresco:imagepipeline-native:2.5.0
com.facebook.fresco:imagepipeline-native:3.2.0
com.facebook.fresco:imagepipeline-okhttp3:3.2.0
com.facebook.fresco:imagepipeline-native:3.1.3
com.facebook.fresco:imagepipeline-okhttp3:3.1.3
com.facebook.fresco:imagepipeline:2.5.0
com.facebook.fresco:imagepipeline:3.2.0
com.facebook.fresco:imagepipeline:3.1.3
com.facebook.fresco:memory-type-ashmem:2.5.0
com.facebook.fresco:memory-type-ashmem:3.2.0
com.facebook.fresco:memory-type-ashmem:3.1.3
com.facebook.fresco:memory-type-java:2.5.0
com.facebook.fresco:memory-type-java:3.2.0
com.facebook.fresco:memory-type-java:3.1.3
com.facebook.fresco:memory-type-native:2.5.0
com.facebook.fresco:memory-type-native:3.2.0
com.facebook.fresco:middleware:3.2.0
com.facebook.fresco:memory-type-native:3.1.3
com.facebook.fresco:middleware:3.1.3
com.facebook.fresco:nativeimagefilters:2.5.0
com.facebook.fresco:nativeimagefilters:3.2.0
com.facebook.fresco:nativeimagefilters:3.1.3
com.facebook.fresco:nativeimagetranscoder:2.5.0
com.facebook.fresco:nativeimagetranscoder:3.2.0
com.facebook.fresco:soloader:3.2.0
com.facebook.fresco:ui-common:3.2.0
com.facebook.fresco:nativeimagetranscoder:3.1.3
com.facebook.fresco:soloader:3.1.3
com.facebook.fresco:ui-common:3.1.3
com.facebook.infer.annotation:infer-annotation:0.18.0
com.facebook.react:react-android:0.75.3
com.facebook.soloader:annotation:0.11.0
com.facebook.soloader:nativeloader:0.11.0
com.facebook.soloader:soloader:0.11.0
com.facebook.react:react-android:0.73.5
com.facebook.soloader:annotation:0.10.5
com.facebook.soloader:nativeloader:0.10.5
com.facebook.soloader:soloader:0.10.5
com.facebook.yoga:proguard-annotations:1.19.0
com.fasterxml.jackson.core:jackson-annotations:2.11.1
com.fasterxml.jackson.core:jackson-core:2.11.1
@@ -604,8 +559,8 @@ com.github.bumptech.glide:glide:4.12.0
com.github.bumptech.glide:okhttp3-integration:4.12.0
com.github.clans:fab:1.6.4
com.github.gundy:semver4j:0.16.4
com.github.status-im.status-keycard-java:android:3.1.2
com.github.status-im.status-keycard-java:lib:3.1.2
com.github.status-im.status-keycard-java:android:3.1.1
com.github.status-im.status-keycard-java:lib:3.1.1
com.github.status-im:function:0.0.1
com.github.wix-playground:ahbottomnavigation:3.3.0
com.github.wix-playground:reflow-animator:1.0.6
@@ -620,9 +575,9 @@ com.google.android.material:material:1.2.0-alpha03
com.google.android:annotations:4.1.1.4
com.google.api.grpc:proto-google-common-protos:1.12.0
com.google.api.grpc:proto-google-common-protos:2.0.1
com.google.api.grpc:proto-google-common-protos:2.17.0
com.google.auto.value:auto-value-annotations:1.6.2
com.google.auto.value:auto-value-annotations:1.6.3
com.google.auto.value:auto-value-annotations:1.7.4
com.google.auto.value:auto-value:1.5.2
com.google.code.findbugs:jsr305:1.3.9
com.google.code.findbugs:jsr305:3.0.2
@@ -633,7 +588,6 @@ com.google.code.gson:gson:2.8.5
com.google.code.gson:gson:2.8.6
com.google.code.gson:gson:2.8.9
com.google.code.gson:gson:2.9.1
com.google.code.gson:gson:2.10.1
com.google.crypto.tink:tink:1.3.0-rc2
com.google.crypto.tink:tink:1.7.0
com.google.dagger:dagger:2.28.3
@@ -644,7 +598,8 @@ com.google.errorprone:error_prone_annotations:2.3.2
com.google.errorprone:error_prone_annotations:2.3.4
com.google.errorprone:error_prone_annotations:2.4.0
com.google.errorprone:error_prone_annotations:2.7.1
com.google.errorprone:error_prone_annotations:2.18.0
com.google.errorprone:error_prone_annotations:2.9.0
com.google.errorprone:error_prone_annotations:2.11.0
com.google.flatbuffers:flatbuffers-java:1.12.0
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:17.0
@@ -655,34 +610,33 @@ com.google.guava:guava:28.1-jre
com.google.guava:guava:29.0-jre
com.google.guava:guava:30.1-jre
com.google.guava:guava:31.0.1-jre
com.google.guava:guava:32.0.1-jre
com.google.guava:guava:31.1-jre
com.google.guava:listenablefuture:1.0
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.1
com.google.j2objc:j2objc-annotations:1.3
com.google.j2objc:j2objc-annotations:2.8
com.google.jimfs:jimfs:1.1
com.google.prefab:cli:2.1.0
com.google.prefab:cli:2.0.0
com.google.protobuf:protobuf-java-util:3.4.0
com.google.protobuf:protobuf-java-util:3.10.0
com.google.protobuf:protobuf-java-util:3.17.2
com.google.protobuf:protobuf-java-util:3.22.3
com.google.protobuf:protobuf-java-util:3.19.3
com.google.protobuf:protobuf-java:3.0.0
com.google.protobuf:protobuf-java:3.4.0
com.google.protobuf:protobuf-java:3.10.0
com.google.protobuf:protobuf-java:3.17.2
com.google.protobuf:protobuf-java:3.22.3
com.google.testing.platform:android-device-provider-local:0.0.9-alpha02
com.google.testing.platform:android-driver-instrumentation:0.0.9-alpha02
com.google.testing.platform:android-test-plugin:0.0.9-alpha02
com.google.protobuf:protobuf-java:3.19.3
com.google.testing.platform:android-device-provider-local:0.0.8-alpha08
com.google.testing.platform:android-driver-instrumentation:0.0.8-alpha08
com.google.testing.platform:android-test-plugin:0.0.8-alpha08
com.google.testing.platform:core-proto:0.0.8-alpha04
com.google.testing.platform:core-proto:0.0.8-alpha07
com.google.testing.platform:core-proto:0.0.8-alpha08
com.google.testing.platform:core-proto:0.0.9-alpha02
com.google.testing.platform:core:0.0.9-alpha02
com.google.testing.platform:launcher:0.0.9-alpha02
com.google.testing.platform:core:0.0.8-alpha08
com.google.testing.platform:launcher:0.0.8-alpha08
com.google.test.platform:core-proto:0.0.2-dev
com.google.zxing:core:3.4.1
com.ibm.icu:icu4j:53.1
com.intellij:annotations:12.0
com.parse.bolts:bolts-tasks:1.4.0
com.squareup.okhttp3:okhttp-tls:4.11.0
@@ -690,10 +644,8 @@ com.squareup.okhttp3:okhttp-urlconnection:4.9.2
com.squareup.okhttp3:okhttp:4.9.2
com.squareup.okhttp3:okhttp:4.11.0
com.squareup.okio:okio-jvm:3.2.0
com.squareup.okio:okio-jvm:3.4.0
com.squareup.okio:okio:2.9.0
com.squareup.okio:okio:3.2.0
com.squareup.okio:okio:3.4.0
com.squareup:javapoet:1.8.0
com.squareup:javapoet:1.10.0
com.squareup:javapoet:1.13.0
@@ -712,61 +664,60 @@ de.undercouch:gradle-download-task:4.1.1
de.undercouch:gradle-download-task:5.0.1
io.grpc:grpc-api:1.21.1
io.grpc:grpc-api:1.39.0
io.grpc:grpc-api:1.57.0
io.grpc:grpc-api:1.45.1
io.grpc:grpc-context:1.21.1
io.grpc:grpc-context:1.39.0
io.grpc:grpc-context:1.57.0
io.grpc:grpc-context:1.45.1
io.grpc:grpc-core:1.21.1
io.grpc:grpc-core:1.39.0
io.grpc:grpc-core:1.57.0
io.grpc:grpc-core:1.45.1
io.grpc:grpc-netty:1.21.1
io.grpc:grpc-netty:1.39.0
io.grpc:grpc-netty:1.57.0
io.grpc:grpc-netty:1.45.1
io.grpc:grpc-protobuf-lite:1.21.1
io.grpc:grpc-protobuf-lite:1.39.0
io.grpc:grpc-protobuf-lite:1.57.0
io.grpc:grpc-protobuf-lite:1.45.1
io.grpc:grpc-protobuf:1.21.1
io.grpc:grpc-protobuf:1.39.0
io.grpc:grpc-protobuf:1.57.0
io.grpc:grpc-protobuf:1.45.1
io.grpc:grpc-stub:1.21.1
io.grpc:grpc-stub:1.39.0
io.grpc:grpc-stub:1.57.0
io.grpc:grpc-stub:1.45.1
io.legere:pdfiumandroid:1.0.19
io.netty:netty-buffer:4.1.34.Final
io.netty:netty-buffer:4.1.52.Final
io.netty:netty-buffer:4.1.93.Final
io.netty:netty-buffer:4.1.72.Final
io.netty:netty-codec-http2:4.1.34.Final
io.netty:netty-codec-http2:4.1.52.Final
io.netty:netty-codec-http2:4.1.93.Final
io.netty:netty-codec-http2:4.1.72.Final
io.netty:netty-codec-http:4.1.34.Final
io.netty:netty-codec-http:4.1.52.Final
io.netty:netty-codec-http:4.1.93.Final
io.netty:netty-codec-http:4.1.72.Final
io.netty:netty-codec-socks:4.1.34.Final
io.netty:netty-codec-socks:4.1.52.Final
io.netty:netty-codec-socks:4.1.93.Final
io.netty:netty-codec-socks:4.1.72.Final
io.netty:netty-codec:4.1.34.Final
io.netty:netty-codec:4.1.52.Final
io.netty:netty-codec:4.1.93.Final
io.netty:netty-codec:4.1.72.Final
io.netty:netty-common:4.1.34.Final
io.netty:netty-common:4.1.52.Final
io.netty:netty-common:4.1.93.Final
io.netty:netty-common:4.1.72.Final
io.netty:netty-handler-proxy:4.1.34.Final
io.netty:netty-handler-proxy:4.1.52.Final
io.netty:netty-handler-proxy:4.1.93.Final
io.netty:netty-handler-proxy:4.1.72.Final
io.netty:netty-handler:4.1.34.Final
io.netty:netty-handler:4.1.52.Final
io.netty:netty-handler:4.1.93.Final
io.netty:netty-handler:4.1.72.Final
io.netty:netty-resolver:4.1.34.Final
io.netty:netty-resolver:4.1.52.Final
io.netty:netty-resolver:4.1.93.Final
io.netty:netty-transport-native-unix-common:4.1.93.Final
io.netty:netty-resolver:4.1.72.Final
io.netty:netty-tcnative-classes:2.0.46.Final
io.netty:netty-transport:4.1.34.Final
io.netty:netty-transport:4.1.52.Final
io.netty:netty-transport:4.1.93.Final
io.netty:netty-transport:4.1.72.Final
io.opencensus:opencensus-api:0.21.0
io.opencensus:opencensus-contrib-grpc-metrics:0.21.0
io.perfmark:perfmark-api:0.23.0
io.perfmark:perfmark-api:0.26.0
it.unimi.dsi:fastutil:7.2.0
it.unimi.dsi:fastutil:8.4.0
jakarta.activation:jakarta.activation-api:1.2.1
@@ -780,8 +731,9 @@ junit:junit:4.12
junit:junit:4.13.2
me.zhanghai.android.materialprogressbar:library:1.4.2
net.bytebuddy:byte-buddy-agent:1.11.13
net.bytebuddy:byte-buddy-agent:1.11.19
net.bytebuddy:byte-buddy:1.11.13
net.bytebuddy:byte-buddy:1.14.11
net.bytebuddy:byte-buddy:1.11.19
net.java.dev.jna:jna-platform:5.6.0
net.java.dev.jna:jna:5.6.0
net.sf.jopt-simple:jopt-simple:4.9
@@ -809,36 +761,30 @@ org.apache.httpcomponents:httpclient:4.5.2
org.apache.httpcomponents:httpclient:4.5.6
org.apache.httpcomponents:httpclient:4.5.9
org.apache.httpcomponents:httpclient:4.5.13
org.apache.httpcomponents:httpclient:4.5.14
org.apache.httpcomponents:httpcore:4.1
org.apache.httpcomponents:httpcore:4.2.5
org.apache.httpcomponents:httpcore:4.4.5
org.apache.httpcomponents:httpcore:4.4.10
org.apache.httpcomponents:httpcore:4.4.11
org.apache.httpcomponents:httpcore:4.4.13
org.apache.httpcomponents:httpcore:4.4.16
org.apache.httpcomponents:httpcore:4.4.15
org.apache.httpcomponents:httpmime:4.1
org.apache.httpcomponents:httpmime:4.5.2
org.apache.httpcomponents:httpmime:4.5.6
org.assertj:assertj-core:3.25.1
org.bitbucket.b_c:jose4j:0.7.0
org.bitbucket.b_c:jose4j:0.9.5
org.bouncycastle:bcpkix-jdk15on:1.48
org.bouncycastle:bcpkix-jdk15on:1.56
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcpkix-jdk18on:1.77
org.bouncycastle:bcprov-jdk15on:1.48
org.bouncycastle:bcprov-jdk15on:1.56
org.bouncycastle:bcprov-jdk15on:1.60
org.bouncycastle:bcprov-jdk15on:1.67
org.bouncycastle:bcprov-jdk18on:1.77
org.bouncycastle:bcutil-jdk18on:1.77
org.bouncycastle:bcprov-jdk15on:1.68
org.checkerframework:checker-qual:2.5.2
org.checkerframework:checker-qual:2.8.1
org.checkerframework:checker-qual:2.11.1
org.checkerframework:checker-qual:3.5.0
org.checkerframework:checker-qual:3.12.0
org.checkerframework:checker-qual:3.33.0
org.codehaus.groovy:groovy-xml:3.0.9
org.codehaus.groovy:groovy-xml:3.0.10
org.codehaus.groovy:groovy:3.0.9
@@ -847,12 +793,12 @@ org.codehaus.mojo:animal-sniffer-annotations:1.14
org.codehaus.mojo:animal-sniffer-annotations:1.17
org.codehaus.mojo:animal-sniffer-annotations:1.18
org.codehaus.mojo:animal-sniffer-annotations:1.19
org.codehaus.mojo:animal-sniffer-annotations:1.23
org.codehaus.woodstox:stax2-api:4.2.1
org.eclipse.jdt.core.compiler:ecj:4.4.2
org.eclipse.jdt.core.compiler:ecj:4.6.1
org.eclipse.jgit:org.eclipse.jgit:5.13.0.202109080827-r
org.eclipse.jgit:org.eclipse.jgit:5.13.1.202206130422-r
org.fusesource.jansi:jansi:1.18
org.glassfish.jaxb:jaxb-core:2.2.11
org.glassfish.jaxb:jaxb-runtime:2.2.11
org.glassfish.jaxb:jaxb-runtime:2.3.1
@@ -861,8 +807,9 @@ org.glassfish.jaxb:txw2:2.2.11
org.glassfish.jaxb:txw2:2.3.1
org.glassfish.jaxb:txw2:2.3.2
org.gradle.toolchains:foojay-resolver:0.5.0
org.gradle:github-dependency-graph-gradle-plugin:1.3.2
org.gradle:github-dependency-graph-gradle-plugin:1.3.1
org.hamcrest:hamcrest-core:1.3
org.hamcrest:hamcrest:2.2
org.jacoco:org.jacoco.core:0.7.4.201502262128
org.jacoco:org.jacoco.report:0.7.4.201502262128
org.jdom:jdom2:2.0.6
@@ -870,59 +817,69 @@ org.jetbrains.dokka:dokka-core:1.4.32
org.jetbrains.intellij.deps:trove4j:1.0.20181211
org.jetbrains.intellij.deps:trove4j:1.0.20200330
org.jetbrains.kotlinx:atomicfu:0.16.3
org.jetbrains.kotlinx:atomicfu:0.21.0
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.6.1
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.6.4
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.6.3
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.7.3
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.1
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.3
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.3
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.1
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.3
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3
org.jetbrains.kotlinx:kotlinx-serialization-core:1.6.3
org.jetbrains.kotlinx:kotlinx-serialization-protobuf:1.6.3
org.jetbrains.kotlin:kotlin-android-extensions-runtime:1.9.22
org.jetbrains.kotlin:kotlin-android-extensions:1.6.20
org.jetbrains.kotlin:kotlin-android-extensions:1.9.24
org.jetbrains.kotlin:kotlin-android-extensions:1.8.0
org.jetbrains.kotlin:kotlin-android-extensions:1.9.0
org.jetbrains.kotlin:kotlin-annotations-jvm:1.3.72
org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.6.20
org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.8.0
org.jetbrains.kotlin:kotlin-build-common:1.6.20
org.jetbrains.kotlin:kotlin-build-common:1.9.24
org.jetbrains.kotlin:kotlin-build-tools-api:1.9.24
org.jetbrains.kotlin:kotlin-build-tools-impl:1.9.24
org.jetbrains.kotlin:kotlin-build-common:1.8.0
org.jetbrains.kotlin:kotlin-build-tools-api:1.9.0
org.jetbrains.kotlin:kotlin-build-tools-impl:1.9.0
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.6.20
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.24
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.8.0
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.0
org.jetbrains.kotlin:kotlin-compiler-runner:1.6.20
org.jetbrains.kotlin:kotlin-compiler-runner:1.9.24
org.jetbrains.kotlin:kotlin-compiler-runner:1.8.0
org.jetbrains.kotlin:kotlin-compiler-runner:1.9.0
org.jetbrains.kotlin:kotlin-daemon-client:1.6.20
org.jetbrains.kotlin:kotlin-daemon-client:1.9.24
org.jetbrains.kotlin:kotlin-daemon-client:1.8.0
org.jetbrains.kotlin:kotlin-daemon-client:1.9.0
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.6.20
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.24
org.jetbrains.kotlin:kotlin-gradle-plugins-bom:1.9.24
org.jetbrains.kotlin:kotlin-gradle-plugin-annotations:1.9.24
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.8.0
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.0
org.jetbrains.kotlin:kotlin-gradle-plugins-bom:1.9.0
org.jetbrains.kotlin:kotlin-gradle-plugin-annotations:1.9.0
org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.6.20
org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.9.24
org.jetbrains.kotlin:kotlin-gradle-plugin-idea-proto:1.9.24
org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.9.24
org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.8.0
org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.9.0
org.jetbrains.kotlin:kotlin-gradle-plugin-idea-proto:1.8.0
org.jetbrains.kotlin:kotlin-gradle-plugin-idea-proto:1.9.0
org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.8.0
org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.9.0
org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.6.20
org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.9.24
org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.8.0
org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.9.0
org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.20
org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.24
org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.0
org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0
org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.6.20
org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.9.24
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.9.24
org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.8.0
org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.9.0
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.8.0
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.9.0
org.jetbrains.kotlin:kotlin-native-utils:1.6.20
org.jetbrains.kotlin:kotlin-native-utils:1.9.24
org.jetbrains.kotlin:kotlin-parcelize-runtime:1.9.22
org.jetbrains.kotlin:kotlin-native-utils:1.8.0
org.jetbrains.kotlin:kotlin-native-utils:1.9.0
org.jetbrains.kotlin:kotlin-project-model:1.6.20
org.jetbrains.kotlin:kotlin-project-model:1.9.24
org.jetbrains.kotlin:kotlin-project-model:1.8.0
org.jetbrains.kotlin:kotlin-project-model:1.9.0
org.jetbrains.kotlin:kotlin-reflect:1.1.3-2
org.jetbrains.kotlin:kotlin-reflect:1.2.0
org.jetbrains.kotlin:kotlin-reflect:1.3.50
@@ -931,16 +888,21 @@ org.jetbrains.kotlin:kotlin-reflect:1.4.32
org.jetbrains.kotlin:kotlin-reflect:1.5.31
org.jetbrains.kotlin:kotlin-reflect:1.6.10
org.jetbrains.kotlin:kotlin-reflect:1.7.10
org.jetbrains.kotlin:kotlin-reflect:1.9.20
org.jetbrains.kotlin:kotlin-reflect:1.8.20-RC2
org.jetbrains.kotlin:kotlin-scripting-common:1.6.20
org.jetbrains.kotlin:kotlin-scripting-common:1.9.24
org.jetbrains.kotlin:kotlin-scripting-common:1.8.0
org.jetbrains.kotlin:kotlin-scripting-common:1.9.0
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.6.20
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.24
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.8.0
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.0
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.6.20
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.24
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.8.0
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.0
org.jetbrains.kotlin:kotlin-scripting-jvm:1.6.20
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.24
org.jetbrains.kotlin:kotlin-script-runtime:1.9.24
org.jetbrains.kotlin:kotlin-scripting-jvm:1.8.0
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.0
org.jetbrains.kotlin:kotlin-script-runtime:1.8.0
org.jetbrains.kotlin:kotlin-script-runtime:1.9.0
org.jetbrains.kotlin:kotlin-stdlib-common:1.2.71
org.jetbrains.kotlin:kotlin-stdlib-common:1.3.50
org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72
@@ -948,31 +910,32 @@ org.jetbrains.kotlin:kotlin-stdlib-common:1.4.32
org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31
org.jetbrains.kotlin:kotlin-stdlib-common:1.6.20
org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.20
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.24
org.jetbrains.kotlin:kotlin-stdlib-common:1.8.0
org.jetbrains.kotlin:kotlin-stdlib-common:1.8.20-RC2
org.jetbrains.kotlin:kotlin-stdlib-common:1.8.21
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.0
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.22
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.71
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.50
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.32
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.31
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.10
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.20
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.20
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.20-RC2
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.21
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.20
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.24
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.0
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.2.71
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.50
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.32
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.31
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.10
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.20
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.20-RC2
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.21
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.20
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.24
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0
org.jetbrains.kotlin:kotlin-stdlib:1.1.3-2
org.jetbrains.kotlin:kotlin-stdlib:1.2.71
org.jetbrains.kotlin:kotlin-stdlib:1.3.50
@@ -981,14 +944,20 @@ org.jetbrains.kotlin:kotlin-stdlib:1.4.32
org.jetbrains.kotlin:kotlin-stdlib:1.5.31
org.jetbrains.kotlin:kotlin-stdlib:1.6.20
org.jetbrains.kotlin:kotlin-stdlib:1.7.10
org.jetbrains.kotlin:kotlin-stdlib:1.9.20
org.jetbrains.kotlin:kotlin-stdlib:1.9.24
org.jetbrains.kotlin:kotlin-tooling-core:1.9.24
org.jetbrains.kotlin:kotlin-stdlib:1.8.0
org.jetbrains.kotlin:kotlin-stdlib:1.8.20-RC2
org.jetbrains.kotlin:kotlin-stdlib:1.8.21
org.jetbrains.kotlin:kotlin-stdlib:1.9.0
org.jetbrains.kotlin:kotlin-stdlib:1.9.22
org.jetbrains.kotlin:kotlin-tooling-core:1.8.0
org.jetbrains.kotlin:kotlin-tooling-core:1.9.0
org.jetbrains.kotlin:kotlin-tooling-metadata:1.6.20
org.jetbrains.kotlin:kotlin-util-io:1.6.20
org.jetbrains.kotlin:kotlin-util-io:1.9.24
org.jetbrains.kotlin:kotlin-util-io:1.8.0
org.jetbrains.kotlin:kotlin-util-io:1.9.0
org.jetbrains.kotlin:kotlin-util-klib:1.6.20
org.jetbrains.kotlin:kotlin-util-klib:1.9.24
org.jetbrains.kotlin:kotlin-util-klib:1.8.0
org.jetbrains.kotlin:kotlin-util-klib:1.9.0
org.jetbrains.trove4j:trove4j:20160824
org.jetbrains:annotations:13.0
org.jetbrains:annotations:23.0.0
@@ -1000,6 +969,8 @@ org.jvnet.staxex:stax-ex:1.7.7
org.jvnet.staxex:stax-ex:1.8
org.jvnet.staxex:stax-ex:1.8.1
org.mockito:mockito-core:3.12.4
org.mockito:mockito-core:4.0.0
org.mockito:mockito-inline:4.0.0
org.objenesis:objenesis:3.2
org.ow2.asm:asm-analysis:5.0.3
org.ow2.asm:asm-analysis:5.1
@@ -1007,13 +978,11 @@ org.ow2.asm:asm-analysis:6.0
org.ow2.asm:asm-analysis:7.0
org.ow2.asm:asm-analysis:9.1
org.ow2.asm:asm-analysis:9.2
org.ow2.asm:asm-analysis:9.6
org.ow2.asm:asm-commons:5.1
org.ow2.asm:asm-commons:6.0
org.ow2.asm:asm-commons:7.0
org.ow2.asm:asm-commons:9.1
org.ow2.asm:asm-commons:9.2
org.ow2.asm:asm-commons:9.6
org.ow2.asm:asm-debug-all:5.0.1
org.ow2.asm:asm-tree:5.0.3
org.ow2.asm:asm-tree:5.1
@@ -1021,29 +990,36 @@ org.ow2.asm:asm-tree:6.0
org.ow2.asm:asm-tree:7.0
org.ow2.asm:asm-tree:9.1
org.ow2.asm:asm-tree:9.2
org.ow2.asm:asm-tree:9.6
org.ow2.asm:asm-util:5.1
org.ow2.asm:asm-util:6.0
org.ow2.asm:asm-util:7.0
org.ow2.asm:asm-util:9.1
org.ow2.asm:asm-util:9.2
org.ow2.asm:asm-util:9.6
org.ow2.asm:asm:5.0.3
org.ow2.asm:asm:5.1
org.ow2.asm:asm:6.0
org.ow2.asm:asm:7.0
org.ow2.asm:asm:9.1
org.ow2.asm:asm:9.2
org.ow2.asm:asm:9.6
org.robolectric:annotations:4.7.3
org.robolectric:junit:4.7.3
org.robolectric:nativeruntime:4.7.3
org.robolectric:pluginapi:4.7.3
org.robolectric:plugins-maven-dependency-resolver:4.7.3
org.robolectric:resources:4.7.3
org.robolectric:robolectric:4.7.3
org.robolectric:sandbox:4.7.3
org.robolectric:shadowapi:4.7.3
org.robolectric:shadows-framework:4.7.3
org.robolectric:utils-reflector:4.7.3
org.robolectric:utils:4.7.3
org.slf4j:slf4j-api:1.7.30
org.tensorflow:tensorflow-lite-metadata:0.1.0-rc1
org.tensorflow:tensorflow-lite-metadata:0.1.0-rc2
xerces:xercesImpl:2.12.0
xml-apis:xml-apis:1.4.01
org.gradle.toolchains.foojay-resolver-convention:org.gradle.toolchains.foojay-resolver-convention.gradle.plugin:0.5.0
org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin:1.9.24
org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin:1.8.0
com.android.tools.build:gradle:3.5.4
com.facebook.react:hermes-android:0.75.3
com.android.tools.lint:lint-gradle:31.5.0
org.junit:junit-bom:5.9.3
org.junit:junit-bom:5.9.2
com.android.tools.lint:lint-gradle:31.1.1
com.facebook.react:hermes-android:0.73.5
+267 -306
View File
File diff suppressed because it is too large Load Diff
-55
View File
@@ -1,55 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
# Fallback versions for each dependency
readonly FOOJAY_FALLBACK="0.5.0"
readonly KOTLIN_FALLBACK="1.8.0"
readonly TOOLS_FALLBACK="3.5.4"
readonly HERMES_FALLBACK="0.73.5"
readonly GRADLE_LINT_FALLBACK="31.1.1"
GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
cd "${GIT_ROOT}"
get_version() {
local file="$1"
local pattern="$2"
local fallback="$3"
local version
if [[ ! -f "$file" ]]; then
echo "$fallback"
return 0
fi
version=$(grep "$pattern" "$file" 2>/dev/null | grep -o "[0-9]\+\.[0-9]\+\.[0-9]\+\.*[0-9]*" | tail -n1 || echo "$fallback")
echo "$version"
}
# https://github.com/googlesamples/android-custom-lint-rules/blob/be672cd747ecf13844918e1afccadb935f856a72/docs/api-guide/example.md.html#L112-L129
get_gradle_lint_version() {
gradlePluginVersion=$(get_version "./nix/pkgs/aapt2/default.nix" "version =" $GRADLE_LINT_FALLBACK)
major=$(echo "$gradlePluginVersion" | grep -o "^[0-9]*")
# lintVersion = gradlePluginVersion + 23.0.0
major=$((major + 23))
minor=$(echo "$gradlePluginVersion" | grep -o "\.[0-9]*\." | grep -o "[0-9]*")
patch=$(echo "$gradlePluginVersion" | grep -o "[0-9]*$")
echo "$major.$minor.$patch"
}
foojay_version=$(get_version "./node_modules/@react-native/gradle-plugin/settings.gradle.kts" "foojay.*version" "$FOOJAY_FALLBACK")
kotlin_version=$(get_version "./node_modules/@react-native/gradle-plugin/gradle/libs.versions.toml" "kotlin =" "$KOTLIN_FALLBACK")
tools_version=$(get_version "./patches/BlurView-build.gradle.patch" "gradle:" "$TOOLS_FALLBACK")
hermes_version=$(get_version "./node_modules/react-native/ReactAndroid/gradle.properties" "VERSION_NAME" "$HERMES_FALLBACK")
lint_version=$(get_gradle_lint_version)
cat << EOF
org.gradle.toolchains.foojay-resolver-convention:org.gradle.toolchains.foojay-resolver-convention.gradle.plugin:$foojay_version
org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin:$kotlin_version
com.android.tools.build:gradle:$tools_version
com.facebook.react:hermes-android:$hermes_version
com.android.tools.lint:lint-gradle:$lint_version
org.junit:junit-bom:5.9.3
org.junit:junit-bom:5.9.2
EOF
+8 -2
View File
@@ -38,10 +38,16 @@ function gen_deps_list() {
echo -e "${CLR}Found ${GRN}$(wc -l < "${DEPS_LIST}")${RST} direct dependencies..."
}
# FIXME: Fix for missing packages.
# FIXME: Temporary fix for missing packages.
# https://github.com/status-im/status-mobile/issues/15447
function add_deps_hack() {
"${CUR_DIR}/deps_hack.sh" >> "${DEPS_LIST}"
echo -n \
'org.gradle.toolchains.foojay-resolver-convention:org.gradle.toolchains.foojay-resolver-convention.gradle.plugin:0.5.0
org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin:1.8.0
com.android.tools.build:gradle:3.5.4
com.android.tools.lint:lint-gradle:31.1.1
com.facebook.react:hermes-android:0.73.5' \
>> "${DEPS_LIST}"
}
# Find download URLs for each dependency.

Some files were not shown because too many files have changed in this diff Show More