Files
status-react/src/native_module/core.cljs
T
frank f45f96975e refactor_: rename LOG_REQUEST_GO to API_LOGGING_ENABLED (#21677)
https://github.com/status-im/status-go/compare/032eb5b6...c014fbfc

- Rename LOG_REQUEST_GO env variable to API_LOGGING_ENABLED across all env files
- Rename requests.log to api.log for consistency
- Remove standalone initLogging functionality from native modules as it's now
  handled within InitializeApplication
- Add logging configuration (logEnabled, logLevel, apiLoggingEnabled) to
  InitializeApplication params
- Add logDir parameter for Android to ensure proper log file location

This change consolidates logging initialization into the InitializeApplication
flow and makes the naming more consistent with its actual functionality.
2024-11-29 22:01:27 +08:00

584 lines
20 KiB
Clojure

(ns native-module.core
(:require
["react-native" :as react-native]
[clojure.string :as string]
[native-module.utils :as native-utils]
[react-native.platform :as platform]
[taoensso.timbre :as log]
[utils.transforms :as types]))
(defn status
[]
(when (exists? (.-NativeModules react-native))
(.-Status ^js (.-NativeModules react-native))))
(defn account-manager
[]
(when (exists? (.-NativeModules react-native))
(.-AccountManager ^js (.-NativeModules react-native))))
(defn encryption
[]
(when (exists? (.-NativeModules react-native))
(.-EncryptionUtils ^js (.-NativeModules react-native))))
(defn database
[]
(when (exists? (.-NativeModules react-native))
(.-DatabaseManager ^js (.-NativeModules react-native))))
(defn ui-helper
[]
(when (exists? (.-NativeModules react-native))
(.-UIHelper ^js (.-NativeModules react-native))))
(defn log-manager
[]
(when (exists? (.-NativeModules react-native))
(.-LogManager ^js (.-NativeModules react-native))))
(defn utils
[]
(when (exists? (.-NativeModules react-native))
(.-Utils ^js (.-NativeModules react-native))))
(defn network
[]
(when (exists? (.-NativeModules react-native))
(.-NetworkManager ^js (.-NativeModules react-native))))
(defn mail-manager
[]
(when (exists? (.-NativeModules react-native))
(.-MailManager ^js (.-NativeModules react-native))))
(defn mail
[opts callback]
(.mail ^js (mail-manager) (clj->js opts) callback))
(defn init
[handler]
(.addListener ^js (.-DeviceEventEmitter ^js react-native) "gethEvent" #(handler (.-jsonEvent ^js %))))
(defn clear-web-data
[]
(log/debug "[native-module] clear-web-data")
(when (ui-helper)
(.clearCookies ^js (ui-helper))
(.clearStorageAPIs ^js (ui-helper))))
(defn init-keystore
[key-uid callback]
(log/debug "[native-module] init-keystore" key-uid)
(.initKeystore ^js (encryption) key-uid callback))
(defn initialize-application
[request callback]
(log/debug "[native-module] initialize-application")
(.initializeApplication ^js (account-manager)
(types/clj->json request)
#(callback (types/json->clj %))))
(defn accept-terms
([]
(native-utils/promisify-native-module-call accept-terms))
([callback]
(.acceptTerms ^js (account-manager) callback)))
(defn prepare-dir-and-update-config
[key-uid config callback]
(log/debug "[native-module] prepare-dir-and-update-config")
(.prepareDirAndUpdateConfig ^js (account-manager)
key-uid
config
#(callback (types/json->clj %))))
(defn login-account
"NOTE: beware, the password has to be sha3 hashed"
[{:keys [keyUid] :as request}]
(log/debug "[native-module] loginAccount")
(clear-web-data)
(init-keystore
keyUid
#(.loginAccount ^js (account-manager) (types/clj->json request))))
(defn create-account-and-login
[request]
(.createAccountAndLogin ^js (account-manager) (types/clj->json request)))
(defn restore-account-and-login
[request]
(.restoreAccountAndLogin ^js (account-manager) (types/clj->json request)))
(defn export-db
"NOTE: beware, the password has to be sha3 hashed"
[key-uid account-data hashed-password callback]
(log/debug "[native-module] export-db")
(clear-web-data)
(init-keystore
key-uid
#(.exportUnencryptedDatabase ^js (database) account-data hashed-password callback)))
(defn import-db
"NOTE: beware, the password has to be sha3 hashed"
[key-uid account-data hashed-password]
(log/debug "[native-module] import-db")
(clear-web-data)
(init-keystore
key-uid
#(.importUnencryptedDatabase ^js (database) account-data hashed-password)))
(defn logout
[]
(log/debug "[native-module] logout")
(clear-web-data)
(.logout ^js (account-manager)))
(defn multiaccount-derive-addresses
"NOTE: this should be named derive-accounts
this only derive addresses, they still need to be stored
with `multiaccount-store-derived` if you want to be able to
reuse the derived addresses later"
[account-id paths callback]
(log/debug "[native-module] multiaccount-derive-addresses")
(when (status)
(.multiAccountDeriveAddresses ^js (account-manager)
(types/clj->json {:accountID account-id
:paths paths})
callback)))
(defn multiaccount-generate-and-derive-addresses
"used to generate multiple multiaccounts for onboarding
NOTE: nothing is saved so you will need to use
`multiaccount-store-account` on the selected multiaccount
to store the key"
[n mnemonic-length paths callback]
(log/debug "[native-module] multiaccount-generate-and-derive-addresses")
(.multiAccountGenerateAndDeriveAddresses ^js (account-manager)
(types/clj->json {:n n
:mnemonicPhraseLength mnemonic-length
:bip39Passphrase ""
:paths paths})
callback))
(defn multiaccount-import-mnemonic
[mnemonic password callback]
(log/debug "[native-module] multiaccount-import-mnemonic")
(.multiAccountImportMnemonic ^js (account-manager)
(types/clj->json {:mnemonicPhrase mnemonic
;;NOTE this is not the multiaccount password
:Bip39Passphrase password})
callback))
(defn verify
"NOTE: beware, the password has to be sha3 hashed"
[address hashed-password callback]
(log/debug "[native-module] verify")
(.verify ^js (account-manager) address hashed-password callback))
(defn set-soft-input-mode
[mode]
(log/debug "[native-module] set-soft-input-mode")
(.setSoftInputMode ^js (ui-helper) mode))
(defn call-rpc
[payload callback]
(log/debug "[native-module] call-rpc")
(.callRPC ^js (network) payload callback))
(defn call-private-rpc
[payload callback]
(.callPrivateRPC ^js (network) payload callback))
(defn hash-transaction
"used for keycard"
[rpcParams callback]
(log/debug "[native-module] hash-transaction")
(.hashTransaction ^js (encryption) rpcParams callback))
(defn hash-message
"used for keycard"
[message callback]
(log/debug "[native-module] hash-message")
(.hashMessage ^js (encryption) message callback))
(defn start-searching-for-local-pairing-peers
"starts a UDP multicast beacon that both listens for and broadcasts to LAN peers"
[callback]
(log/info "[native-module] Start Searching for Local Pairing Peers"
{:fn :start-searching-for-local-pairing-peers})
(.startSearchForLocalPairingPeers ^js (network) callback))
(defn local-pairing-preflight-outbound-check
"Checks whether the device has allows connecting to the local server"
[callback]
(log/info "[native-module] Performing local pairing preflight check")
(when platform/ios?
(.localPairingPreflightOutboundCheck ^js (encryption) callback)))
(defn get-connection-string-for-bootstrapping-another-device
"Generates connection string form status-go for the purpose of local pairing on the sender end"
[config-json callback]
(log/info "[native-module] Fetching Connection String"
{:fn :get-connection-string-for-bootstrapping-another-device
:config-json config-json})
(.getConnectionStringForBootstrappingAnotherDevice ^js (network) config-json callback))
(defn input-connection-string-for-bootstrapping
"Provides connection string to status-go for the purpose of local pairing on the receiver end"
[connection-string config-json callback]
(log/info "[native-module] Sending Connection String"
{:fn :input-connection-string-for-bootstrapping
:config-json config-json
:connection-string connection-string})
(.inputConnectionStringForBootstrapping ^js (network) connection-string config-json callback))
(defn deserialize-and-compress-key
"Provides a community id (public key) to status-go which is first deserialized
and then compressed. Example input/output :
input key = zQ3shTAten2v9CwyQD1Kc7VXAqNPDcHZAMsfbLHCZEx6nFqk9 and
output key = 0x025596a7ff87da36860a84b0908191ce60a504afc94aac93c1abd774f182967ce6"
[input-key callback]
(log/info "[native-module] Deserializing and then compressing public key"
{:fn :deserialize-and-compress-key
:key input-key})
(.deserializeAndCompressKey ^js (encryption) input-key callback))
(defn serialize-legacy-key
"Compresses an old format public key (0x04...) to the new one zQ..."
[public-key]
(.serializeLegacyKey ^js (encryption) public-key))
(defn compressed-key->public-key
"Provides compressed key to status-go and gets back the uncompressed public key via deserialization"
[public-key deserialization-key callback]
(log/info "[native-module] Deserializing compressed key"
{:fn :compressed-key->public-key
:public-key public-key})
(.multiformatDeserializePublicKey ^js (encryption) public-key deserialization-key callback))
(defn hash-typed-data
"used for keycard"
[data callback]
(log/debug "[native-module] hash-typed-data")
(.hashTypedData ^js (encryption) data callback))
(defn hash-typed-data-v4
"used for keycard"
[data callback]
(log/debug "[native-module] hash-typed-data-v4")
(.hashTypedDataV4 ^js (encryption) data callback))
(defn send-transaction-with-signature
"used for keycard"
[rpcParams sig callback]
(log/debug "[native-module] send-transaction-with-signature")
(.sendTransactionWithSignature ^js (network) rpcParams sig callback))
(defn sign-message
"NOTE: beware, the password in rpcParams has to be sha3 hashed"
([rpcParams]
(native-utils/promisify-native-module-call sign-message rpcParams))
([rpcParams callback]
(log/debug "[native-module] sign-message")
(.signMessage ^js (encryption) rpcParams callback)))
(defn recover-message
[rpcParams callback]
(log/debug "[native-module] recover")
(.recover ^js (network) rpcParams callback))
(defn send-transaction
"NOTE: beware, the password has to be sha3 hashed"
[rpcParams hashed-password callback]
(log/debug "[native-module] send-transaction")
(.sendTransaction ^js (network) rpcParams hashed-password callback))
(defn sign-typed-data
"NOTE: beware, the password has to be sha3 hashed"
([data account hashed-password]
(native-utils/promisify-native-module-call sign-typed-data data account hashed-password))
([data account hashed-password callback]
(log/debug "[native-module] sign-typed-data")
(.signTypedData ^js (encryption) data account hashed-password callback)))
(defn sign-typed-data-v4
"NOTE: beware, the password has to be sha3 hashed"
([data account hashed-password]
(native-utils/promisify-native-module-call sign-typed-data-v4 data account hashed-password))
([data account hashed-password callback]
(log/debug "[native-module] sign-typed-data-v4")
(.signTypedDataV4 ^js (encryption) data account hashed-password callback)))
(defn send-logs
[dbJson js-logs callback]
(log/debug "[native-module] send-logs")
(.sendLogs ^js (log-manager) dbJson js-logs callback))
(defn close-application
[]
(log/debug "[native-module] close-application")
(.closeApplication ^js (status)))
(defn connection-change
[type expensive?]
(log/debug "[native-module] connection-change")
(.connectionChange ^js (status) type (boolean expensive?)))
(defn app-state-change
[state]
(log/debug "[native-module] app-state-change")
(.appStateChange ^js (status) state))
(defn start-local-notifications
[]
(log/debug "[native-module] start-local-notifications")
(.startLocalNotifications ^js (status)))
(defn set-blank-preview-flag
[flag]
(log/debug "[native-module] set-blank-preview-flag")
;; Sometimes the app crashes during logout because `flag` is nil.
(when-not (nil? flag)
(.setBlankPreviewFlag ^js (encryption) flag)))
(defn get-device-model-info
[]
(log/debug "[native-module] get-device-model-info")
;;NOTE: we have to check for status module because of tests
(when-let [^js status-module (status)]
{:model (.-model status-module)
:brand (.-brand status-module)
:build-id (.-buildId status-module)
:device-id (.-deviceId status-module)}))
(defn get-installation-name
[]
;; NOTE(rasom): Only needed for android devices currently
(when platform/android?
(string/join " "
((juxt :model :device-id)
(get-device-model-info)))))
(defn get-node-config
[callback]
(log/debug "[native-module] get-node-config")
(.getNodeConfig ^js (status) callback))
(defn toggle-webview-debug
[on]
(log/debug "[native-module] toggle-webview-debug" on)
(.toggleWebviewDebug ^js (ui-helper) on))
(defn rooted-device?
[callback]
(log/debug "[native-module] rooted-device?")
(cond
;; we assume that iOS is safe by default
platform/ios?
(callback false)
;; we check root on android
platform/android?
(if (status)
(.isDeviceRooted ^js (status) callback)
;; if module isn't initialized we return true to avoid degrading security
(callback true))
;; in unknown scenarios we also consider the device rooted to avoid degrading security
:else (callback true)))
(defn encode-transfer
[to-norm amount-hex]
(log/debug "[native-module] encode-transfer")
(.encodeTransfer ^js (encryption) to-norm amount-hex))
(defn encode-function-call
[method params]
(log/debug "[native-module] encode-function-call")
(.encodeFunctionCall ^js (encryption) method (types/clj->json params)))
(defn decode-parameters
[bytes-string types]
(log/debug "[native-module] decode-parameters")
(let [json-str (.decodeParameters ^js (encryption)
(types/clj->json {:bytesString bytes-string :types types}))]
(types/json->clj json-str)))
(defn hex-to-number
[hex]
(log/debug "[native-module] hex-to-number")
(let [json-str (.hexToNumber ^js (encryption) hex)]
(types/json->clj json-str)))
(defn number-to-hex
[num]
(log/debug "[native-module] number-to-hex")
(.numberToHex ^js (encryption) (str num)))
(defn sha3
[s]
(log/debug "[native-module] sha3")
(when s
(.sha3 ^js (encryption) (str s))))
(defn utf8-to-hex
[s]
(log/debug "[native-module] utf8-to-hex")
(.utf8ToHex ^js (encryption) s))
(defn hex-to-utf8
[s]
(log/debug "[native-module] hex-to-utf8")
(.hexToUtf8 ^js (encryption) s))
(defn check-address-checksum
[address]
(log/debug "[native-module] check-address-checksum")
(let [result (.checkAddressChecksum ^js (utils) address)]
(types/json->clj result)))
(defn toggle-centralized-metrics
[enabled callback]
(.toggleCentralizedMetrics ^js (status) (types/clj->json {:enabled enabled}) callback))
(defn add-centralized-metric
[metric]
(.addCentralizedMetric ^js (status) (types/clj->json metric) #(log/debug "pushed metric" % metric)))
(defn address?
[address]
(log/debug "[native-module] address?")
(when address
(let [result (.isAddress ^js (utils) address)]
(types/json->clj result))))
(defn to-checksum-address
[address]
(log/debug "[native-module] to-checksum-address")
(.toChecksumAddress ^js (utils) address))
(defn validate-mnemonic
"Validate that a mnemonic conforms to BIP39 dictionary/checksum standards"
([mnemonic]
(native-utils/promisify-native-module-call validate-mnemonic mnemonic))
([mnemonic callback]
(log/debug "[native-module] validate-mnemonic")
(.validateMnemonic ^js (utils) mnemonic callback)))
(defn validate-connection-string
[connection-string]
(log/debug "[native-module] validate-connection-string")
(->> connection-string
(.validateConnectionString ^js (utils))
types/json->clj))
(defn delete-multiaccount
"Delete multiaccount from database, deletes multiaccount's database and
key files."
[key-uid callback]
(log/debug "[native-module] delete-multiaccount")
(.deleteMultiaccount ^js (account-manager) key-uid callback))
(defn delete-imported-key
"Delete imported key file."
[key-uid address hashed-password callback]
(log/debug "[native-module] delete-imported-key")
(.deleteImportedKey ^js (status) key-uid address hashed-password callback))
(defn reset-keyboard-input
[input selection]
(log/debug "[native-module] resetKeyboardInput")
(when platform/android?
(.resetKeyboardInputCursor ^js (ui-helper) input selection)))
(defn reset-password
([key-uid current-password-hashed new-password-hashed]
(native-utils/promisify-native-module-call reset-password
key-uid
current-password-hashed
new-password-hashed))
([key-uid current-password-hashed new-password-hashed callback]
(log/debug "[native-module] change-database-password")
(init-keystore
key-uid
#(.reEncryptDbAndKeystore ^js (encryption)
key-uid
current-password-hashed
new-password-hashed
callback))))
(defn convert-to-keycard-profile
[{:keys [key-uid] :as profile} settings password new-password callback]
(.convertToKeycardAccount ^js (encryption)
key-uid
(types/clj->json profile)
(types/clj->json settings)
(:keycard-instance-uid settings)
password
new-password
#(when callback (callback (types/json->clj %)))))
(defn backup-disabled-data-dir
[]
(.backupDisabledDataDir ^js (utils)))
(defn fleets
[]
(.fleets ^js (status)))
(defn keystore-dir
[]
(.keystoreDir ^js (utils)))
(defn log-file-directory
[]
(.logFileDirectory ^js (log-manager)))
(defn get-random-mnemonic
[callback]
(.getRandomMnemonic ^js (account-manager) #(callback (types/json->clj %))))
(defn create-account-from-mnemonic
[mnemonic callback]
(.createAccountFromMnemonicAndDeriveAccountsForPaths ^js (account-manager)
(types/clj->json mnemonic)
#(callback (types/json->clj %))))
(defn get-connection-string-for-exporting-keypairs-keystores
"Generates connection string form status-go for the purpose of exporting keypairs and keystores on sender side"
([config-json]
(native-utils/promisify-native-module-call get-connection-string-for-exporting-keypairs-keystores
config-json))
([config-json callback]
(log/info "[native-module] Fetching Export Keypairs Connection String"
{:fn :get-connection-string-for-exporting-keypairs-keystores
:config-json config-json})
(.getConnectionStringForExportingKeypairsKeystores ^js (network) config-json callback)))
(defn input-connection-string-for-importing-keypairs-keystores
"Provides connection string to status-go for the purpose of importing keypairs and keystores on the receiver side"
([connection-string config-json]
(native-utils/promisify-native-module-call input-connection-string-for-importing-keypairs-keystores
connection-string
config-json))
([connection-string config-json callback]
(log/info "[native-module] Sending Import Keypairs Connection String"
{:fn :input-connection-string-for-importing-keypairs-keystores
:config-json config-json
:connection-string connection-string})
(.inputConnectionStringForImportingKeypairsKeystores ^js (network)
connection-string
config-json
callback)))
(defn create-account-from-private-key
"Validate that a mnemonic conforms to BIP39 dictionary/checksum standards"
([private-key]
(native-utils/promisify-native-module-call create-account-from-private-key private-key))
([private-key callback]
(log/debug "[native-module] create-account-from-private-key")
(.createAccountFromPrivateKey ^js (account-manager)
(types/clj->json {:privateKey private-key})
callback)))