Compare commits
56
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ff4b8d8b6 | ||
|
|
f775010691 | ||
|
|
540094c229 | ||
|
|
08b65cbcb7 | ||
|
|
d623cc8444 | ||
|
|
4b7c906df2 | ||
|
|
3b446963ef | ||
|
|
cec46f985a | ||
|
|
06b2996167 | ||
|
|
02e24208db | ||
|
|
84b8943fd4 | ||
|
|
c52b3e457e | ||
|
|
21cc8a199a | ||
|
|
59374543ef | ||
|
|
9f84a7b912 | ||
|
|
2b0847ef76 | ||
|
|
97b19c5440 | ||
|
|
b3e88508ac | ||
|
|
7b09402fcb | ||
|
|
a912125ba9 | ||
|
|
2d0437dd5e | ||
|
|
43651ef0d0 | ||
|
|
13232dc7b7 | ||
|
|
93b5f7a918 | ||
|
|
4898d32243 | ||
|
|
588692e0eb | ||
|
|
bd9e440839 | ||
|
|
940edc2e53 | ||
|
|
5a93cd755e | ||
|
|
942c130d23 | ||
|
|
bb8aad3be8 | ||
|
|
ba76b9fd51 | ||
|
|
5f085e9cea | ||
|
|
12b8dcf1e7 | ||
|
|
0e6d59b312 | ||
|
|
087fcb1010 | ||
|
|
0de4c8cabb | ||
|
|
6553d5ca44 | ||
|
|
20b256b0d0 | ||
|
|
1c85b292f8 | ||
|
|
d2e975f6d9 | ||
|
|
721aa51d8d | ||
|
|
23c25d7715 | ||
|
|
54e4b597ed | ||
|
|
0b5dac0ad0 | ||
|
|
180065129f | ||
|
|
866b854ee0 | ||
|
|
072370b0d6 | ||
|
|
d74edff9b9 | ||
|
|
0a0591f67a | ||
|
|
7a8db689f4 | ||
|
|
311fde9409 | ||
|
|
f89b66f562 | ||
|
|
d179cbf59b | ||
|
|
7ff7e78691 | ||
|
|
6c352397ab |
@@ -4,7 +4,6 @@ DEFAULT_NETWORK=mainnet_rpc
|
||||
DEV_BUILD=1
|
||||
ETHEREUM_DEV_CLUSTER=1
|
||||
EXTENSIONS=0
|
||||
FLEET=status.prod
|
||||
GROUP_CHATS_ENABLED=1
|
||||
LOG_LEVEL=info
|
||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||
@@ -26,7 +25,6 @@ APN_TOPIC=im.status.ethereum.pr
|
||||
COMMUNITIES_ENABLED=1
|
||||
DATABASE_MANAGEMENT_ENABLED=1
|
||||
DELETE_MESSAGE_ENABLED=1
|
||||
COLLECTIBLES_ENABLED=1
|
||||
COMMANDS_ENABLED=1
|
||||
TWO_MINUTES_SYNCING=1
|
||||
SWAP_ENABLED=1
|
||||
|
||||
@@ -2,7 +2,7 @@ DEBUG_WEBVIEW=1
|
||||
DEFAULT_NETWORK=goerli_rpc
|
||||
ETHEREUM_DEV_CLUSTER=1
|
||||
EXTENSIONS=0
|
||||
FLEET=status.prod
|
||||
FLEET=status.staging
|
||||
GROUP_CHATS_ENABLED=1
|
||||
LOG_LEVEL=debug
|
||||
MAILSERVER_CONFIRMATIONS_ENABLED=0
|
||||
|
||||
@@ -3,7 +3,6 @@ DEBUG_WEBVIEW=1
|
||||
DEFAULT_NETWORK=goerli_rpc
|
||||
ETHEREUM_DEV_CLUSTER=1
|
||||
EXTENSIONS=0
|
||||
FLEET=status.prod
|
||||
GROUP_CHATS_ENABLED=1
|
||||
LOG_LEVEL=debug
|
||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||
|
||||
@@ -2,7 +2,6 @@ DEBUG_WEBVIEW=1
|
||||
DEFAULT_NETWORK=mainnet_rpc
|
||||
ETHEREUM_DEV_CLUSTER=1
|
||||
EXTENSIONS=0
|
||||
FLEET=status.prod
|
||||
GROUP_CHATS_ENABLED=1
|
||||
LOG_LEVEL=info
|
||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||
|
||||
@@ -2,7 +2,6 @@ DEBUG_WEBVIEW=0
|
||||
DEFAULT_NETWORK=mainnet_rpc
|
||||
ETHEREUM_DEV_CLUSTER=0
|
||||
EXTENSIONS=0
|
||||
FLEET=status.prod
|
||||
GROUP_CHATS_ENABLED=1
|
||||
LOG_LEVEL=
|
||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||
@@ -18,6 +17,5 @@ PARTITIONED_TOPIC=0
|
||||
ENABLE_ROOT_ALERT=1
|
||||
MAX_IMAGES_BATCH=1
|
||||
DELETE_MESSAGE_ENABLED=1
|
||||
COLLECTIBLES_ENABLED=1
|
||||
FAST_CREATE_COMMUNITY_ENABLED=0
|
||||
TEST_NETWORKS_ENABLED=0
|
||||
|
||||
+14
-9
@@ -1,10 +1,15 @@
|
||||
*
|
||||
/*
|
||||
|
||||
# Format top-level js files.
|
||||
!*.js
|
||||
!*/
|
||||
*.clj-kondo
|
||||
*.shadow-cljs
|
||||
modules
|
||||
result
|
||||
target
|
||||
component-spec
|
||||
/app
|
||||
|
||||
# Ignore all except src/js/**/*.js
|
||||
!/src/
|
||||
/src/*
|
||||
!/src/js
|
||||
!/src/js/**/*.js
|
||||
|
||||
# Ignore all except translations/en.json
|
||||
!/translations/
|
||||
/translations/*
|
||||
!/translations/en.json
|
||||
|
||||
@@ -6,4 +6,8 @@ module.exports = {
|
||||
tabWidth: 2,
|
||||
trailingComma: 'all',
|
||||
useTabs: false,
|
||||
|
||||
// JSON sorting
|
||||
jsonSortOrder: '{ "/.*/": "caseInsensitiveLexical" } ',
|
||||
plugins: ['prettier-plugin-sort-json'],
|
||||
};
|
||||
|
||||
@@ -317,7 +317,7 @@ lint: ##@test Run code style checks
|
||||
scripts/lint/translations.clj && \
|
||||
zprint '{:search-config? true}' -sfc $$ALL_CLOJURE_FILES && \
|
||||
sh scripts/lint/trailing-newline.sh && \
|
||||
node_modules/.bin/prettier --write .
|
||||
node_modules/.bin/prettier --check .
|
||||
|
||||
# NOTE: We run the linter twice because of https://github.com/kkinnear/zprint/issues/271
|
||||
lint-fix: export TARGET := clojure
|
||||
@@ -457,6 +457,12 @@ android-tail-geth: export VERSION ?= debug
|
||||
android-tail-geth:
|
||||
adb shell 'while true; do cat; sleep 1; done < /storage/emulated/0/Android/data/im.status.ethereum$$( [ "$(VERSION)" = "release" ] || echo ".$(VERSION)" )/files/Download/geth.log'
|
||||
|
||||
android-clean-geth: export TARGET := android-sdk
|
||||
android-clean-geth: export VERSION ?= debug
|
||||
android-clean-geth:
|
||||
adb shell 'rm /storage/emulated/0/Android/data/im.status.ethereum$$( [ "$(VERSION)" = "release" ] || echo ".$(VERSION)" )/files/Download/geth.log'
|
||||
|
||||
|
||||
android-logcat: export TARGET := android-sdk
|
||||
android-logcat: ##@other Read status-mobile logs from Android phone using adb
|
||||
adb logcat | grep -e RNBootstrap -e ReactNativeJS -e ReactNative -e StatusModule -e StatusNativeLogs -e 'F DEBUG :' -e 'Go :' -e 'GoLog :' -e 'libc :'
|
||||
|
||||
@@ -99,7 +99,7 @@ pipeline {
|
||||
--rerun_count=2 \
|
||||
--testrail_report=True \
|
||||
-m testrail_id \
|
||||
-m \"new_ui_critical or new_ui_medium\" \
|
||||
-m \"nightly\" \
|
||||
-k \"${params.KEYWORD_EXPRESSION}\" \
|
||||
--apk=${params.APK_URL ?: apk_path}
|
||||
"""
|
||||
|
||||
@@ -35,13 +35,11 @@ pipeline {
|
||||
description: 'OBSOLETE ARGUMENT TO BE REMOVED',
|
||||
defaultValue: 'DUMMY',
|
||||
)
|
||||
/* Commented to use TEST_MARKERS values from job params
|
||||
string(
|
||||
name: 'TEST_MARKERS',
|
||||
description: 'Marker expression for matching tests to run.',
|
||||
defaultValue: 'new_ui_critical',
|
||||
defaultValue: 'smoke',
|
||||
)
|
||||
*/
|
||||
}
|
||||
|
||||
options {
|
||||
|
||||
+2
-2
@@ -915,7 +915,7 @@ PODS:
|
||||
- glog
|
||||
- RCT-Folly (= 2022.05.16.00)
|
||||
- React-Core
|
||||
- react-native-compat (2.12.2):
|
||||
- react-native-compat (2.11.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2022.05.16.00)
|
||||
- React-Core
|
||||
@@ -1517,7 +1517,7 @@ SPEC CHECKSUMS:
|
||||
react-native-blob-util: 600972b1782380a5a7d5db61a3817ea32349dae9
|
||||
react-native-blur: 799045500f56146afc46245148080e7b7623cb75
|
||||
react-native-cameraroll: af8eec1e585d053ff485d98ec837f9a8a11b5745
|
||||
react-native-compat: 84e00e8dcff9251278c0d48f2bce81f4502e3925
|
||||
react-native-compat: 3af9add14d349701306d3d052638435f6795ac2c
|
||||
react-native-config: 5330c8258265c1e5fdb8c009d2cabd6badd96727
|
||||
react-native-get-random-values: 21325b2244dfa6b58878f51f9aa42821e7ba3d06
|
||||
react-native-hole-view: 6935448993bac79f2b5a4ad7e9741094cf810679
|
||||
|
||||
+8
@@ -246,6 +246,14 @@ class AccountManager(private val reactContext: ReactApplicationContext) : ReactC
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.openAccounts(rootDir) }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
private fun initializeApplication(request: String, callback: Callback) {
|
||||
Log.d(TAG, "initializeApplication")
|
||||
Log.d(TAG, "[Initializing application $request")
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.initializeApplication(request) }, callback)
|
||||
}
|
||||
|
||||
|
||||
@ReactMethod
|
||||
fun logout() {
|
||||
Log.d(TAG, "logout")
|
||||
|
||||
+5
@@ -92,6 +92,11 @@ public class EncryptionUtils extends ReactContextBaseJavaModule {
|
||||
return Statusgo.hexToUtf8(str);
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String serializeLegacyKey(final String publicKey) {
|
||||
return Statusgo.serializeLegacyKey(publicKey);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setBlankPreviewFlag(final Boolean blankPreview) {
|
||||
final SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this.reactContext);
|
||||
|
||||
+10
@@ -76,6 +76,16 @@ class StatusModule(private val reactContext: ReactApplicationContext, private va
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.getNodeConfig() }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun addCentralizedMetric(request: String, callback: Callback) {
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.addCentralizedMetric(request) }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun toggleCentralizedMetrics(request: String, callback: Callback) {
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.toggleCentralizedMetrics(request) }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun deleteImportedKey(keyUID: String, address: String, password: String, callback: Callback) {
|
||||
val keyStoreDir = utils.getKeyStorePath(keyUID)
|
||||
|
||||
@@ -153,4 +153,9 @@ class Utils(private val reactContext: ReactApplicationContext) : ReactContextBas
|
||||
|
||||
return strArray
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
fun validateConnectionString(connectionString: String): String {
|
||||
return Statusgo.validateConnectionString(connectionString)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,6 +195,15 @@ RCT_EXPORT_METHOD(verifyDatabasePassword:(NSString *)keyUID
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(initializeApplication:(NSString *)request
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"initializeApplication() method called");
|
||||
#endif
|
||||
NSString *result = StatusgoInitializeApplication(request);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(openAccounts:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"OpenAccounts() method called");
|
||||
|
||||
@@ -94,6 +94,10 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(hexToUtf8:(NSString *)str) {
|
||||
return StatusgoHexToUtf8(str);
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(serializeLegacyKey:(NSString *)str) {
|
||||
return StatusgoSerializeLegacyKey(str);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setBlankPreviewFlag:(BOOL *)newValue)
|
||||
{
|
||||
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
@@ -176,6 +176,24 @@ RCT_EXPORT_METHOD(appStateChange:(NSString *)type) {
|
||||
StatusgoAppStateChange(type);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(addCentralizedMetric:(NSString *)request
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"addCentralizedMetric() method called");
|
||||
#endif
|
||||
NSString *result = StatusgoAddCentralizedMetric(request);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(toggleCentralizedMetrics:(NSString *)request
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"toggleCentralizedMetrics() method called");
|
||||
#endif
|
||||
NSString *result = StatusgoToggleCentralizedMetrics(request);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(startLocalNotifications) {
|
||||
#if DEBUG
|
||||
NSLog(@"StartLocalNotifications() method called");
|
||||
|
||||
@@ -128,4 +128,8 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(toChecksumAddress:(NSString *)address) {
|
||||
return StatusgoToChecksumAddress(address);
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(validateConnectionString:(NSString *)cs) {
|
||||
return StatusgoValidateConnectionString(cs);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -302,6 +302,36 @@ void _MultiAccountStoreAccount(const FunctionCallbackInfo<Value>& args) {
|
||||
delete c;
|
||||
}
|
||||
|
||||
void _InitializeApplication(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 InitializeApplication")));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the argument types
|
||||
|
||||
if (!args[0]->IsString()) {
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong argument type for request")));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String::Utf8Value arg0Obj(isolate, args[0]->ToString(context).ToLocalChecked());
|
||||
char *arg0 = *arg0Obj;
|
||||
|
||||
// Call exported Go function, which returns a C string
|
||||
char *c = InitializeApplication(arg0);
|
||||
|
||||
Local<String> ret = String::NewFromUtf8(isolate, c).ToLocalChecked();
|
||||
args.GetReturnValue().Set(ret);
|
||||
delete c;
|
||||
}
|
||||
|
||||
void _InitKeystore(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
@@ -642,6 +672,38 @@ void _Sha3(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
}
|
||||
|
||||
void _SerializeLegacyKey(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 SerializeLegacyKey")));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the argument types
|
||||
|
||||
if (!args[0]->IsString()) {
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'str'")));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String::Utf8Value arg0Obj(isolate, args[0]->ToString(context).ToLocalChecked());
|
||||
char *arg0 = *arg0Obj;
|
||||
|
||||
// Call exported Go function, which returns a C string
|
||||
char *c = SerializeLegacyKey(arg0);
|
||||
|
||||
Local<String> ret = String::NewFromUtf8(isolate, c).ToLocalChecked();
|
||||
args.GetReturnValue().Set(ret);
|
||||
delete c;
|
||||
|
||||
}
|
||||
|
||||
void _ToChecksumAddress(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
Local<Context> context = isolate->GetCurrentContext();
|
||||
@@ -1935,6 +1997,7 @@ void init(Local<Object> exports) {
|
||||
NODE_SET_METHOD(exports, "multiAccountStoreDerivedAccounts", _MultiAccountStoreDerivedAccounts);
|
||||
NODE_SET_METHOD(exports, "multiAccountStoreAccount", _MultiAccountStoreAccount);
|
||||
NODE_SET_METHOD(exports, "initKeystore", _InitKeystore);
|
||||
NODE_SET_METHOD(exports, "initializeApplication", _InitializeApplication);
|
||||
NODE_SET_METHOD(exports, "fleets", _Fleets);
|
||||
NODE_SET_METHOD(exports, "stopCPUProfiling", _StopCPUProfiling);
|
||||
NODE_SET_METHOD(exports, "encodeTransfer", _EncodeTransfer);
|
||||
@@ -1945,6 +2008,7 @@ void init(Local<Object> exports) {
|
||||
NODE_SET_METHOD(exports, "checkAddressChecksum", _CheckAddressChecksum);
|
||||
NODE_SET_METHOD(exports, "isAddress", _IsAddress);
|
||||
NODE_SET_METHOD(exports, "sha3", _Sha3);
|
||||
NODE_SET_METHOD(exports, "serializeLegacyKey", _SerializeLegacyKey);
|
||||
NODE_SET_METHOD(exports, "toChecksumAddress", _ToChecksumAddress);
|
||||
NODE_SET_METHOD(exports, "logout", _Logout);
|
||||
NODE_SET_METHOD(exports, "hashMessage", _HashMessage);
|
||||
@@ -1972,7 +2036,7 @@ void init(Local<Object> exports) {
|
||||
NODE_SET_METHOD(exports, "signTypedData", _SignTypedData);
|
||||
NODE_SET_METHOD(exports, "sendTransaction", _SendTransaction);
|
||||
NODE_SET_METHOD(exports, "appStateChange", _AppStateChange);
|
||||
NODE_SET_METHOD(exports, "setSignalEventCallback", _SetSignalEventCallback);
|
||||
NODE_SET_METHOD(exports, "setSignalEventCallback", _SetSignalEventCallback);
|
||||
NODE_SET_METHOD(exports, "validateNodeConfig", _ValidateNodeConfig);
|
||||
NODE_SET_METHOD(exports, "hashTypedData", _HashTypedData);
|
||||
NODE_SET_METHOD(exports, "recover", _Recover);
|
||||
|
||||
+2
-1
@@ -97,7 +97,8 @@
|
||||
"jest-silent-reporter": "^0.5.0",
|
||||
"nodemon": "^2.0.16",
|
||||
"nyc": "^14.1.1",
|
||||
"prettier": "^2.8.8",
|
||||
"prettier": "^3.3.3",
|
||||
"prettier-plugin-sort-json": "^4.0.0",
|
||||
"process": "0.11.10",
|
||||
"react-test-renderer": "18.1.0",
|
||||
"shadow-cljs": "2.26.2",
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 8.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.2 KiB |
@@ -45,6 +45,8 @@ SECRETS_ENV_VARS=(
|
||||
'INFURA_TOKEN'
|
||||
'INFURA_TOKEN_SECRET'
|
||||
'OPENSEA_API_KEY'
|
||||
'MIXPANEL_APP_ID'
|
||||
'MIXPANEL_TOKEN'
|
||||
'POKT_TOKEN'
|
||||
)
|
||||
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
:closure-defines
|
||||
{status-im.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
|
||||
status-im.config/INFURA_TOKEN #shadow/env "INFURA_TOKEN"
|
||||
status-im.config/MIXPANEL_APP_ID #shadow/env "MIXPANEL_APP_ID"
|
||||
status-im.config/MIXPANEL_TOKEN #shadow/env "MIXPANEL_TOKEN"
|
||||
status-im.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"
|
||||
status-im.config/RARIBLE_MAINNET_API_KEY #shadow/env "RARIBLE_MAINNET_API_KEY"
|
||||
status-im.config/RARIBLE_TESTNET_API_KEY #shadow/env "RARIBLE_TESTNET_API_KEY"
|
||||
@@ -102,6 +104,8 @@
|
||||
{status-im.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
|
||||
status-im.config/INFURA_TOKEN #shadow/env "INFURA_TOKEN"
|
||||
status-im.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"
|
||||
status-im.config/MIXPANEL_APP_ID #shadow/env "MIXPANEL_APP_ID"
|
||||
status-im.config/MIXPANEL_TOKEN #shadow/env "MIXPANEL_TOKEN"
|
||||
status-im.config/RARIBLE_MAINNET_API_KEY #shadow/env "RARIBLE_MAINNET_API_KEY"
|
||||
status-im.config/RARIBLE_TESTNET_API_KEY #shadow/env "RARIBLE_TESTNET_API_KEY"
|
||||
status-im.config/ALCHEMY_ETHEREUM_MAINNET_TOKEN #shadow/env "ALCHEMY_ETHEREUM_MAINNET_TOKEN"
|
||||
@@ -143,6 +147,8 @@
|
||||
status-im.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
|
||||
status-im.config/INFURA_TOKEN #shadow/env "INFURA_TOKEN"
|
||||
status-im.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"
|
||||
status-im.config/MIXPANEL_APP_ID #shadow/env "MIXPANEL_APP_ID"
|
||||
status-im.config/MIXPANEL_TOKEN #shadow/env "MIXPANEL_TOKEN"
|
||||
status-im.config/RARIBLE_MAINNET_API_KEY #shadow/env "RARIBLE_MAINNET_API_KEY"
|
||||
status-im.config/RARIBLE_TESTNET_API_KEY #shadow/env "RARIBLE_TESTNET_API_KEY"
|
||||
status-im.config/ALCHEMY_ETHEREUM_MAINNET_TOKEN #shadow/env "ALCHEMY_ETHEREUM_MAINNET_TOKEN"
|
||||
|
||||
+276
-37
@@ -1,38 +1,277 @@
|
||||
(ns keycard.keycard)
|
||||
(ns keycard.keycard
|
||||
(:require
|
||||
["react-native" :as rn]
|
||||
["react-native-status-keycard" :default status-keycard]
|
||||
[react-native.platform :as platform]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.address :as address]))
|
||||
|
||||
(defprotocol Keycard
|
||||
(start-nfc [this args])
|
||||
(stop-nfc [this args])
|
||||
(set-nfc-message [this args])
|
||||
(check-nfc-support [this args])
|
||||
(check-nfc-enabled [this args])
|
||||
(open-nfc-settings [this])
|
||||
(register-card-events [this args])
|
||||
(set-pairings [this args])
|
||||
(on-card-disconnected [this callback])
|
||||
(on-card-connected [this callback])
|
||||
(remove-event-listener [this event])
|
||||
(remove-event-listeners [this])
|
||||
(get-application-info [this args])
|
||||
(factory-reset [this args])
|
||||
(install-applet [this args])
|
||||
(install-cash-applet [this args])
|
||||
(init-card [this args])
|
||||
(install-applet-and-init-card [this args])
|
||||
(pair [this args])
|
||||
(generate-and-load-key [this args])
|
||||
(unblock-pin [this args])
|
||||
(verify-pin [this args])
|
||||
(change-pin [this args])
|
||||
(change-puk [this args])
|
||||
(change-pairing [this args])
|
||||
(unpair [this args])
|
||||
(delete [this args])
|
||||
(remove-key [this args])
|
||||
(remove-key-with-unpair [this args])
|
||||
(export-key [this args])
|
||||
(unpair-and-delete [this args])
|
||||
(import-keys [this args])
|
||||
(get-keys [this args])
|
||||
(sign [this args])
|
||||
(sign-typed-data [this args]))
|
||||
(defonce event-emitter
|
||||
(if platform/ios?
|
||||
(new (.-NativeEventEmitter rn) status-keycard)
|
||||
(.-DeviceEventEmitter rn)))
|
||||
|
||||
(defn start-nfc
|
||||
[{:keys [on-success on-failure prompt-message]}]
|
||||
(log/debug "start-nfc")
|
||||
(.. status-keycard
|
||||
(startNFC (str prompt-message))
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn stop-nfc
|
||||
[{:keys [on-success on-failure error-message]}]
|
||||
(log/debug "stop-nfc")
|
||||
(.. status-keycard
|
||||
(stopNFC (str error-message))
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn set-nfc-message
|
||||
[{:keys [on-success on-failure status-message]}]
|
||||
(log/debug "set-nfc-message")
|
||||
(.. status-keycard
|
||||
(setNFCMessage (str status-message))
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn check-nfc-support
|
||||
[{:keys [on-success]}]
|
||||
(.. status-keycard
|
||||
nfcIsSupported
|
||||
(then on-success)))
|
||||
|
||||
(defn check-nfc-enabled
|
||||
[{:keys [on-success]}]
|
||||
(.. status-keycard
|
||||
nfcIsEnabled
|
||||
(then on-success)))
|
||||
|
||||
(defn open-nfc-settings
|
||||
[]
|
||||
(.openNfcSettings status-keycard))
|
||||
|
||||
(defn remove-event-listeners
|
||||
[]
|
||||
(doseq [event ["keyCardOnConnected" "keyCardOnDisconnected" "keyCardOnNFCUserCancelled"
|
||||
"keyCardOnNFCTimeout"]]
|
||||
(.removeAllListeners ^js event-emitter event)))
|
||||
|
||||
(defn remove-event-listener
|
||||
[^js event]
|
||||
(when event
|
||||
(.remove event)))
|
||||
|
||||
(defn on-card-connected
|
||||
[callback]
|
||||
(.addListener ^js event-emitter "keyCardOnConnected" callback))
|
||||
|
||||
(defn on-card-disconnected
|
||||
[callback]
|
||||
(.addListener ^js event-emitter "keyCardOnDisconnected" callback))
|
||||
|
||||
(defn on-nfc-user-cancelled
|
||||
[callback]
|
||||
(.addListener ^js event-emitter "keyCardOnNFCUserCancelled" callback))
|
||||
|
||||
(defn on-nfc-timeout
|
||||
[callback]
|
||||
(.addListener ^js event-emitter "keyCardOnNFCTimeout" callback))
|
||||
|
||||
(defn on-nfc-enabled
|
||||
[callback]
|
||||
(.addListener ^js event-emitter "keyCardOnNFCEnabled" callback))
|
||||
|
||||
(defn on-nfc-disabled
|
||||
[callback]
|
||||
(.addListener ^js event-emitter "keyCardOnNFCDisabled" callback))
|
||||
|
||||
(defn set-pairings
|
||||
[pairings]
|
||||
(.. status-keycard (setPairings (clj->js (or pairings {})))))
|
||||
|
||||
(defn get-application-info
|
||||
[{:keys [on-success on-failure]}]
|
||||
(.. status-keycard
|
||||
(getApplicationInfo)
|
||||
(then (fn [response]
|
||||
(let [info (-> response
|
||||
(js->clj :keywordize-keys true)
|
||||
(update :key-uid address/normalized-hex))]
|
||||
(on-success info))))
|
||||
(catch on-failure)))
|
||||
|
||||
(defn factory-reset
|
||||
[{:keys [on-success on-failure]}]
|
||||
(.. status-keycard
|
||||
(factoryReset)
|
||||
(then (fn [response]
|
||||
(let [info (-> response
|
||||
(js->clj :keywordize-keys true)
|
||||
(update :key-uid address/normalized-hex))]
|
||||
(on-success info))))
|
||||
(catch on-failure)))
|
||||
|
||||
(defn install-applet
|
||||
[{:keys [on-success on-failure]}]
|
||||
(.. status-keycard
|
||||
installApplet
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn install-cash-applet
|
||||
[{:keys [on-success on-failure]}]
|
||||
(.. status-keycard
|
||||
installCashApplet
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn init-card
|
||||
[{:keys [pin on-success on-failure]}]
|
||||
(.. status-keycard
|
||||
(init pin)
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn install-applet-and-init-card
|
||||
[{:keys [pin on-success on-failure]}]
|
||||
(.. status-keycard
|
||||
(installAppletAndInitCard pin)
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn pair
|
||||
[{:keys [password on-success on-failure]}]
|
||||
(when password
|
||||
(.. status-keycard
|
||||
(pair password)
|
||||
(then on-success)
|
||||
(catch on-failure))))
|
||||
|
||||
(defn generate-and-load-key
|
||||
[{:keys [mnemonic pin on-success on-failure]}]
|
||||
(.. status-keycard
|
||||
(generateAndLoadKey mnemonic pin)
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn unblock-pin
|
||||
[{:keys [puk new-pin on-success on-failure]}]
|
||||
(when (and new-pin puk)
|
||||
(.. status-keycard
|
||||
(unblockPin puk new-pin)
|
||||
(then on-success)
|
||||
(catch on-failure))))
|
||||
|
||||
(defn verify-pin
|
||||
[{:keys [pin on-success on-failure]}]
|
||||
(when (not-empty pin)
|
||||
(.. status-keycard
|
||||
(verifyPin pin)
|
||||
(then on-success)
|
||||
(catch on-failure))))
|
||||
|
||||
(defn change-pin
|
||||
[{:keys [current-pin new-pin on-success on-failure]}]
|
||||
(when (and current-pin new-pin)
|
||||
(.. status-keycard
|
||||
(changePin current-pin new-pin)
|
||||
(then on-success)
|
||||
(catch on-failure))))
|
||||
|
||||
(defn change-puk
|
||||
[{:keys [pin puk on-success on-failure]}]
|
||||
(when (and pin puk)
|
||||
(.. status-keycard
|
||||
(changePUK pin puk)
|
||||
(then on-success)
|
||||
(catch on-failure))))
|
||||
|
||||
(defn change-pairing
|
||||
[{:keys [pin pairing on-success on-failure]}]
|
||||
(when (and pin pairing)
|
||||
(.. status-keycard
|
||||
(changePairingPassword pin pairing)
|
||||
(then on-success)
|
||||
(catch on-failure))))
|
||||
|
||||
(defn unpair
|
||||
[{:keys [pin on-success on-failure]}]
|
||||
(when pin
|
||||
(.. status-keycard
|
||||
(unpair pin)
|
||||
(then on-success)
|
||||
(catch on-failure))))
|
||||
|
||||
(defn delete
|
||||
[{:keys [on-success on-failure]}]
|
||||
(.. status-keycard
|
||||
(delete)
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn remove-key
|
||||
[{:keys [pin on-success on-failure]}]
|
||||
(.. status-keycard
|
||||
(removeKey pin)
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn remove-key-with-unpair
|
||||
[{:keys [pin on-success on-failure]}]
|
||||
(.. status-keycard
|
||||
(removeKeyWithUnpair pin)
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn export-key
|
||||
[{:keys [pin path on-success on-failure]}]
|
||||
(.. status-keycard
|
||||
(exportKeyWithPath pin path)
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn unpair-and-delete
|
||||
[{:keys [pin on-success on-failure]}]
|
||||
(when (not-empty pin)
|
||||
(.. status-keycard
|
||||
(unpairAndDelete pin)
|
||||
(then on-success)
|
||||
(catch on-failure))))
|
||||
|
||||
(defn import-keys
|
||||
[{:keys [pin on-success on-failure]}]
|
||||
(when (not-empty pin)
|
||||
(.. status-keycard
|
||||
(importKeys pin)
|
||||
(then on-success)
|
||||
(catch on-failure))))
|
||||
|
||||
(defn get-keys
|
||||
[{:keys [pin on-success on-failure]}]
|
||||
(when (not-empty pin)
|
||||
(.. status-keycard
|
||||
(getKeys pin)
|
||||
(then on-success)
|
||||
(catch on-failure))))
|
||||
|
||||
(defn sign
|
||||
[{pin :pin path :path card-hash :hash on-success :on-success on-failure :on-failure}]
|
||||
(when (and pin card-hash)
|
||||
(if path
|
||||
(.. status-keycard
|
||||
(signWithPath pin path card-hash)
|
||||
(then on-success)
|
||||
(catch on-failure))
|
||||
(.. status-keycard
|
||||
(sign pin card-hash)
|
||||
(then on-success)
|
||||
(catch on-failure)))))
|
||||
|
||||
(defn sign-typed-data
|
||||
[{card-hash :hash on-success :on-success on-failure :on-failure}]
|
||||
(when card-hash
|
||||
(.. status-keycard
|
||||
(signPinless card-hash)
|
||||
(then on-success)
|
||||
(catch on-failure))))
|
||||
|
||||
@@ -1,365 +0,0 @@
|
||||
(ns keycard.real-keycard
|
||||
(:require
|
||||
["react-native" :as rn]
|
||||
["react-native-status-keycard" :default status-keycard]
|
||||
[keycard.keycard :as keycard]
|
||||
[react-native.platform :as platform]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.address :as address]))
|
||||
|
||||
(defonce event-emitter
|
||||
(if platform/ios?
|
||||
(new (.-NativeEventEmitter rn) status-keycard)
|
||||
(.-DeviceEventEmitter rn)))
|
||||
|
||||
(defonce active-listeners (atom []))
|
||||
|
||||
(defn start-nfc
|
||||
[{:keys [on-success on-failure prompt-message]}]
|
||||
(log/debug "start-nfc")
|
||||
(.. status-keycard
|
||||
(startNFC (str prompt-message))
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn stop-nfc
|
||||
[{:keys [on-success on-failure error-message]}]
|
||||
(log/debug "stop-nfc")
|
||||
(.. status-keycard
|
||||
(stopNFC (str error-message))
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn set-nfc-message
|
||||
[{:keys [on-success on-failure status-message]}]
|
||||
(log/debug "set-nfc-message")
|
||||
(.. status-keycard
|
||||
(setNFCMessage (str status-message))
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn check-nfc-support
|
||||
[{:keys [on-success]}]
|
||||
(.. status-keycard
|
||||
nfcIsSupported
|
||||
(then on-success)))
|
||||
|
||||
(defn check-nfc-enabled
|
||||
[{:keys [on-success]}]
|
||||
(.. status-keycard
|
||||
nfcIsEnabled
|
||||
(then on-success)))
|
||||
|
||||
(defn open-nfc-settings
|
||||
[]
|
||||
(.openNfcSettings status-keycard))
|
||||
|
||||
(defn remove-event-listeners
|
||||
[]
|
||||
(doseq [event ["keyCardOnConnected" "keyCardOnDisconnected" "keyCardOnNFCUserCancelled"
|
||||
"keyCardOnNFCTimeout"]]
|
||||
(.removeAllListeners ^js event-emitter event)))
|
||||
|
||||
(defn remove-event-listener
|
||||
[^js event]
|
||||
(.remove event))
|
||||
|
||||
(defn on-card-connected
|
||||
[callback]
|
||||
(.addListener ^js event-emitter "keyCardOnConnected" callback))
|
||||
|
||||
(defn on-card-disconnected
|
||||
[callback]
|
||||
(.addListener ^js event-emitter "keyCardOnDisconnected" callback))
|
||||
|
||||
(defn on-nfc-user-cancelled
|
||||
[callback]
|
||||
(.addListener ^js event-emitter "keyCardOnNFCUserCancelled" callback))
|
||||
|
||||
(defn on-nfc-timeout
|
||||
[callback]
|
||||
(.addListener ^js event-emitter "keyCardOnNFCTimeout" callback))
|
||||
|
||||
(defn on-nfc-enabled
|
||||
[callback]
|
||||
(.addListener ^js event-emitter "keyCardOnNFCEnabled" callback))
|
||||
|
||||
(defn on-nfc-disabled
|
||||
[callback]
|
||||
(.addListener ^js event-emitter "keyCardOnNFCDisabled" callback))
|
||||
|
||||
(defn set-pairings
|
||||
[{:keys [pairings]}]
|
||||
(.. status-keycard (setPairings (clj->js (or pairings {})))))
|
||||
|
||||
(defn register-card-events
|
||||
[args]
|
||||
(doseq [listener @active-listeners]
|
||||
(remove-event-listener listener))
|
||||
(reset! active-listeners
|
||||
[(on-card-connected (:on-card-connected args))
|
||||
(on-card-disconnected (:on-card-disconnected args))
|
||||
(on-nfc-user-cancelled (:on-nfc-user-cancelled args))
|
||||
(on-nfc-timeout (:on-nfc-timeout args))
|
||||
(on-nfc-enabled (:on-nfc-enabled args))
|
||||
(on-nfc-disabled (:on-nfc-disabled args))]))
|
||||
|
||||
(defn get-application-info
|
||||
[{:keys [on-success on-failure]}]
|
||||
|
||||
(.. status-keycard
|
||||
(getApplicationInfo)
|
||||
(then (fn [response]
|
||||
(let [info (-> response
|
||||
(js->clj :keywordize-keys true)
|
||||
(update :key-uid address/normalized-hex))]
|
||||
(on-success info))))
|
||||
(catch on-failure)))
|
||||
|
||||
(defn factory-reset
|
||||
[{:keys [on-success on-failure]}]
|
||||
(.. status-keycard
|
||||
(factoryReset)
|
||||
(then (fn [response]
|
||||
(let [info (-> response
|
||||
(js->clj :keywordize-keys true)
|
||||
(update :key-uid address/normalized-hex))]
|
||||
(on-success info))))
|
||||
(catch on-failure)))
|
||||
|
||||
(defn install-applet
|
||||
[{:keys [on-success on-failure]}]
|
||||
(.. status-keycard
|
||||
installApplet
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn install-cash-applet
|
||||
[{:keys [on-success on-failure]}]
|
||||
(.. status-keycard
|
||||
installCashApplet
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn init-card
|
||||
[{:keys [pin on-success on-failure]}]
|
||||
(.. status-keycard
|
||||
(init pin)
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn install-applet-and-init-card
|
||||
[{:keys [pin on-success on-failure]}]
|
||||
(.. status-keycard
|
||||
(installAppletAndInitCard pin)
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn pair
|
||||
[{:keys [password on-success on-failure]}]
|
||||
(when password
|
||||
(.. status-keycard
|
||||
(pair password)
|
||||
(then on-success)
|
||||
(catch on-failure))))
|
||||
|
||||
(defn generate-and-load-key
|
||||
[{:keys [mnemonic pin on-success on-failure]}]
|
||||
(.. status-keycard
|
||||
(generateAndLoadKey mnemonic pin)
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn unblock-pin
|
||||
[{:keys [puk new-pin on-success on-failure]}]
|
||||
(when (and new-pin puk)
|
||||
(.. status-keycard
|
||||
(unblockPin puk new-pin)
|
||||
(then on-success)
|
||||
(catch on-failure))))
|
||||
|
||||
(defn verify-pin
|
||||
[{:keys [pin on-success on-failure]}]
|
||||
(when (not-empty pin)
|
||||
(.. status-keycard
|
||||
(verifyPin pin)
|
||||
(then on-success)
|
||||
(catch on-failure))))
|
||||
|
||||
(defn change-pin
|
||||
[{:keys [current-pin new-pin on-success on-failure]}]
|
||||
(when (and current-pin new-pin)
|
||||
(.. status-keycard
|
||||
(changePin current-pin new-pin)
|
||||
(then on-success)
|
||||
(catch on-failure))))
|
||||
|
||||
(defn change-puk
|
||||
[{:keys [pin puk on-success on-failure]}]
|
||||
(when (and pin puk)
|
||||
(.. status-keycard
|
||||
(changePUK pin puk)
|
||||
(then on-success)
|
||||
(catch on-failure))))
|
||||
|
||||
(defn change-pairing
|
||||
[{:keys [pin pairing on-success on-failure]}]
|
||||
(when (and pin pairing)
|
||||
(.. status-keycard
|
||||
(changePairingPassword pin pairing)
|
||||
(then on-success)
|
||||
(catch on-failure))))
|
||||
|
||||
(defn unpair
|
||||
[{:keys [pin on-success on-failure]}]
|
||||
(when pin
|
||||
(.. status-keycard
|
||||
(unpair pin)
|
||||
(then on-success)
|
||||
(catch on-failure))))
|
||||
|
||||
(defn delete
|
||||
[{:keys [on-success on-failure]}]
|
||||
(.. status-keycard
|
||||
(delete)
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn remove-key
|
||||
[{:keys [pin on-success on-failure]}]
|
||||
(.. status-keycard
|
||||
(removeKey pin)
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn remove-key-with-unpair
|
||||
[{:keys [pin on-success on-failure]}]
|
||||
(.. status-keycard
|
||||
(removeKeyWithUnpair pin)
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn export-key
|
||||
[{:keys [pin path on-success on-failure]}]
|
||||
(.. status-keycard
|
||||
(exportKeyWithPath pin path)
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn unpair-and-delete
|
||||
[{:keys [pin on-success on-failure]}]
|
||||
(when (not-empty pin)
|
||||
(.. status-keycard
|
||||
(unpairAndDelete pin)
|
||||
(then on-success)
|
||||
(catch on-failure))))
|
||||
|
||||
(defn import-keys
|
||||
[{:keys [pin on-success on-failure]}]
|
||||
(when (not-empty pin)
|
||||
(.. status-keycard
|
||||
(importKeys pin)
|
||||
(then on-success)
|
||||
(catch on-failure))))
|
||||
|
||||
(defn get-keys
|
||||
[{:keys [pin on-success on-failure]}]
|
||||
(when (not-empty pin)
|
||||
(.. status-keycard
|
||||
(getKeys pin)
|
||||
(then on-success)
|
||||
(catch on-failure))))
|
||||
|
||||
(defn sign
|
||||
[{pin :pin path :path card-hash :hash on-success :on-success on-failure :on-failure}]
|
||||
(when (and pin card-hash)
|
||||
(if path
|
||||
(.. status-keycard
|
||||
(signWithPath pin path card-hash)
|
||||
(then on-success)
|
||||
(catch on-failure))
|
||||
(.. status-keycard
|
||||
(sign pin card-hash)
|
||||
(then on-success)
|
||||
(catch on-failure)))))
|
||||
|
||||
(defn sign-typed-data
|
||||
[{card-hash :hash on-success :on-success on-failure :on-failure}]
|
||||
(when card-hash
|
||||
(.. status-keycard
|
||||
(signPinless card-hash)
|
||||
(then on-success)
|
||||
(catch on-failure))))
|
||||
|
||||
(defrecord RealKeycard []
|
||||
keycard/Keycard
|
||||
(keycard/start-nfc [_this args]
|
||||
(start-nfc args))
|
||||
(keycard/stop-nfc [_this args]
|
||||
(stop-nfc args))
|
||||
(keycard/set-nfc-message [_this args]
|
||||
(set-nfc-message args))
|
||||
(keycard/check-nfc-support [_this args]
|
||||
(check-nfc-support args))
|
||||
(keycard/check-nfc-enabled [_this args]
|
||||
(check-nfc-enabled args))
|
||||
(keycard/open-nfc-settings [_this]
|
||||
(open-nfc-settings))
|
||||
(keycard/register-card-events [_this args]
|
||||
(register-card-events args))
|
||||
(keycard/on-card-connected [_this callback]
|
||||
(on-card-connected callback))
|
||||
(keycard/on-card-disconnected [_this callback]
|
||||
(on-card-disconnected callback))
|
||||
(keycard/remove-event-listener [_this event]
|
||||
(remove-event-listener event))
|
||||
(keycard/remove-event-listeners [_this]
|
||||
(remove-event-listeners))
|
||||
(keycard/set-pairings [_this args]
|
||||
(set-pairings args))
|
||||
(keycard/get-application-info [_this args]
|
||||
(get-application-info args))
|
||||
(keycard/factory-reset [_this args]
|
||||
(factory-reset args))
|
||||
(keycard/install-applet [_this args]
|
||||
(install-applet args))
|
||||
(keycard/install-cash-applet [_this args]
|
||||
(install-cash-applet args))
|
||||
(keycard/init-card [_this args]
|
||||
(init-card args))
|
||||
(keycard/install-applet-and-init-card [_this args]
|
||||
(install-applet-and-init-card args))
|
||||
(keycard/pair [_this args]
|
||||
(pair args))
|
||||
(keycard/generate-and-load-key [_this args]
|
||||
(generate-and-load-key args))
|
||||
(keycard/unblock-pin [_this args]
|
||||
(unblock-pin args))
|
||||
(keycard/verify-pin [_this args]
|
||||
(verify-pin args))
|
||||
(keycard/change-pin [_this args]
|
||||
(change-pin args))
|
||||
(keycard/change-puk [_this args]
|
||||
(change-puk args))
|
||||
(keycard/change-pairing [_this args]
|
||||
(change-pairing args))
|
||||
(keycard/unpair [_this args]
|
||||
(unpair args))
|
||||
(keycard/delete [_this args]
|
||||
(delete args))
|
||||
(keycard/remove-key [_this args]
|
||||
(remove-key args))
|
||||
(keycard/remove-key-with-unpair [_this args]
|
||||
(remove-key-with-unpair args))
|
||||
(keycard/export-key [_this args]
|
||||
(export-key args))
|
||||
(keycard/unpair-and-delete [_this args]
|
||||
(unpair-and-delete args))
|
||||
(keycard/import-keys [_this args]
|
||||
(import-keys args))
|
||||
(keycard/get-keys [_this args]
|
||||
(get-keys args))
|
||||
(keycard/sign [_this args]
|
||||
(sign args))
|
||||
(keycard/sign-typed-data [_this args]
|
||||
(sign-typed-data args)))
|
||||
@@ -26,7 +26,6 @@
|
||||
legacy.status-im.ui.components.invite.events
|
||||
[legacy.status-im.ui.components.react :as react]
|
||||
legacy.status-im.ui.screens.notifications-settings.events
|
||||
legacy.status-im.ui.screens.privacy-and-security-settings.events
|
||||
[legacy.status-im.utils.dimensions :as dimensions]
|
||||
legacy.status-im.utils.logging.core
|
||||
[legacy.status-im.utils.utils :as utils]
|
||||
|
||||
@@ -120,12 +120,3 @@
|
||||
{:events [:multiaccounts.ui/switch-backup-enabled]}
|
||||
[cofx enabled?]
|
||||
(multiaccount-update cofx :backup-enabled? enabled? {}))
|
||||
|
||||
(rf/defn toggle-opensea-nfts-visibility
|
||||
{:events [::toggle-opensea-nfts-visiblity]}
|
||||
[cofx visible?]
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in (:db cofx) [:profile/profile :opensea-enabled?] visible?)
|
||||
;; need to add fully qualified namespace to counter circular deps
|
||||
:dispatch [:legacy.status-im.wallet.core/fetch-collectibles-collection]}
|
||||
(multiaccount-update :opensea-enabled? visible? {})))
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
[{:keys [current-log-level
|
||||
telemetry-enabled?
|
||||
light-client-enabled?
|
||||
store-confirmations-enabled?
|
||||
current-fleet
|
||||
test-networks-enabled?
|
||||
is-goerli-enabled?
|
||||
@@ -77,6 +78,15 @@
|
||||
[:wakuv2.ui/toggle-light-client (not light-client-enabled?)])
|
||||
:accessory :switch
|
||||
:active light-client-enabled?}
|
||||
{:size :small
|
||||
:title (i18n/label :t/store-confirmations)
|
||||
:accessibility-label :store-confirmations
|
||||
:container-margin-bottom 8
|
||||
:on-press
|
||||
#(re-frame/dispatch
|
||||
[:wakuv2.ui/toggle-store-confirmations (not store-confirmations-enabled?)])
|
||||
:accessory :switch
|
||||
:active store-confirmations-enabled?}
|
||||
{:size :small
|
||||
:title "Testnet mode"
|
||||
:accessibility-label :test-networks-enabled
|
||||
@@ -114,13 +124,14 @@
|
||||
|
||||
(views/defview advanced-settings
|
||||
[]
|
||||
(views/letsubs [test-networks-enabled? [:profile/test-networks-enabled?]
|
||||
is-goerli-enabled? [:profile/is-goerli-enabled?]
|
||||
light-client-enabled? [:profile/light-client-enabled?]
|
||||
telemetry-enabled? [:profile/telemetry-enabled?]
|
||||
current-log-level [:log-level/current-log-level]
|
||||
current-fleet [:fleets/current-fleet]
|
||||
peer-syncing-enabled? [:profile/peer-syncing-enabled?]]
|
||||
(views/letsubs [test-networks-enabled? [:profile/test-networks-enabled?]
|
||||
is-goerli-enabled? [:profile/is-goerli-enabled?]
|
||||
light-client-enabled? [:profile/light-client-enabled?]
|
||||
store-confirmations-enabled? [:profile/store-confirmations-enabled?]
|
||||
telemetry-enabled? [:profile/telemetry-enabled?]
|
||||
current-log-level [:log-level/current-log-level]
|
||||
current-fleet [:fleets/current-fleet]
|
||||
peer-syncing-enabled? [:profile/peer-syncing-enabled?]]
|
||||
[:<>
|
||||
[quo/page-nav
|
||||
{:type :title
|
||||
@@ -130,13 +141,14 @@
|
||||
:on-press #(rf/dispatch [:navigate-back])}]
|
||||
[list/flat-list
|
||||
{:data (flat-list-data
|
||||
{:current-log-level current-log-level
|
||||
:telemetry-enabled? telemetry-enabled?
|
||||
:light-client-enabled? light-client-enabled?
|
||||
:current-fleet current-fleet
|
||||
:dev-mode? false
|
||||
:test-networks-enabled? test-networks-enabled?
|
||||
:is-goerli-enabled? is-goerli-enabled?
|
||||
:peer-syncing-enabled? peer-syncing-enabled?})
|
||||
{:current-log-level current-log-level
|
||||
:telemetry-enabled? telemetry-enabled?
|
||||
:light-client-enabled? light-client-enabled?
|
||||
:store-confirmations-enabled? store-confirmations-enabled?
|
||||
:current-fleet current-fleet
|
||||
:dev-mode? false
|
||||
:test-networks-enabled? test-networks-enabled?
|
||||
:is-goerli-enabled? is-goerli-enabled?
|
||||
:peer-syncing-enabled? peer-syncing-enabled?})
|
||||
:key-fn (fn [_ i] (str i))
|
||||
:render-fn render-item}]]))
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
(ns legacy.status-im.ui.screens.dapps-permissions.styles
|
||||
(:require
|
||||
[legacy.status-im.ui.components.colors :as colors]))
|
||||
|
||||
(def icon-container
|
||||
{:width 40
|
||||
:height 40
|
||||
:border-radius 20
|
||||
:background-color colors/gray-lighter
|
||||
:align-items :center
|
||||
:justify-content :center})
|
||||
@@ -1,64 +0,0 @@
|
||||
(ns legacy.status-im.ui.screens.dapps-permissions.views
|
||||
(:require-macros [legacy.status-im.utils.views :as views])
|
||||
(:require
|
||||
[legacy.status-im.ui.components.colors :as colors]
|
||||
[legacy.status-im.ui.components.core :as quo]
|
||||
[legacy.status-im.ui.components.icons.icons :as icons]
|
||||
[legacy.status-im.ui.components.list.item :as list.item]
|
||||
[legacy.status-im.ui.components.list.views :as list]
|
||||
[legacy.status-im.ui.components.react :as react]
|
||||
[legacy.status-im.ui.components.topbar :as topbar]
|
||||
[legacy.status-im.ui.screens.dapps-permissions.styles :as styles]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.constants :as constants]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(defn d-icon
|
||||
[]
|
||||
[react/view styles/icon-container
|
||||
[icons/icon :main-icons/dapp {:color colors/gray}]])
|
||||
|
||||
(defn prepare-items
|
||||
[{:keys [dapp permissions]}]
|
||||
{:title dapp
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:navigate-to :manage-dapps-permissions
|
||||
{:dapp dapp :permissions permissions}])
|
||||
:icon [d-icon]})
|
||||
|
||||
(defn prepare-items-manage
|
||||
[name]
|
||||
(fn [permission]
|
||||
{:title (cond
|
||||
(= permission constants/dapp-permission-web3)
|
||||
name
|
||||
(= permission constants/dapp-permission-contact-code)
|
||||
(i18n/label :t/contact-code))
|
||||
:size :small
|
||||
:accessory [icons/icon :main-icons/check {}]}))
|
||||
|
||||
(views/defview dapps-permissions
|
||||
[]
|
||||
(views/letsubs [permissions [:dapps/permissions]]
|
||||
[list/flat-list
|
||||
{:data (vec (map prepare-items (vals permissions)))
|
||||
:key-fn (fn [_ i] (str i))
|
||||
:render-fn list.item/list-item}]))
|
||||
|
||||
(views/defview manage
|
||||
[]
|
||||
(views/letsubs [{:keys [dapp permissions]} [:get-screen-params]
|
||||
{:keys [name]} [:dapps-account]]
|
||||
[:<>
|
||||
[topbar/topbar {:title dapp}]
|
||||
[list/flat-list
|
||||
{:data (vec (map (prepare-items-manage name) permissions))
|
||||
:key-fn (fn [_ i] (str i))
|
||||
:render-fn list.item/list-item}]
|
||||
[react/view
|
||||
{:padding-vertical 16
|
||||
:padding-horizontal 16}
|
||||
[quo/button
|
||||
{:theme :negative
|
||||
:on-press #(re-frame/dispatch [:dapps/revoke-access dapp])}
|
||||
(i18n/label :t/revoke-access)]]]))
|
||||
@@ -1,13 +0,0 @@
|
||||
(ns legacy.status-im.ui.screens.link-previews-settings.styles)
|
||||
|
||||
(def link-preview-settings-image
|
||||
{:height 100
|
||||
:align-self :center
|
||||
:margin-top 16})
|
||||
|
||||
(def whitelist-container
|
||||
{:flex-direction :row
|
||||
:justify-content :space-between})
|
||||
|
||||
(def enable-all
|
||||
{:align-self :flex-end})
|
||||
@@ -1,67 +0,0 @@
|
||||
(ns legacy.status-im.ui.screens.link-previews-settings.views
|
||||
(:require-macros [legacy.status-im.utils.views :as views])
|
||||
(:require
|
||||
[legacy.status-im.react-native.resources :as resources]
|
||||
[legacy.status-im.ui.components.core :as components]
|
||||
[legacy.status-im.ui.components.list.item :as list.item]
|
||||
[legacy.status-im.ui.components.list.views :as list]
|
||||
[legacy.status-im.ui.components.react :as react]
|
||||
[legacy.status-im.ui.screens.link-previews-settings.styles :as styles]
|
||||
[quo.core :as quo]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.contexts.chat.messenger.messages.link-preview.events]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn prepare-urls-items-data
|
||||
[link-previews-enabled-sites]
|
||||
(fn [{:keys [title address]}]
|
||||
(let [enabled? (contains? link-previews-enabled-sites title)]
|
||||
{:title title
|
||||
:subtitle address
|
||||
:size :small
|
||||
:accessory :switch
|
||||
:active (contains? link-previews-enabled-sites title)
|
||||
:on-press #(re-frame/dispatch
|
||||
[:chat.ui/enable-link-previews title ((complement boolean) enabled?)])})))
|
||||
|
||||
(views/defview link-previews-settings
|
||||
[]
|
||||
(views/letsubs [link-previews-whitelist [:link-previews-whitelist]
|
||||
link-previews-enabled-sites [:link-preview/enabled-sites]]
|
||||
(let [all-enabled (= (count link-previews-whitelist) (count link-previews-enabled-sites))]
|
||||
[:<>
|
||||
[quo/page-nav
|
||||
{:type :title
|
||||
:title (i18n/label :t/chat-link-previews)
|
||||
:background :blur
|
||||
:icon-name :i/close
|
||||
:on-press #(rf/dispatch [:navigate-back])}]
|
||||
[react/image
|
||||
{:source (resources/get-theme-image :unfurl)
|
||||
:style styles/link-preview-settings-image}]
|
||||
[components/text {:style {:margin 16}}
|
||||
(i18n/label :t/you-can-choose-preview-websites)]
|
||||
[components/separator {:style {:margin-vertical 8}}]
|
||||
|
||||
[react/view styles/whitelist-container
|
||||
[components/list-header (i18n/label :t/websites)]
|
||||
|
||||
(when (> (count link-previews-whitelist) 1)
|
||||
[components/button
|
||||
{:on-press #(re-frame/dispatch [:chat.ui/enable-all-link-previews
|
||||
link-previews-whitelist
|
||||
(not all-enabled)])
|
||||
:type :secondary
|
||||
:style styles/enable-all}
|
||||
(if all-enabled
|
||||
(i18n/label :t/disable-all)
|
||||
(i18n/label :t/enable-all))])]
|
||||
[list/flat-list
|
||||
{:data (vec (map (prepare-urls-items-data link-previews-enabled-sites)
|
||||
link-previews-whitelist))
|
||||
:key-fn (fn [_ i] (str i))
|
||||
:render-fn list.item/list-item
|
||||
:footer [quo/text
|
||||
{:color :secondary
|
||||
:style {:margin 16}} (i18n/label :t/previewing-may-share-metadata)]}]])))
|
||||
@@ -1,12 +1,14 @@
|
||||
(ns legacy.status-im.ui.screens.peers-stats
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn peers-stats
|
||||
[]
|
||||
(let [peers-count (rf/sub [:peer-stats/count])]
|
||||
(let [peers-count (rf/sub [:peer-stats/count])
|
||||
theme (rf/sub [:theme])]
|
||||
(rn/use-mount
|
||||
(fn []
|
||||
(rf/dispatch [:peer-stats/get-count])))
|
||||
@@ -18,4 +20,5 @@
|
||||
{:style {:flex-direction :row
|
||||
:margin-vertical 8
|
||||
:justify-content :space-between}}
|
||||
[rn/text (str (i18n/label :t/peers-count) ": " peers-count)]]]))
|
||||
[rn/text {:style {:color (colors/theme-colors colors/neutral-100 colors/white theme)}}
|
||||
(str (i18n/label :t/peers-count) ": " peers-count)]]]))
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
(ns legacy.status-im.ui.screens.privacy-and-security-settings.delete-profile
|
||||
(:require
|
||||
[legacy.status-im.ui.components.chat-icon.screen :as chat-icon.screen]
|
||||
[legacy.status-im.ui.components.core :as quo]
|
||||
[legacy.status-im.ui.components.list.item :as list.item]
|
||||
[legacy.status-im.ui.components.react :as react]
|
||||
[legacy.status-im.ui.screens.privacy-and-security-settings.events :as delete-profile]
|
||||
[re-frame.core :as re-frame]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.contexts.profile.utils :as profile.utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(defn valid-password?
|
||||
[password]
|
||||
(>= (count password) 6))
|
||||
|
||||
(defn on-delete-profile
|
||||
[password]
|
||||
#(do
|
||||
(re-frame/dispatch
|
||||
[::delete-profile/delete-profile @password])
|
||||
(reset! password nil)))
|
||||
|
||||
(defn delete-profile
|
||||
[]
|
||||
(let [password (reagent/atom nil)
|
||||
text-input-ref (atom nil)]
|
||||
(fn []
|
||||
(let [profile @(re-frame/subscribe [:profile/profile])
|
||||
error @(re-frame/subscribe [:delete-profile/error])
|
||||
keep-keys-on-keycard? @(re-frame/subscribe
|
||||
[:delete-profile/keep-keys-on-keycard?])]
|
||||
(when (and @text-input-ref error (not @password))
|
||||
(.clear ^js @text-input-ref))
|
||||
[react/keyboard-avoiding-view {:style {:flex 1}}
|
||||
[react/scroll-view {:style {:flex 1}}
|
||||
[react/view {:style {:align-items :center}}
|
||||
[quo/text
|
||||
{:weight :bold
|
||||
:size :x-large}
|
||||
(i18n/label :t/delete-profile)]]
|
||||
[list.item/list-item
|
||||
{:title (profile.utils/displayed-name profile)
|
||||
:icon [chat-icon.screen/contact-icon-contacts-tab profile]}]
|
||||
[quo/text
|
||||
{:style {:margin-horizontal 24}
|
||||
:align :center
|
||||
:color :negative}
|
||||
(i18n/label :t/delete-profile-warning)]
|
||||
[quo/text-input
|
||||
{:style {:margin-horizontal 36
|
||||
:margin-top 36}
|
||||
:show-cancel false
|
||||
:secure-text-entry true
|
||||
:return-key-type :next
|
||||
:on-submit-editing nil
|
||||
:auto-focus true
|
||||
:on-change-text #(reset! password (security/mask-data %))
|
||||
:bottom-value 36
|
||||
:get-ref #(reset! text-input-ref %)
|
||||
:error (when (and error (not @password))
|
||||
(if (= :wrong-password error)
|
||||
(i18n/label :t/wrong-password)
|
||||
(str error)))}]]
|
||||
[react/view {:style {:align-items :center}}
|
||||
[quo/separator]
|
||||
(when (not keep-keys-on-keycard?)
|
||||
[quo/text
|
||||
{:style {:margin-horizontal 24 :margin-bottom 16}
|
||||
:align :center
|
||||
:color :negative}
|
||||
(i18n/label :t/delete-profile-warning)])
|
||||
[react/view
|
||||
{:style {:margin-vertical 8}}
|
||||
[quo/button
|
||||
{:on-press (on-delete-profile password)
|
||||
:theme :negative
|
||||
:accessibility-label :delete-profile-confirm
|
||||
:disabled ((complement valid-password?) @password)}
|
||||
(i18n/label :t/delete-profile)]]]]))))
|
||||
@@ -1,73 +0,0 @@
|
||||
(ns legacy.status-im.ui.screens.privacy-and-security-settings.events
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[legacy.status-im.utils.deprecated-types :as types]
|
||||
[native-module.core :as native-module]
|
||||
[re-frame.core :as re-frame]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(defn safe-blank?
|
||||
[s]
|
||||
(or (not s)
|
||||
(string/blank? s)))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::delete-profile
|
||||
(fn [{:keys [address key-uid callback masked-password]}]
|
||||
(let [hashed-password
|
||||
(-> masked-password
|
||||
security/safe-unmask-data
|
||||
native-module/sha3)]
|
||||
(native-module/verify
|
||||
address
|
||||
hashed-password
|
||||
(fn [result]
|
||||
(let [{:keys [error]} (types/json->clj result)]
|
||||
(log/info "[delete-profile] verify-password" result error)
|
||||
(if-not (safe-blank? error)
|
||||
(callback :wrong-password nil)
|
||||
(native-module/delete-multiaccount
|
||||
key-uid
|
||||
(fn [result]
|
||||
(let [{:keys [error]} (types/json->clj result)]
|
||||
(callback error nil)))))))))))
|
||||
|
||||
(rf/defn delete-profile
|
||||
{:events [::delete-profile]}
|
||||
[{:keys [db] :as cofx} masked-password]
|
||||
(log/info "[delete-profile] delete")
|
||||
(let [{:keys [key-uid wallet-root-address]} (:profile/profile db)]
|
||||
{:db (dissoc db :delete-profile/error)
|
||||
::delete-profile
|
||||
{:masked-password masked-password
|
||||
:key-uid key-uid
|
||||
:address wallet-root-address
|
||||
:callback
|
||||
(fn [error result]
|
||||
(log/info "[delete-profile] callback" error)
|
||||
(if (safe-blank? error)
|
||||
(re-frame/dispatch [::on-delete-profile-success result])
|
||||
(re-frame/dispatch [::on-delete-profile-failure error])))}}))
|
||||
|
||||
(rf/defn on-delete-profile-success
|
||||
{:events [::on-delete-profile-success]}
|
||||
[cofx]
|
||||
(log/info "[delete-profile] on-success")
|
||||
{:effects.utils/show-popup
|
||||
{:title (i18n/label :t/profile-deleted-title)
|
||||
:content (i18n/label :t/profile-deleted-content)
|
||||
:on-dismiss #(re-frame/dispatch [:logout])}})
|
||||
|
||||
(rf/defn on-delete-profile-failure
|
||||
{:events [::on-delete-profile-failure]}
|
||||
[{:keys [db]} error]
|
||||
(log/info "[delete-profile] on-failure" error)
|
||||
{:db (assoc db :delete-profile/error error)})
|
||||
|
||||
(rf/defn keep-keys-on-keycard
|
||||
{:events [::keep-keys-on-keycard]}
|
||||
[{:keys [db] :as cofx} checked?]
|
||||
{:db (assoc-in db [:delete-profile/keep-keys-on-keycard?] checked?)})
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
(ns legacy.status-im.ui.screens.privacy-and-security-settings.messages-from-contacts-only
|
||||
(:require-macros [legacy.status-im.utils.views :as views])
|
||||
(:require
|
||||
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||
[legacy.status-im.ui.components.list.item :as list.item]
|
||||
[legacy.status-im.ui.components.react :as react]
|
||||
[re-frame.core :as re-frame]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/defn handle-messages-from-contacts-only-switched
|
||||
{:events [::messages-from-contacts-only-switched]}
|
||||
[cofx value]
|
||||
(multiaccounts.update/multiaccount-update cofx
|
||||
:messages-from-contacts-only
|
||||
value
|
||||
{}))
|
||||
|
||||
(views/defview messages-from-contacts-only-view
|
||||
[]
|
||||
(views/letsubs [{:keys [messages-from-contacts-only]} [:profile/profile]]
|
||||
[react/view {:margin-top 8}
|
||||
[list.item/list-item
|
||||
{:active (not messages-from-contacts-only)
|
||||
:accessory :radio
|
||||
:title (i18n/label :t/anyone)
|
||||
:on-press #(re-frame/dispatch [::messages-from-contacts-only-switched false])}]
|
||||
[list.item/list-item
|
||||
{:active messages-from-contacts-only
|
||||
:accessory :radio
|
||||
:title (i18n/label :t/contacts)
|
||||
:subtitle (i18n/label :t/messages-from-contacts-only-subtitle)
|
||||
:subtitle-max-lines 4
|
||||
:on-press #(re-frame/dispatch [::messages-from-contacts-only-switched true])}]]))
|
||||
@@ -1,175 +0,0 @@
|
||||
(ns legacy.status-im.ui.screens.privacy-and-security-settings.views
|
||||
(:require
|
||||
[legacy.status-im.multiaccounts.reset-password.core :as reset-password]
|
||||
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||
[legacy.status-im.ui.components.core :as components]
|
||||
[legacy.status-im.ui.components.list.item :as list.item]
|
||||
[legacy.status-im.ui.components.react :as react]
|
||||
[quo.core :as quo]
|
||||
[re-frame.core :as re-frame]
|
||||
[react-native.platform :as platform]
|
||||
[status-im.config :as config]
|
||||
[status-im.constants :as constants]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf])
|
||||
(:require-macros [legacy.status-im.utils.views :as views]))
|
||||
|
||||
(defn separator
|
||||
[]
|
||||
[components/separator {:style {:margin-vertical 8}}])
|
||||
|
||||
(def titles
|
||||
{constants/profile-pictures-visibility-contacts-only (i18n/label :t/recent-recipients)
|
||||
constants/profile-pictures-visibility-everyone (i18n/label :t/everyone)
|
||||
constants/profile-pictures-visibility-none (i18n/label :t/none)
|
||||
constants/profile-pictures-show-to-contacts-only (i18n/label :t/recent-recipients)
|
||||
constants/profile-pictures-show-to-everyone (i18n/label :t/everyone)
|
||||
constants/profile-pictures-show-to-none (i18n/label :t/none)})
|
||||
|
||||
(views/defview privacy-and-security
|
||||
[]
|
||||
(views/letsubs [{:keys [preview-privacy?
|
||||
messages-from-contacts-only
|
||||
webview-allow-permission-requests?
|
||||
opensea-enabled?
|
||||
profile-pictures-visibility]}
|
||||
[:profile/profile]
|
||||
has-picture [:profile/has-picture]
|
||||
profile-pictures-show-to [:multiaccount/profile-pictures-show-to]]
|
||||
[:<>
|
||||
[quo/page-nav
|
||||
{:type :no-title
|
||||
:background :blur
|
||||
:icon-name :i/close
|
||||
:on-press #(rf/dispatch [:navigate-back])}]
|
||||
[react/scroll-view {:padding-vertical 8}
|
||||
[components/list-header (i18n/label :t/privacy)]
|
||||
[list.item/list-item
|
||||
{:size :small
|
||||
:title (i18n/label :t/set-dapp-access-permissions)
|
||||
:on-press #(re-frame/dispatch [:navigate-to :dapps-permissions])
|
||||
:accessibility-label :dapps-permissions-button
|
||||
:chevron true}]
|
||||
[list.item/list-item
|
||||
{:size :small
|
||||
:title (if platform/android?
|
||||
(i18n/label :t/hide-content-when-switching-apps)
|
||||
(i18n/label :t/hide-content-when-switching-apps-ios))
|
||||
:container-margin-bottom 8
|
||||
:active preview-privacy?
|
||||
:accessory :switch
|
||||
:on-press #(re-frame/dispatch
|
||||
[:profile.settings/change-preview-privacy
|
||||
((complement boolean) preview-privacy?)])}]
|
||||
(when config/collectibles-enabled?
|
||||
[list.item/list-item
|
||||
{:size :small
|
||||
:title (i18n/label :t/display-collectibles)
|
||||
:container-margin-bottom 8
|
||||
:active opensea-enabled?
|
||||
:accessory :switch
|
||||
:on-press #(re-frame/dispatch
|
||||
[::multiaccounts.update/toggle-opensea-nfts-visiblity
|
||||
(not opensea-enabled?)])}])
|
||||
[list.item/list-item
|
||||
{:size :small
|
||||
:title (i18n/label :t/chat-link-previews)
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:open-modal :legacy-link-previews-settings])
|
||||
:accessibility-label :chat-link-previews}]
|
||||
[list.item/list-item
|
||||
{:size :small
|
||||
:title (i18n/label :t/accept-new-chats-from)
|
||||
:chevron true
|
||||
:accessory :text
|
||||
:accessory-text (i18n/label (if messages-from-contacts-only
|
||||
:t/contacts
|
||||
:t/anyone))
|
||||
:on-press #(re-frame/dispatch [:navigate-to :messages-from-contacts-only])
|
||||
:accessibility-label :accept-new-chats-from}]
|
||||
[list.item/list-item
|
||||
{:size :small
|
||||
:title (i18n/label :t/reset-password)
|
||||
:chevron true
|
||||
:accessory :text
|
||||
:on-press #(do
|
||||
(re-frame/dispatch [::reset-password/clear-form-vals])
|
||||
(re-frame/dispatch [:navigate-to :reset-password]))
|
||||
:accessibility-label :reset-password}]
|
||||
(when platform/android?
|
||||
[list.item/list-item
|
||||
{:size :small
|
||||
:title (i18n/label :t/webview-camera-permission-requests)
|
||||
:active webview-allow-permission-requests?
|
||||
:accessory :switch
|
||||
:subtitle (i18n/label :t/webview-camera-permission-requests-subtitle)
|
||||
:subtitle-max-lines 2
|
||||
:on-press #(re-frame/dispatch
|
||||
[:profile.settings/profile-update
|
||||
:webview-allow-permission-requests?
|
||||
((complement boolean) webview-allow-permission-requests?)])}])
|
||||
[separator]
|
||||
[components/list-header (i18n/label :t/privacy-photos)]
|
||||
[list.item/list-item
|
||||
{:size :small
|
||||
:title (i18n/label :t/show-profile-pictures)
|
||||
:accessibility-label :show-profile-pictures
|
||||
:accessory :text
|
||||
:accessory-text (get titles profile-pictures-visibility)
|
||||
:on-press #(re-frame/dispatch [:navigate-to :privacy-and-security-profile-pic])
|
||||
:chevron true}]
|
||||
[list.item/list-item
|
||||
{:size :small
|
||||
:title (i18n/label :t/show-profile-pictures-to)
|
||||
:disabled (not has-picture)
|
||||
:accessibility-label :show-profile-pictures-to
|
||||
:accessory :text
|
||||
:accessory-text (get titles profile-pictures-show-to)
|
||||
:on-press #(re-frame/dispatch [:navigate-to
|
||||
:privacy-and-security-profile-pic-show-to])
|
||||
:chevron true}]
|
||||
|
||||
[separator]
|
||||
[list.item/list-item
|
||||
{:size :small
|
||||
:theme :negative
|
||||
:title (i18n/label :t/delete-my-profile)
|
||||
:on-press #(re-frame/dispatch [:navigate-to :delete-profile])
|
||||
:accessibility-label :dapps-permissions-button
|
||||
:chevron true}]]]))
|
||||
|
||||
(defn ppst-radio-item
|
||||
[id value]
|
||||
[list.item/list-item
|
||||
{:active (= value id)
|
||||
:accessory :radio
|
||||
:title (get titles id)
|
||||
:on-press #(re-frame/dispatch [:profile.settings/change-profile-pictures-show-to id])}])
|
||||
|
||||
(views/defview profile-pic-show-to
|
||||
[]
|
||||
(views/letsubs [{:keys [profile-pictures-show-to]} [:profile/profile]]
|
||||
[react/view {:margin-top 8}
|
||||
[ppst-radio-item constants/profile-pictures-show-to-everyone profile-pictures-show-to]
|
||||
[ppst-radio-item constants/profile-pictures-show-to-contacts-only profile-pictures-show-to]
|
||||
[ppst-radio-item constants/profile-pictures-show-to-none profile-pictures-show-to]
|
||||
|
||||
[react/view {:style {:margin-horizontal 16}}
|
||||
[components/text {:color :secondary}
|
||||
(i18n/label :t/privacy-show-to-warning)]]]))
|
||||
|
||||
(defn ppvf-radio-item
|
||||
[id value]
|
||||
[list.item/list-item
|
||||
{:active (= value id)
|
||||
:accessory :radio
|
||||
:title (get titles id)
|
||||
:on-press #(re-frame/dispatch [:profile.settings/profile-update :profile-pictures-visibility id])}])
|
||||
|
||||
(views/defview profile-pic
|
||||
[]
|
||||
(views/letsubs [{:keys [profile-pictures-visibility]} [:profile/profile]]
|
||||
[react/view {:margin-top 8}
|
||||
[ppvf-radio-item constants/profile-pictures-visibility-everyone profile-pictures-visibility]
|
||||
[ppvf-radio-item constants/profile-pictures-visibility-contacts-only profile-pictures-visibility]
|
||||
[ppvf-radio-item constants/profile-pictures-visibility-none profile-pictures-visibility]]))
|
||||
@@ -13,12 +13,6 @@
|
||||
[]
|
||||
[rn/scroll-view {:flex 1}
|
||||
[components/list-header "Legacy settings"]
|
||||
[list.item/list-item
|
||||
{:icon :main-icons/security
|
||||
:title (i18n/label :t/privacy-and-security)
|
||||
:accessibility-label :privacy-and-security-settings-button
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:open-modal :legacy-privacy-and-security])}]
|
||||
[list.item/list-item
|
||||
{:icon :main-icons/mobile
|
||||
:title (i18n/label :t/sync-settings)
|
||||
|
||||
@@ -8,12 +8,10 @@
|
||||
[legacy.status-im.ui.screens.bug-report :as bug-report]
|
||||
[legacy.status-im.ui.screens.communities.invite :as communities.invite]
|
||||
[legacy.status-im.ui.screens.communities.members :as members]
|
||||
[legacy.status-im.ui.screens.dapps-permissions.views :as dapps-permissions]
|
||||
[legacy.status-im.ui.screens.default-sync-period-settings.view :as default-sync-period-settings]
|
||||
[legacy.status-im.ui.screens.fleet-settings.views :as fleet-settings]
|
||||
[legacy.status-im.ui.screens.glossary.view :as glossary]
|
||||
[legacy.status-im.ui.screens.help-center.views :as help-center]
|
||||
[legacy.status-im.ui.screens.link-previews-settings.views :as link-previews-settings]
|
||||
[legacy.status-im.ui.screens.log-level-settings.views :as log-level-settings]
|
||||
[legacy.status-im.ui.screens.mobile-network-settings.view :as mobile-network-settings]
|
||||
[legacy.status-im.ui.screens.notifications-settings.views :as notifications-settings]
|
||||
@@ -21,10 +19,6 @@
|
||||
[legacy.status-im.ui.screens.offline-messaging-settings.views :as offline-messaging-settings]
|
||||
[legacy.status-im.ui.screens.pairing.views :as pairing]
|
||||
[legacy.status-im.ui.screens.peers-stats :as peers-stats]
|
||||
[legacy.status-im.ui.screens.privacy-and-security-settings.delete-profile :as delete-profile]
|
||||
[legacy.status-im.ui.screens.privacy-and-security-settings.messages-from-contacts-only :as
|
||||
messages-from-contacts-only]
|
||||
[legacy.status-im.ui.screens.privacy-and-security-settings.views :as privacy-and-security]
|
||||
[legacy.status-im.ui.screens.profile.seed.views :as profile.seed]
|
||||
[legacy.status-im.ui.screens.profile.user.views :as profile.user]
|
||||
[legacy.status-im.ui.screens.progress.views :as progress]
|
||||
@@ -94,17 +88,6 @@
|
||||
:insets {:top? platform/android?}}
|
||||
:component profile.user/legacy-settings}
|
||||
|
||||
;; PRIVACY AND SECURITY
|
||||
{:name :legacy-privacy-and-security
|
||||
:options {:topBar {:visible false}
|
||||
:insets {:top? platform/android?}}
|
||||
:component privacy-and-security/privacy-and-security}
|
||||
|
||||
{:name :legacy-link-previews-settings
|
||||
:options {:topBar {:visible false}
|
||||
:insets {:top? platform/android?}}
|
||||
:component link-previews-settings/link-previews-settings}
|
||||
|
||||
;; SYNC
|
||||
{:name :legacy-sync-settings
|
||||
:options {:topBar {:visible false}
|
||||
@@ -150,25 +133,6 @@
|
||||
{:name :edit-mailserver
|
||||
:options {:insets {:top? true}}
|
||||
:component edit-mailserver/edit-mailserver}
|
||||
{:name :dapps-permissions
|
||||
:options {:topBar (topbar-options :t/dapps-permissions)
|
||||
:insets {:top? true}}
|
||||
:component dapps-permissions/dapps-permissions}
|
||||
{:name :messages-from-contacts-only
|
||||
:options {:topBar (topbar-options :t/accept-new-chats-from)
|
||||
:insets {:top? true}}
|
||||
:component messages-from-contacts-only/messages-from-contacts-only-view}
|
||||
{:name :privacy-and-security-profile-pic-show-to
|
||||
:options {:topbar (topbar-options :t/show-profile-pictures-to)
|
||||
:insets {:top? true}}
|
||||
:component privacy-and-security/profile-pic-show-to}
|
||||
{:name :privacy-and-security-profile-pic
|
||||
:options {:topBar (topbar-options :t/show-profile-pictures)
|
||||
:insets {:top? true}}
|
||||
:component privacy-and-security/profile-pic}
|
||||
{:name :manage-dapps-permissions
|
||||
:options {:insets {:top? true}}
|
||||
:component dapps-permissions/manage}
|
||||
{:name :rpc-usage-info
|
||||
:options {:topBar (topbar-options :t/rpc-usage-info)
|
||||
:insets {:top? true}}
|
||||
@@ -196,9 +160,6 @@
|
||||
:options {:topBar (topbar-options :t/reset-password)
|
||||
:insets {:top? true}}
|
||||
:component reset-password/reset-password}
|
||||
{:name :delete-profile
|
||||
:insets {:bottom? true}
|
||||
:component delete-profile/delete-profile}
|
||||
{:name :default-sync-period-settings
|
||||
:options {:topBar (topbar-options :t/default-sync-period)
|
||||
:insets {:top? true}}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
(ns legacy.status-im.utils.hex
|
||||
(:require
|
||||
[clojure.string :as string]))
|
||||
|
||||
(defn normalize-hex
|
||||
[hex]
|
||||
(when hex
|
||||
(string/lower-case (if (string/starts-with? hex "0x")
|
||||
(subs hex 2)
|
||||
hex))))
|
||||
|
||||
(defn valid-hex?
|
||||
[hex]
|
||||
(let [hex (normalize-hex hex)]
|
||||
(and (re-matches #"^[0-9a-fA-F]+$" hex)
|
||||
(not= (js/parseInt hex 16) 0))))
|
||||
@@ -1,58 +0,0 @@
|
||||
(ns legacy.status-im.utils.keychain.core
|
||||
(:require
|
||||
[oops.core :as oops]
|
||||
[re-frame.core :as re-frame]
|
||||
[react-native.keychain :as keychain]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- whisper-key-name
|
||||
[address]
|
||||
(str address "-whisper"))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keychain/get-keycard-keys
|
||||
(fn [[key-uid callback]]
|
||||
(keychain/get-credentials
|
||||
key-uid
|
||||
(fn [encryption-key-data]
|
||||
(if encryption-key-data
|
||||
(keychain/get-credentials
|
||||
(whisper-key-name key-uid)
|
||||
(fn [whisper-key-data]
|
||||
(if whisper-key-data
|
||||
(callback [(oops/oget encryption-key-data "password")
|
||||
(oops/oget whisper-key-data "password")])
|
||||
(callback nil))))
|
||||
(callback nil))))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keychain/save-keycard-keys
|
||||
(fn [[key-uid encryption-public-key whisper-private-key]]
|
||||
(keychain/save-credentials
|
||||
key-uid
|
||||
key-uid
|
||||
encryption-public-key
|
||||
#(when-not %
|
||||
(log/error
|
||||
(str "Error while saving encryption-public-key"))))
|
||||
(keychain/save-credentials
|
||||
(whisper-key-name key-uid)
|
||||
key-uid
|
||||
whisper-private-key
|
||||
#(when-not %
|
||||
(log/error
|
||||
(str "Error while saving whisper-private-key"))))))
|
||||
|
||||
(rf/defn get-keycard-keys
|
||||
[_ key-uid]
|
||||
{:keychain/get-keycard-keys
|
||||
[key-uid
|
||||
#(re-frame/dispatch
|
||||
[:multiaccounts.login.callback/get-keycard-keys-success key-uid %])]})
|
||||
|
||||
(rf/defn save-keycard-keys
|
||||
[_ key-uid encryption-public-key whisper-private-key]
|
||||
{:keychain/save-keycard-keys [key-uid
|
||||
encryption-public-key
|
||||
whisper-private-key]})
|
||||
@@ -1,130 +0,0 @@
|
||||
(ns legacy.status-im.utils.test
|
||||
(:require
|
||||
[legacy.status-im.utils.deprecated-types :as types]
|
||||
[re-frame.core :as re-frame]))
|
||||
|
||||
(def native-status (js/require "../../modules/react-native-status/nodejs/bindings"))
|
||||
|
||||
(def fs (js/require "fs"))
|
||||
(def path (js/require "path"))
|
||||
(def os (js/require "os"))
|
||||
|
||||
(def tmpdir (.tmpdir os))
|
||||
|
||||
(def test-dir-prefix (.join path tmpdir "status-mobile-tests"))
|
||||
|
||||
(def test-dir (.mkdtempSync fs test-dir-prefix))
|
||||
|
||||
(def initialized? (atom false))
|
||||
|
||||
(defn signal-received-callback
|
||||
[a]
|
||||
(re-frame/dispatch [:signals/signal-received a]))
|
||||
|
||||
;; We poll for signals, could not get callback working
|
||||
(defn init!
|
||||
[]
|
||||
(when-not @initialized?
|
||||
(.setSignalEventCallback native-status)
|
||||
(reset! initialized? true)
|
||||
(js/setInterval (fn []
|
||||
(.pollSignal native-status signal-received-callback)
|
||||
100))))
|
||||
|
||||
(def ui-helper
|
||||
(clj->js
|
||||
{:clearCookies identity
|
||||
:clearStorageAPIs identity}))
|
||||
|
||||
(def encryption-utils
|
||||
(clj->js
|
||||
{:sha3
|
||||
(fn [s] (.sha3 native-status s))
|
||||
:setBlankPreviewFlag
|
||||
identity
|
||||
:encodeTransfer
|
||||
(fn [to-norm amount-hex]
|
||||
(.encodeTransfer native-status to-norm amount-hex))
|
||||
:hexToNumber
|
||||
(fn [hex] (.hexToNumber native-status hex))
|
||||
:decodeParameters
|
||||
(fn [decode-param-json]
|
||||
(.decodeParameters native-status decode-param-json))
|
||||
:numberToHex
|
||||
(fn [num-str] (.numberToHex native-status num-str))
|
||||
:initKeystore
|
||||
(fn [key-uid callback]
|
||||
(callback (.initKeystore native-status
|
||||
(str test-dir "/keystore/" key-uid))))
|
||||
:multiformatDeserializePublicKey
|
||||
(fn [public-key deserialization-key callback]
|
||||
(callback (.multiformatDeserializePublicKey
|
||||
native-status
|
||||
public-key
|
||||
deserialization-key)))}))
|
||||
|
||||
(def account-manager
|
||||
(clj->js
|
||||
{:openAccounts
|
||||
(fn [callback]
|
||||
(callback (.openAccounts native-status test-dir)))
|
||||
:createAccountAndLogin
|
||||
(fn [request] (.createAccountAndLogin native-status request))
|
||||
:logout
|
||||
(fn [] (.logout native-status))
|
||||
:multiAccountImportMnemonic
|
||||
(fn [json callback]
|
||||
(callback (.multiAccountImportMnemonic native-status json)))
|
||||
:multiAccountLoadAccount
|
||||
(fn [json callback]
|
||||
(callback (.multiAccountLoadAccount native-status json)))
|
||||
:multiAccountDeriveAddresses
|
||||
(fn [json callback]
|
||||
(callback (.multiAccountDeriveAddresses native-status json)))
|
||||
:multiAccountGenerateAndDeriveAddresses
|
||||
(fn [json callback]
|
||||
(callback (.multiAccountGenerateAndDeriveAddresses native-status json)))
|
||||
:multiAccountStoreDerived
|
||||
(fn [json callback]
|
||||
(callback (.multiAccountStoreDerivedAccounts native-status json)))}))
|
||||
|
||||
(def utils
|
||||
(clj->js
|
||||
{:backupDisabledDataDir
|
||||
(fn [] (str test-dir "/backup"))
|
||||
:keystoreDir (fn [] "")
|
||||
:toChecksumAddress
|
||||
(fn [address] (.toChecksumAddress native-status address))
|
||||
:checkAddressChecksum
|
||||
(fn [address] (.checkAddressChecksum native-status address))
|
||||
:validateMnemonic
|
||||
(fn [json callback] (callback (.validateMnemonic native-status json)))
|
||||
:isAddress
|
||||
(fn [address] (.isAddress native-status address))}))
|
||||
|
||||
(def log-manager
|
||||
(clj->js
|
||||
{:logFileDirectory
|
||||
(fn [] (str test-dir "/log"))
|
||||
:initLogging
|
||||
(fn [enabled mobile-system log-level callback]
|
||||
(callback (.initLogging native-status
|
||||
(types/clj->json {:Enabled enabled
|
||||
:MobileSystem mobile-system
|
||||
:Level log-level
|
||||
:File (str test-dir "/geth.log")}))))}))
|
||||
|
||||
(def network
|
||||
(clj->js
|
||||
{:callPrivateRPC
|
||||
(fn [payload callback]
|
||||
(callback (.callPrivateRPC native-status payload)))}))
|
||||
|
||||
(def status
|
||||
(clj->js
|
||||
{:getNodeConfig
|
||||
(fn [] (types/clj->json {:WakuV2Config ""}))
|
||||
:fleets
|
||||
(fn [] (.fleets native-status))
|
||||
:startLocalNotifications
|
||||
identity}))
|
||||
@@ -137,3 +137,19 @@
|
||||
:on-error #(log/error "failed to set light client"
|
||||
{:error %
|
||||
:enabled? enabled?})}]})
|
||||
|
||||
(rf/defn toggle-store-confirmations
|
||||
{:events [:wakuv2.ui/toggle-store-confirmations]}
|
||||
[{:keys [db]} enabled?]
|
||||
{:db (assoc-in db
|
||||
[:profile/profile :wakuv2-config :EnableStoreConfirmationForMessagesSent]
|
||||
enabled?)
|
||||
|
||||
:json-rpc/call [{:method "wakuext_setStoreConfirmationForMessagesSent"
|
||||
:params [{:enabled enabled?}]
|
||||
:on-success (fn []
|
||||
(log/info "store confirmation set successfully" enabled?)
|
||||
(re-frame/dispatch [:logout]))
|
||||
:on-error #(log/error "failed to set store confirmation"
|
||||
{:error %
|
||||
:enabled? enabled?})}]})
|
||||
|
||||
@@ -110,8 +110,11 @@
|
||||
(def status-keycard
|
||||
#js
|
||||
{:default #js
|
||||
{:nfcIsSupported (fn [] #js {:then identity})
|
||||
:nfcIsEnabled (fn [] #js {:then identity})}})
|
||||
{:nfcIsSupported (fn [] #js {:then identity})
|
||||
:nfcIsEnabled (fn [] #js {:then identity})
|
||||
:getApplicationInfo (fn [] #js {:then identity})
|
||||
:getKeys (fn [] #js {:then identity})
|
||||
:setPairings (fn [] #js {:then identity})}})
|
||||
|
||||
(def snoopy #js {:default #js {}})
|
||||
(def snoopy-filter #js {:default #js {}})
|
||||
|
||||
+26
-100
@@ -72,10 +72,12 @@
|
||||
(log/debug "[native-module] init-keystore" key-uid)
|
||||
(.initKeystore ^js (encryption) key-uid callback))
|
||||
|
||||
(defn open-accounts
|
||||
[callback]
|
||||
(log/debug "[native-module] open-accounts")
|
||||
(.openAccounts ^js (account-manager) #(callback (types/json->clj %))))
|
||||
(defn initialize-application
|
||||
[request callback]
|
||||
(log/debug "[native-module] initialize-application")
|
||||
(.initializeApplication ^js (account-manager)
|
||||
(types/clj->json request)
|
||||
#(callback (types/json->clj %))))
|
||||
|
||||
(defn prepare-dir-and-update-config
|
||||
[key-uid config callback]
|
||||
@@ -85,31 +87,6 @@
|
||||
config
|
||||
#(callback (types/json->clj %))))
|
||||
|
||||
(defn save-multiaccount-and-login-with-keycard
|
||||
"NOTE: chat-key is a whisper private key sent from keycard"
|
||||
[key-uid multiaccount-data password settings config accounts-data chat-key]
|
||||
(log/debug "[native-module] save-account-and-login-with-keycard")
|
||||
(init-keystore
|
||||
key-uid
|
||||
#(.saveAccountAndLoginWithKeycard
|
||||
^js (account-manager)
|
||||
multiaccount-data
|
||||
password
|
||||
settings
|
||||
config
|
||||
accounts-data
|
||||
chat-key)))
|
||||
|
||||
(defn login-with-config
|
||||
"NOTE: beware, the password has to be sha3 hashed"
|
||||
[key-uid account-data hashed-password config]
|
||||
(log/debug "[native-module] loginWithConfig")
|
||||
(clear-web-data)
|
||||
(let [config (if config (types/clj->json config) "")]
|
||||
(init-keystore
|
||||
key-uid
|
||||
#(.loginWithConfig ^js (account-manager) account-data hashed-password config))))
|
||||
|
||||
(defn login-account
|
||||
"NOTE: beware, the password has to be sha3 hashed"
|
||||
[{:keys [keyUid] :as request}]
|
||||
@@ -151,19 +128,6 @@
|
||||
(clear-web-data)
|
||||
(.logout ^js (account-manager)))
|
||||
|
||||
(defn multiaccount-load-account
|
||||
"NOTE: beware, the password has to be sha3 hashed
|
||||
|
||||
this function is used after storing an account when you still want to
|
||||
derive accounts from it, because saving an account flushes the loaded keys
|
||||
from memory"
|
||||
[address hashed-password callback]
|
||||
(log/debug "[native-module] multiaccount-load-account")
|
||||
(.multiAccountLoadAccount ^js (account-manager)
|
||||
(types/clj->json {:address address
|
||||
:password hashed-password})
|
||||
callback))
|
||||
|
||||
(defn multiaccount-derive-addresses
|
||||
"NOTE: this should be named derive-accounts
|
||||
this only derive addresses, they still need to be stored
|
||||
@@ -177,38 +141,6 @@
|
||||
:paths paths})
|
||||
callback)))
|
||||
|
||||
(defn multiaccount-store-account
|
||||
"NOTE: beware, the password has to be sha3 hashed
|
||||
|
||||
this stores the account and flush keys in memory so
|
||||
in order to also store derived accounts like initial wallet
|
||||
and chat accounts, you need to load the account again with
|
||||
`multiaccount-load-account` before using `multiaccount-store-derived`
|
||||
and the id of the account stored will have changed"
|
||||
[account-id key-uid hashed-password callback]
|
||||
(log/debug "[native-module] multiaccount-store-account")
|
||||
(when (status)
|
||||
(init-keystore
|
||||
key-uid
|
||||
#(.multiAccountStoreAccount ^js (account-manager)
|
||||
(types/clj->json {:accountID account-id
|
||||
:password hashed-password})
|
||||
callback))))
|
||||
|
||||
(defn multiaccount-store-derived
|
||||
"NOTE: beware, the password has to be sha3 hashed"
|
||||
[account-id key-uid paths hashed-password callback]
|
||||
(log/debug "[native-module] multiaccount-store-derived"
|
||||
"account-id"
|
||||
account-id)
|
||||
(init-keystore
|
||||
key-uid
|
||||
#(.multiAccountStoreDerived ^js (account-manager)
|
||||
(types/clj->json {:accountID account-id
|
||||
:paths paths
|
||||
:password hashed-password})
|
||||
callback)))
|
||||
|
||||
(defn multiaccount-generate-and-derive-addresses
|
||||
"used to generate multiple multiaccounts for onboarding
|
||||
NOTE: nothing is saved so you will need to use
|
||||
@@ -232,37 +164,12 @@
|
||||
:Bip39Passphrase password})
|
||||
callback))
|
||||
|
||||
(defn multiaccount-import-private-key
|
||||
[private-key callback]
|
||||
(log/debug "[native-module] multiaccount-import-private-key")
|
||||
(.multiAccountImportPrivateKey ^js (account-manager)
|
||||
(types/clj->json {:privateKey private-key})
|
||||
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 verify-database-password
|
||||
"NOTE: beware, the password has to be sha3 hashed"
|
||||
[key-uid hashed-password callback]
|
||||
(log/debug "[native-module] verify-database-password")
|
||||
(.verifyDatabasePassword ^js (account-manager) key-uid hashed-password callback))
|
||||
|
||||
(defn login-with-keycard
|
||||
[{:keys [key-uid multiaccount-data password chat-key node-config]}]
|
||||
(log/debug "[native-module] login-with-keycard")
|
||||
(clear-web-data)
|
||||
(init-keystore
|
||||
key-uid
|
||||
#(.loginWithKeycard ^js (account-manager)
|
||||
multiaccount-data
|
||||
password
|
||||
chat-key
|
||||
(types/clj->json node-config))))
|
||||
|
||||
(defn set-soft-input-mode
|
||||
[mode]
|
||||
(log/debug "[native-module] set-soft-input-mode")
|
||||
@@ -331,6 +238,11 @@
|
||||
: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]
|
||||
@@ -513,6 +425,14 @@
|
||||
(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?")
|
||||
@@ -533,6 +453,13 @@
|
||||
(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."
|
||||
@@ -643,7 +570,6 @@
|
||||
(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)))
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
(defn- get-dimensions
|
||||
[size]
|
||||
(case size
|
||||
:size-32 32
|
||||
:size-24 24
|
||||
:size-20 20
|
||||
nil))
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
(ns quo.components.avatars.token-avatar.view
|
||||
(:require [quo.components.avatars.token-avatar.style :as style]
|
||||
[quo.components.utilities.token.view :as token]
|
||||
[react-native.core :as rn]
|
||||
[react-native.hole-view :as hole-view]
|
||||
[react-native.platform :as platform]
|
||||
@@ -12,13 +13,14 @@
|
||||
[:map {:closed true}
|
||||
[:type {:optional true} [:enum :asset :collectible]]
|
||||
[:context? {:optional true} [:maybe :boolean]]
|
||||
[:image :schema.common/image-source]
|
||||
[:image {:optional true} [:maybe :schema.common/image-source]]
|
||||
[:token {:optional true} [:maybe [:or :keyword :string]]]
|
||||
[:network-image {:optional true} [:maybe :schema.common/image-source]]
|
||||
[:container-style {:optional true} [:maybe :map]]]]]
|
||||
:any])
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [type context? image network-image container-style]}]
|
||||
[{:keys [type context? image token network-image container-style]}]
|
||||
[rn/view
|
||||
{:style (merge style/container container-style)
|
||||
:accessibility-label :token-avatar}
|
||||
@@ -32,9 +34,11 @@
|
||||
[])
|
||||
:style style/hole-view}
|
||||
platform/android? (assoc :key context?))
|
||||
[rn/image
|
||||
{:source image
|
||||
:style (style/image type)}]]
|
||||
[token/view
|
||||
{:size :size-32
|
||||
:token token
|
||||
:style (style/image type)
|
||||
:image-source image}]]
|
||||
(when context?
|
||||
[rn/image
|
||||
{:source network-image
|
||||
|
||||
@@ -21,15 +21,17 @@
|
||||
(colors/theme-colors colors/white colors/neutral-95 theme))})
|
||||
|
||||
(defn buttons-container
|
||||
[actions]
|
||||
{:flex-direction (if (= actions :two-vertical-actions) :column :row)
|
||||
:justify-content :space-around
|
||||
:padding-vertical 12
|
||||
:gap 12
|
||||
:padding-horizontal 20})
|
||||
[actions container-style]
|
||||
(merge
|
||||
{:flex-direction (if (= actions :two-vertical-actions) :column :row)
|
||||
:justify-content :space-around
|
||||
:padding-vertical 12
|
||||
:gap 12
|
||||
:padding-horizontal 20}
|
||||
container-style))
|
||||
|
||||
(def button-container
|
||||
{:flex 1})
|
||||
{:flex-grow 1})
|
||||
|
||||
(def description-top
|
||||
{:flex-direction :row
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
[:button-two-props {:optional true} [:maybe :map]]
|
||||
[:scroll? {:optional true} [:maybe :boolean]]
|
||||
[:blur? {:optional true} [:maybe :boolean]]
|
||||
[:container-style {:optional true} [:maybe :map]]]]]
|
||||
[:container-style {:optional true} [:maybe :map]]
|
||||
[:buttons-container-style {:optional true} [:maybe :map]]]]]
|
||||
:any])
|
||||
|
||||
(def ^:private role-icon
|
||||
@@ -42,7 +43,7 @@
|
||||
(defn- view-internal
|
||||
[{:keys [actions description description-text description-top-text error-message role button-one-label
|
||||
button-two-label blur? button-one-props button-two-props scroll? container-style
|
||||
context-tag-props]}]
|
||||
buttons-container-style context-tag-props]}]
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
[rn/view
|
||||
{:style (merge (style/container scroll? blur? theme) container-style)}
|
||||
@@ -72,14 +73,14 @@
|
||||
:context (i18n/label (keyword "t" role))}
|
||||
context-tag-props)]])
|
||||
|
||||
[rn/view {:style (style/buttons-container actions)}
|
||||
[rn/view {:style (style/buttons-container actions buttons-container-style)}
|
||||
(when (or (= actions :two-actions)
|
||||
(= actions :two-vertical-actions))
|
||||
[button/button
|
||||
(merge
|
||||
{:size 40
|
||||
:background (when (or blur? scroll?) :blur)
|
||||
:container-style style/button-container
|
||||
:background (when (or blur? scroll?) :blur)
|
||||
:theme theme
|
||||
:accessibility-label :button-two}
|
||||
button-two-props)
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
(ns quo.components.list-items.approval-info.component-spec
|
||||
(:require [quo.components.list-items.approval-info.view :as approval-info]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(h/describe "List Items: Approval Info"
|
||||
(h/test "should render correctly with basic props"
|
||||
(h/render-with-theme-provider
|
||||
[approval-info/view
|
||||
{:type :spending-cap
|
||||
:label "Spending Cap"
|
||||
:avatar-props {:image "image"}}])
|
||||
(h/is-truthy (h/get-by-label-text :approval-info)))
|
||||
|
||||
(h/test "should render correctly with label & description"
|
||||
(h/render-with-theme-provider
|
||||
[approval-info/view
|
||||
{:type :spending-cap
|
||||
:label "Spending Cap"
|
||||
:description "Description"
|
||||
:avatar-props {:image "image"}}])
|
||||
(h/is-truthy (h/get-by-text "Spending Cap"))
|
||||
(h/is-truthy (h/get-by-text "Description")))
|
||||
|
||||
(h/test "on-button-press event is called when button is pressed"
|
||||
(let [on-button-press (h/mock-fn)]
|
||||
(h/render-with-theme-provider
|
||||
[approval-info/view
|
||||
{:type :spending-cap
|
||||
:label "Spending Cap"
|
||||
:button-label "Edit"
|
||||
:button-icon :i/options
|
||||
:on-button-press on-button-press
|
||||
:avatar-props {:image "image"}}])
|
||||
(h/fire-event :press (h/get-by-text "Edit"))
|
||||
(h/was-called on-button-press)))
|
||||
|
||||
(h/test "on-option-press event is called when option icon is pressed"
|
||||
(let [on-option-press (h/mock-fn)]
|
||||
(h/render-with-theme-provider
|
||||
[approval-info/view
|
||||
{:type :spending-cap
|
||||
:label "Spending Cap"
|
||||
:option-icon :i/options
|
||||
:on-option-press on-option-press
|
||||
:avatar-props {:image "image"}}])
|
||||
(h/fire-event :press (h/get-by-label-text :icon))
|
||||
(h/was-called on-option-press)))
|
||||
|
||||
(h/test "on-avatar-press event is called when avatar is pressed"
|
||||
(let [on-avatar-press (h/mock-fn)]
|
||||
(h/render-with-theme-provider
|
||||
[approval-info/view
|
||||
{:type :spending-cap
|
||||
:label "Spending Cap"
|
||||
:on-avatar-press on-avatar-press
|
||||
:avatar-props {:image "image"}}])
|
||||
(h/fire-event :press (h/get-by-label-text :token-avatar))
|
||||
(h/was-called on-avatar-press))))
|
||||
@@ -0,0 +1,36 @@
|
||||
(ns quo.components.list-items.approval-info.style
|
||||
(:require [quo.foundations.colors :as colors]))
|
||||
|
||||
(defn icon-description-color
|
||||
[blur? theme]
|
||||
(if blur?
|
||||
colors/white-opa-40
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
|
||||
|
||||
(defn container
|
||||
[description? blur? theme]
|
||||
{:flex-direction :row
|
||||
:padding-horizontal 12
|
||||
:padding-vertical (if description? 8 12)
|
||||
:border-radius 16
|
||||
:gap 8
|
||||
:align-items :center
|
||||
:border-width 1
|
||||
:border-color (if blur?
|
||||
colors/white-opa-5
|
||||
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))})
|
||||
|
||||
(def labels
|
||||
{:flex 1
|
||||
:justify-content :center
|
||||
:padding-right 4})
|
||||
|
||||
(defn label
|
||||
[blur? theme]
|
||||
{:color (if blur?
|
||||
colors/white
|
||||
(colors/theme-colors colors/neutral-100 colors/white theme))})
|
||||
|
||||
(defn description
|
||||
[blur? theme]
|
||||
{:color (icon-description-color blur? theme)})
|
||||
@@ -0,0 +1,124 @@
|
||||
(ns quo.components.list-items.approval-info.view
|
||||
(:require [clojure.string :as string]
|
||||
[quo.components.avatars.account-avatar.view :as account-avatar]
|
||||
[quo.components.avatars.collection-avatar.view :as collection-avatar]
|
||||
[quo.components.avatars.community-avatar.view :as community-avatar]
|
||||
[quo.components.avatars.dapp-avatar.view :as dapp-avatar]
|
||||
[quo.components.avatars.icon-avatar :as icon-avatar]
|
||||
[quo.components.avatars.token-avatar.view :as token-avatar]
|
||||
[quo.components.avatars.wallet-user-avatar.view :as wallet-user-avatar]
|
||||
[quo.components.buttons.button.view :as button]
|
||||
[quo.components.icon :as icon]
|
||||
[quo.components.list-items.approval-info.style :as style]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.tags.tiny-tag.view :as tiny-tag]
|
||||
[quo.foundations.colors :as colors]
|
||||
quo.theme
|
||||
[react-native.core :as rn]
|
||||
[schema.core :as schema]))
|
||||
|
||||
(def ?schema
|
||||
[:=>
|
||||
[:catn
|
||||
[:props
|
||||
[:map {:closed true}
|
||||
[:type
|
||||
[:enum :spending-cap :token-contract :account :spending-contract :network :date-signed
|
||||
:collectible :address :community :collectible-contract]]
|
||||
[:avatar-props :map]
|
||||
[:label :string]
|
||||
[:description {:optional true} [:maybe :string]]
|
||||
[:button-label {:optional true} [:maybe :string]]
|
||||
[:button-icon {:optional true} [:maybe :keyword]]
|
||||
[:blur? {:optional true} [:maybe :boolean]]
|
||||
[:unlimited-icon? {:optional true} [:maybe :boolean]]
|
||||
[:option-icon {:optional true} [:maybe :keyword]]
|
||||
[:tag-label {:optional true} [:maybe :string]]
|
||||
[:on-button-press {:optional true} [:maybe fn?]]
|
||||
[:on-avatar-press {:optional true} [:maybe fn?]]
|
||||
[:on-option-press {:optional true} [:maybe fn?]]
|
||||
[:container-style {:optional true} [:maybe :any]]]]]
|
||||
:any])
|
||||
|
||||
(defn- avatar
|
||||
[{:keys [type avatar-props blur? theme on-press]}]
|
||||
[rn/pressable {:on-press on-press}
|
||||
(case type
|
||||
:account [account-avatar/view (assoc avatar-props :size 32)]
|
||||
:collectible-contract [collection-avatar/view (assoc avatar-props :size :size-32)]
|
||||
:spending-contract [dapp-avatar/view avatar-props]
|
||||
:date-signed [icon-avatar/icon-avatar
|
||||
(assoc avatar-props
|
||||
:size :size-32
|
||||
:opacity 10
|
||||
:color (if blur?
|
||||
colors/white
|
||||
(colors/theme-colors colors/neutral-50
|
||||
colors/neutral-40
|
||||
theme)))]
|
||||
:address [wallet-user-avatar/wallet-user-avatar
|
||||
(assoc avatar-props
|
||||
:size :size-32
|
||||
:monospace? true
|
||||
:lowercase? true
|
||||
:neutral? true)]
|
||||
:community [community-avatar/view avatar-props]
|
||||
[token-avatar/view
|
||||
(assoc avatar-props
|
||||
:type
|
||||
(if (= type :collectible) :collectible :asset))])])
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [type avatar-props label description blur? unlimited-icon? container-style
|
||||
on-option-press on-avatar-press on-button-press button-label button-icon tag-label
|
||||
option-icon]}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
description? (not (string/blank? description))]
|
||||
[rn/view
|
||||
{:style (merge (style/container description? blur? theme) container-style)
|
||||
:accessibility-label :approval-info}
|
||||
[avatar
|
||||
{:type type
|
||||
:blur? blur?
|
||||
:theme theme
|
||||
:on-press on-avatar-press
|
||||
:avatar-props avatar-props}]
|
||||
[rn/view
|
||||
{:style style/labels}
|
||||
[rn/view
|
||||
{:style {:flex-direction :row :align-items :center}}
|
||||
[text/text
|
||||
{:size :paragraph-1
|
||||
:weight (if (= type :address) :monospace :semi-bold)
|
||||
:style (style/label blur? theme)}
|
||||
label]
|
||||
(when unlimited-icon?
|
||||
[icon/icon :i/alert
|
||||
{:container-style {:margin-left 4}
|
||||
:size 16
|
||||
:color (style/icon-description-color blur? theme)}])]
|
||||
(when description?
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight (if (contains? #{:collectible-contract :spending-contract :account :token-contract}
|
||||
type)
|
||||
:monospace
|
||||
:regular)
|
||||
:style (style/description blur? theme)}
|
||||
description])]
|
||||
(when (= type :account) [tiny-tag/view {:label tag-label}])
|
||||
(when (and (= type :spending-cap) button-icon)
|
||||
[button/button
|
||||
{:type :outline
|
||||
:size 24
|
||||
:blur? blur?
|
||||
:icon-left button-icon
|
||||
:on-press on-button-press}
|
||||
button-label])
|
||||
(when option-icon
|
||||
[rn/pressable {:on-press on-option-press}
|
||||
[icon/icon option-icon
|
||||
{:color (style/icon-description-color blur? theme)
|
||||
:size 20}]])]))
|
||||
|
||||
(def view (schema/instrument #'view-internal ?schema))
|
||||
@@ -0,0 +1,43 @@
|
||||
(ns quo.components.pin-input.pin.view
|
||||
(:require [quo.foundations.colors :as colors]
|
||||
quo.theme
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn view
|
||||
[{:keys [theme state blur?]}]
|
||||
(let [app-theme (quo.theme/use-theme)
|
||||
theme (or theme app-theme)]
|
||||
[rn/view {:style {:width 36 :height 36 :align-items :center :justify-content :center}}
|
||||
(case state
|
||||
:active
|
||||
[rn/view
|
||||
{:style {:width 16
|
||||
:height 16
|
||||
:border-radius 8
|
||||
:background-color (if blur?
|
||||
colors/white-opa-20
|
||||
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme))}}]
|
||||
:filled
|
||||
[rn/view
|
||||
{:style {:width 16
|
||||
:height 16
|
||||
:border-radius 8
|
||||
:background-color (if blur?
|
||||
colors/white
|
||||
(colors/theme-colors colors/neutral-100 colors/white theme))}}]
|
||||
:error
|
||||
[rn/view
|
||||
{:style {:width 16
|
||||
:height 16
|
||||
:border-radius 8
|
||||
:background-color (if blur?
|
||||
colors/danger-60
|
||||
(colors/theme-colors colors/danger-50 colors/danger-60 theme))}}]
|
||||
[rn/view
|
||||
{:style
|
||||
{:width 12
|
||||
:height 12
|
||||
:border-radius 6
|
||||
:background-color (if blur?
|
||||
colors/white-opa-20
|
||||
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme))}}])]))
|
||||
@@ -0,0 +1,27 @@
|
||||
(ns quo.components.pin-input.view
|
||||
(:require [quo.components.markdown.text :as text]
|
||||
[quo.components.pin-input.pin.view :as pin]
|
||||
[quo.foundations.colors :as colors]
|
||||
quo.theme
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn view
|
||||
[{:keys [number-of-pins number-of-filled-pins error? info]
|
||||
:or {number-of-pins 6 number-of-filled-pins 0}}]
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
[rn/view {:style {:align-items :center}}
|
||||
[rn/view {:style {:flex-direction :row}}
|
||||
(for [i (range 1 (inc number-of-pins))]
|
||||
^{:key i}
|
||||
[pin/view
|
||||
{:state (cond
|
||||
error? :error
|
||||
(<= i number-of-filled-pins) :filled
|
||||
(= i (inc number-of-filled-pins)) :active)}])]
|
||||
(when info
|
||||
[text/text
|
||||
{:style {:color (if error?
|
||||
(colors/theme-colors colors/danger-50 colors/danger-60 theme)
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))}
|
||||
:size :paragraph-2}
|
||||
info])]))
|
||||
@@ -79,14 +79,20 @@
|
||||
[counter-view counter])
|
||||
[rn/view {:style (style/collectible-border theme)}]]]))
|
||||
|
||||
(defn invalid-image?
|
||||
[image-src]
|
||||
(or (nil? image-src)
|
||||
(string/blank? image-src)))
|
||||
|
||||
(defn view-internal
|
||||
[{:keys [container-style square? on-press counter image-src native-ID supported-file?
|
||||
on-collectible-load aspect-ratio gradient-color-index]
|
||||
:or {gradient-color-index :gradient-1
|
||||
on-collectible-load (fn [])}}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
[error? set-error] (rn/use-state (or (nil? image-src)
|
||||
(string/blank? image-src)))]
|
||||
[error? set-error] (rn/use-state (invalid-image? image-src))]
|
||||
(rn/use-effect #(set-error (invalid-image? image-src))
|
||||
[image-src])
|
||||
[rn/pressable
|
||||
{:style (merge container-style (style/container aspect-ratio))
|
||||
:accessibility-label :expanded-collectible
|
||||
|
||||
@@ -159,4 +159,19 @@
|
||||
:icon :i/placeholder
|
||||
:emoji "🎮"
|
||||
:customization-color :yellow}])
|
||||
(h/is-truthy (h/query-by-label-text :account-emoji))))
|
||||
(h/is-truthy (h/query-by-label-text :account-emoji)))
|
||||
|
||||
(h/test "edit icon is visible when subtitle type is editable"
|
||||
(h/render [quo/data-item
|
||||
{:on-press (h/mock-fn)
|
||||
:blur? false
|
||||
:card? true
|
||||
:status :default
|
||||
:size :default
|
||||
:title "Label"
|
||||
:subtitle "Subtitle"
|
||||
:subtitle-type :editable
|
||||
:icon :i/placeholder
|
||||
:emoji "🎮"
|
||||
:customization-color :yellow}])
|
||||
(h/is-truthy (h/query-by-label-text :edit-icon))))
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
|
||||
(def subtitle-container
|
||||
{:flex-direction :row
|
||||
:align-items :center
|
||||
:margin-bottom 1})
|
||||
|
||||
(def right-container
|
||||
@@ -62,7 +63,7 @@
|
||||
|
||||
(defn subtitle-icon-container
|
||||
[subtitle-type]
|
||||
{:margin-right (when (not= :default subtitle-type) 4)
|
||||
{:margin-right (when-not (contains? #{:editable :default} subtitle-type) 4)
|
||||
:justify-content :center})
|
||||
|
||||
(defn title
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
[quo.components.settings.data-item.style :as style]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]))
|
||||
[react-native.core :as rn]
|
||||
[schema.core :as schema]))
|
||||
|
||||
(defn- left-loading
|
||||
[{:keys [size blur?]}]
|
||||
@@ -40,7 +41,17 @@
|
||||
{:weight :medium
|
||||
:size :paragraph-2
|
||||
:style (style/description blur? theme)}
|
||||
subtitle]]))
|
||||
subtitle]
|
||||
(when (= subtitle-type :editable)
|
||||
[icons/icon :i/edit
|
||||
{:accessibility-label :edit-icon
|
||||
:size 12
|
||||
:container-style {:margin-left 2}
|
||||
:color (if blur?
|
||||
colors/neutral-40
|
||||
(colors/theme-colors colors/neutral-50
|
||||
colors/neutral-40
|
||||
theme))}])]))
|
||||
|
||||
(defn- left-title
|
||||
[{:keys [title blur?]}]
|
||||
@@ -100,7 +111,32 @@
|
||||
:color icon-color
|
||||
:size 20}]])]))
|
||||
|
||||
(defn view
|
||||
|
||||
(def ?schema
|
||||
[:=>
|
||||
[:catn
|
||||
[:props
|
||||
[:map {:closed true}
|
||||
[:blur? {:optional true} [:maybe :boolean]]
|
||||
[:card? {:optional true} [:maybe :boolean]]
|
||||
[:right-icon {:optional true} [:maybe :keyword]]
|
||||
[:right-content {:optional true} [:maybe :map]]
|
||||
[:icon-color {:optional true} [:maybe :schema.common/customization-color]]
|
||||
[:status {:optional true} [:maybe [:enum :default :loading]]]
|
||||
[:subtitle-type {:optional true} [:maybe [:enum :default :icon :network :account :editable]]]
|
||||
[:size {:optional true} [:maybe [:enum :default :small :large]]]
|
||||
[:title :string]
|
||||
[:subtitle {:optional true} [:maybe :string]]
|
||||
[:custom-subtitle {:optional true} [:maybe fn?]]
|
||||
[:icon {:optional true} [:maybe :keyword]]
|
||||
[:emoji {:optional true} [:maybe :string]]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
|
||||
[:network-image {:optional true} [:maybe :schema.common/image-source]]
|
||||
[:on-press {:optional true} [:maybe fn?]]
|
||||
[:container-style {:optional true} [:maybe :map]]]]]
|
||||
:any])
|
||||
|
||||
(defn view-internal
|
||||
[{:keys [blur? card? right-icon right-content status size on-press container-style]
|
||||
:as props}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
@@ -123,3 +159,5 @@
|
||||
{:right-icon right-icon
|
||||
:right-content right-content
|
||||
:icon-color icon-color}])]))
|
||||
|
||||
(def view (schema/instrument #'view-internal ?schema))
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
(defn color
|
||||
[blur? theme]
|
||||
{:color (if blur?
|
||||
colors/white-opa-70
|
||||
colors/white-opa-40
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))})
|
||||
|
||||
(defn label-dot
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
(ns quo.components.slideshow.slider-bar.component-spec
|
||||
(:require
|
||||
[quo.components.slideshow.slider-bar.view :as slider-bar]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(h/describe "Slideshow: slider-bar"
|
||||
(h/test "default render"
|
||||
(h/render-with-theme-provider [slider-bar/view {:accessibility-label :slider-bar}])
|
||||
(h/is-truthy (h/query-by-label-text :slider-bar)))
|
||||
|
||||
(h/test "render with total-amount and active-index"
|
||||
(h/render-with-theme-provider [slider-bar/view
|
||||
{:total-amount 4
|
||||
:active-index 1
|
||||
:accessibility-label :slider-bar}])
|
||||
(h/is-truthy (h/query-by-label-text :slider-bar))
|
||||
(h/is-equal 4 (count (h/query-all-by-label-text :slide-bar-item))))
|
||||
|
||||
(h/test "render with total-amount active-index and possible scroll"
|
||||
(h/render-with-theme-provider [slider-bar/view
|
||||
{:total-amount 10
|
||||
:active-index 7
|
||||
:accessibility-label :slider-bar}])
|
||||
(h/is-truthy (h/query-by-label-text :slider-bar))
|
||||
(h/is-equal 10 (count (h/query-all-by-label-text :slide-bar-item)))))
|
||||
@@ -0,0 +1,14 @@
|
||||
(ns quo.components.slideshow.slider-bar.schema)
|
||||
|
||||
(def ?schema
|
||||
[:=>
|
||||
[:cat
|
||||
[:map {:closed true}
|
||||
[:total-amount {:optional true} [:maybe :int]]
|
||||
[:active-index {:optional true} :int]
|
||||
[:customization-color {:optional true}
|
||||
[:maybe :schema.common/customization-color]]
|
||||
[:blur? {:optional true} [:maybe :boolean]]
|
||||
[:accessibility-label {:optional true} [:maybe :keyword]]
|
||||
[:container-style {:optional true} [:maybe :map]]]]
|
||||
:any])
|
||||
@@ -0,0 +1,31 @@
|
||||
(ns quo.components.slideshow.slider-bar.style
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]))
|
||||
|
||||
(def list-wrapper
|
||||
{:align-items :center})
|
||||
|
||||
(defn list-bar
|
||||
[bar-width]
|
||||
{:width bar-width})
|
||||
|
||||
(defn item-wrapper
|
||||
[{:keys [size spacing]}]
|
||||
{:width size
|
||||
:height size
|
||||
:margin-left spacing
|
||||
:flex 1
|
||||
:align-items :center
|
||||
:justify-content :center})
|
||||
|
||||
(defn item
|
||||
[{:keys [size spacing active? customization-color theme blur?]}]
|
||||
{:width size
|
||||
:height size
|
||||
:border-radius spacing
|
||||
:background-color
|
||||
(cond
|
||||
(and blur? active?) colors/white
|
||||
(and blur? (not active?)) colors/white-opa-10
|
||||
(and (not blur?) active?) (colors/resolve-color customization-color theme)
|
||||
:else (colors/theme-colors colors/neutral-20 colors/neutral-80 theme))})
|
||||
@@ -0,0 +1,150 @@
|
||||
(ns quo.components.slideshow.slider-bar.view
|
||||
(:require
|
||||
[quo.components.slideshow.slider-bar.schema :as component-schema]
|
||||
[quo.components.slideshow.slider-bar.style :as style]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[schema.core :as schema]))
|
||||
|
||||
(def item-size 8)
|
||||
(def item-spacing item-size)
|
||||
(def max-length 6)
|
||||
(def bar-width (* (+ item-spacing item-size) max-length))
|
||||
|
||||
(def micro-scale 0.25)
|
||||
(def small-scale 0.5)
|
||||
(def medium-scale 0.75)
|
||||
(def default-scale 1)
|
||||
|
||||
(def items-before-scroll
|
||||
(/ max-length 2))
|
||||
|
||||
(defn- calc-relative-index
|
||||
"Calculates item index in visible area"
|
||||
[index active-index total-length]
|
||||
(let [last-index (dec total-length)]
|
||||
(cond
|
||||
(< active-index items-before-scroll) index
|
||||
(> active-index
|
||||
(- last-index items-before-scroll)) (+ (- index total-length) max-length)
|
||||
:else (+ (- index active-index) items-before-scroll))))
|
||||
|
||||
(defn- calc-first-item-scale
|
||||
"Calculates scale for first item in visible area"
|
||||
[active-index]
|
||||
(cond
|
||||
(= active-index items-before-scroll) medium-scale
|
||||
(> active-index items-before-scroll) small-scale
|
||||
:else default-scale))
|
||||
|
||||
(defn- calc-second-item-scale
|
||||
"Calculates scale for second item in visible area"
|
||||
[active-index]
|
||||
(if (> active-index items-before-scroll)
|
||||
medium-scale
|
||||
default-scale))
|
||||
|
||||
(defn- calc-last-item-scale
|
||||
"Calculates scale for last item in visible area"
|
||||
[active-index total-length]
|
||||
(let [last-index (dec total-length)]
|
||||
(if (> active-index (- last-index items-before-scroll))
|
||||
medium-scale
|
||||
small-scale)))
|
||||
|
||||
(defn- calc-last-but-one-item-scale
|
||||
"Calculates scale for before last item in visible area"
|
||||
[active-index total-length]
|
||||
(if (> active-index (- (dec total-length) items-before-scroll))
|
||||
default-scale
|
||||
medium-scale))
|
||||
|
||||
(defn- get-scale
|
||||
[index active-index total-length]
|
||||
(let [relative-index (calc-relative-index index active-index total-length)]
|
||||
(if (or (= index active-index)
|
||||
(< total-length max-length))
|
||||
default-scale
|
||||
(cond
|
||||
(< relative-index 0) micro-scale
|
||||
(= relative-index 0) (calc-first-item-scale active-index)
|
||||
(= relative-index 1) (calc-second-item-scale active-index)
|
||||
(= relative-index 4) (calc-last-but-one-item-scale active-index total-length)
|
||||
(= relative-index 5) (calc-last-item-scale active-index total-length)
|
||||
(> relative-index 5) micro-scale
|
||||
:else
|
||||
default-scale))))
|
||||
|
||||
(defn- bar-item
|
||||
[index _ _ {:keys [active-index total-length customization-color theme blur?]}]
|
||||
(let [active? (= index active-index)
|
||||
shared-scale (reanimated/use-shared-value (get-scale index active-index total-length))]
|
||||
(rn/use-effect (fn []
|
||||
(let [new-scale-value (get-scale index active-index total-length)]
|
||||
(reanimated/animate shared-scale new-scale-value)))
|
||||
[index active-index total-length])
|
||||
[rn/view
|
||||
{:key index
|
||||
:style (style/item-wrapper {:size item-size
|
||||
:spacing item-spacing})}
|
||||
[reanimated/view
|
||||
{:accessibility-label :slide-bar-item
|
||||
:style
|
||||
(reanimated/apply-animations-to-style
|
||||
{:transform [{:scale shared-scale}]}
|
||||
(style/item {:size item-size
|
||||
:spacing item-spacing
|
||||
:active? active?
|
||||
:customization-color customization-color
|
||||
:theme theme
|
||||
:blur? blur?}))}]]))
|
||||
|
||||
(defn- get-item-layout
|
||||
[_ index]
|
||||
(let [length (+ item-size item-spacing)]
|
||||
#js {:length length
|
||||
:index index
|
||||
:offset (* index length)}))
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [customization-color blur? accessibility-label container-style]
|
||||
:as props}]
|
||||
(let [active-index (or (:active-index props) 0)
|
||||
total-amount (or (:total-amount props) 1)
|
||||
theme (quo.theme/use-theme)
|
||||
flat-list-ref (rn/use-ref-atom nil)
|
||||
set-flat-list-ref (rn/use-callback #(reset! flat-list-ref %))
|
||||
center-position 0.5
|
||||
data (range total-amount)
|
||||
scroll-to-index (rn/use-callback
|
||||
(fn []
|
||||
(some-> ^js @flat-list-ref
|
||||
(.scrollToIndex #js {:animated true
|
||||
:index active-index
|
||||
:viewOffset item-spacing
|
||||
:viewPosition center-position})))
|
||||
[flat-list-ref active-index])]
|
||||
(rn/use-effect scroll-to-index [active-index])
|
||||
[rn/view
|
||||
{:style (merge style/list-wrapper container-style)
|
||||
:accessibility-label accessibility-label}
|
||||
[reanimated/flat-list
|
||||
{:style (style/list-bar bar-width)
|
||||
:data data
|
||||
:scroll-enabled false
|
||||
:ref set-flat-list-ref
|
||||
:shows-horizontal-scroll-indicator false
|
||||
:bounces false
|
||||
:horizontal true
|
||||
:extra-data (str active-index)
|
||||
:render-data {:active-index active-index
|
||||
:total-length total-amount
|
||||
:customization-color customization-color
|
||||
:theme theme
|
||||
:blur? blur?}
|
||||
:get-item-layout get-item-layout
|
||||
:render-fn bar-item
|
||||
:key-fn identity}]]))
|
||||
|
||||
(def view (schema/instrument #'view-internal component-schema/?schema))
|
||||
@@ -53,7 +53,7 @@
|
||||
(def ^:private ?network
|
||||
[:map
|
||||
[:network-logo {:optional true} [:maybe :schema.common/image-source]]
|
||||
[:network-name {:optional true} [:maybe :string]]])
|
||||
[:network-name {:optional true} [:maybe [:or :string :keyword]]]])
|
||||
|
||||
(def ^:private ?multinetwork
|
||||
[:map
|
||||
|
||||
@@ -41,7 +41,8 @@
|
||||
:align-items :center
|
||||
:height size
|
||||
:background-color background-color
|
||||
:border-radius border-radius}
|
||||
:border-radius border-radius
|
||||
:flex-shrink 1}
|
||||
(= state :selected) (assoc :height (+ size 2)
|
||||
:border-color border-color
|
||||
:border-width 1))))
|
||||
@@ -50,11 +51,13 @@
|
||||
[size]
|
||||
{:margin-right (if (= size 24) 6 10)
|
||||
:flex-direction :row
|
||||
:flex-shrink 1
|
||||
:align-items :center})
|
||||
|
||||
(defn tag-spacing
|
||||
[size]
|
||||
{:margin-left (if (= size 24) 4 8)})
|
||||
[size shrinkable?]
|
||||
(cond-> {:margin-left (if (= size 24) 4 8)}
|
||||
shrinkable? (assoc :flex-shrink 1)))
|
||||
|
||||
(defn text
|
||||
[theme]
|
||||
|
||||
@@ -17,17 +17,19 @@
|
||||
[schema.core :as schema]))
|
||||
|
||||
(defn- tag-skeleton
|
||||
[{:keys [size text theme]
|
||||
[{:keys [size text theme shrinkable?]
|
||||
:or {size 24
|
||||
theme (quo.theme/use-theme)}}
|
||||
logo-component]
|
||||
[rn/view {:style (style/tag-container size)}
|
||||
logo-component
|
||||
[rn/view {:style (style/tag-spacing size)}
|
||||
[rn/view {:style (style/tag-spacing size shrinkable?)}
|
||||
[text/text
|
||||
{:style (style/text theme)
|
||||
:weight :medium
|
||||
:size (if (= size 24) :paragraph-2 :paragraph-1)}
|
||||
{:style (style/text theme)
|
||||
:weight :medium
|
||||
:size (if (= size 24) :paragraph-2 :paragraph-1)
|
||||
:number-of-lines 1
|
||||
:ellipsize-mode :middle}
|
||||
text]]])
|
||||
|
||||
(defn- communities-tag
|
||||
@@ -37,7 +39,7 @@
|
||||
icon-size (if (= size 24) 16 20)]
|
||||
[rn/view {:style (style/tag-container size)}
|
||||
[fast-image/fast-image {:style (style/circle-logo size) :source community-logo}]
|
||||
[rn/view {:style (style/tag-spacing size)}
|
||||
[rn/view {:style (style/tag-spacing size false)}
|
||||
[text/text
|
||||
{:style (style/text theme)
|
||||
:weight :medium
|
||||
@@ -148,9 +150,10 @@
|
||||
|
||||
:collectible
|
||||
[tag-skeleton
|
||||
{:theme theme
|
||||
:size size
|
||||
:text (str collectible-name " #" collectible-number)}
|
||||
{:theme theme
|
||||
:size size
|
||||
:text (str collectible-name " #" collectible-number)
|
||||
:shrinkable? true}
|
||||
[rn/image {:style (style/rounded-logo size) :source collectible}]]
|
||||
|
||||
:account
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
|
||||
(defn main
|
||||
[{:keys [type customization-color]} theme]
|
||||
{:justify-content :center
|
||||
:align-items :center
|
||||
{:align-items :center
|
||||
:height 32
|
||||
:padding-left 4
|
||||
:padding-right 10
|
||||
|
||||
@@ -67,7 +67,9 @@
|
||||
:style (style/main (assoc props :customization-color customization-color) theme)}
|
||||
[left-view props]
|
||||
[text/text
|
||||
{:style (style/label type theme)
|
||||
:weight :semi-bold
|
||||
:size :heading-1}
|
||||
{:style (style/label type theme)
|
||||
:weight :semi-bold
|
||||
:ellipsize-mode :tail
|
||||
:number-of-lines 1
|
||||
:size :heading-1}
|
||||
label]]))
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
[:catn
|
||||
[:props
|
||||
[:map
|
||||
[:type [:enum :status-account :saved-account :account :user]]
|
||||
[:type [:enum :status-account :saved-account :account :user :token]]
|
||||
[:account-props {:optional true} [:maybe :map]]
|
||||
[:token-props {:optional true} [:maybe :map]]
|
||||
[:networks? {:optional true} [:maybe :boolean]]
|
||||
[:values {:optional true} [:maybe :map]]]]]
|
||||
:any])
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
[quo.components.avatars.user-avatar.view :as user-avatar]
|
||||
[quo.components.avatars.wallet-user-avatar.view :as wallet-user-avatar]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.utilities.token.view :as token]
|
||||
[quo.components.wallet.summary-info.schema :as summary-info-schema]
|
||||
[quo.components.wallet.summary-info.style :as style]
|
||||
[quo.foundations.colors :as colors]
|
||||
@@ -58,13 +59,14 @@
|
||||
:theme theme}])]))
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [type account-props networks? values]}]
|
||||
[{:keys [type account-props token-props networks? values]}]
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
[rn/view
|
||||
{:style (style/container networks? theme)}
|
||||
[rn/view
|
||||
{:style style/info-container}
|
||||
(case type
|
||||
:token [token/view (select-keys token-props #{:token :size})]
|
||||
:status-account [account-avatar/view account-props]
|
||||
:saved-account [wallet-user-avatar/wallet-user-avatar (assoc account-props :size :size-32)]
|
||||
:account [wallet-user-avatar/wallet-user-avatar
|
||||
@@ -73,7 +75,8 @@
|
||||
:neutral? true)]
|
||||
[user-avatar/user-avatar account-props])
|
||||
[rn/view {:style {:margin-left 8}}
|
||||
(when (not= type :account) [text/text {:weight :semi-bold} (:name account-props)])
|
||||
(when (not= type :account)
|
||||
[text/text {:weight :semi-bold} (or (:name account-props) (:label token-props))])
|
||||
[rn/view
|
||||
{:style {:flex-direction :row
|
||||
:align-items :center}}
|
||||
@@ -91,7 +94,7 @@
|
||||
:weight (when (= type :account) :semi-bold)
|
||||
:style {:color (when (not= type :account)
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))}}
|
||||
(:address account-props)]]]]
|
||||
(or (:address account-props) (:address token-props))]]]]
|
||||
(when networks?
|
||||
[:<>
|
||||
[rn/view
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
(ns quo.components.wallet.swap-input.component-spec
|
||||
(:require [quo.components.wallet.swap-input.view :as swap-input]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(h/describe "Wallet: Swap Input"
|
||||
(h/test "should render correctly with props"
|
||||
(h/render-with-theme-provider
|
||||
[swap-input/view
|
||||
{:type :pay
|
||||
:error? false
|
||||
:token "SNT"
|
||||
:status :default
|
||||
:currency-symbol "€"
|
||||
:value "5"
|
||||
:fiat-value "1.50"
|
||||
:network-tag-props {:title "Max: 200 SNT"}}])
|
||||
(h/is-truthy (h/get-by-label-text :swap-input))
|
||||
(h/is-truthy (h/get-by-text "SNT"))
|
||||
(h/is-truthy (h/get-by-text "€1.50"))
|
||||
(h/is-truthy (h/get-by-text "Max: 200 SNT")))
|
||||
|
||||
(h/test "should render correctly with approval label"
|
||||
(h/render-with-theme-provider
|
||||
[swap-input/view
|
||||
{:type :pay
|
||||
:show-approval-label? true
|
||||
:approval-label-props
|
||||
{:status :approve
|
||||
:token-value "10"
|
||||
:token-symbol "SNT"}}])
|
||||
(h/is-truthy (h/get-by-text "Approve 10 SNT"))))
|
||||
@@ -0,0 +1,74 @@
|
||||
(ns quo.components.wallet.swap-input.style
|
||||
(:require [quo.foundations.colors :as colors]
|
||||
[quo.foundations.typography :as typography]))
|
||||
|
||||
(defn- border-color
|
||||
[theme]
|
||||
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))
|
||||
|
||||
(defn- loader-color
|
||||
[theme]
|
||||
(colors/theme-colors colors/neutral-5 colors/neutral-90 theme))
|
||||
|
||||
(defn content
|
||||
[theme]
|
||||
{:border-width 1
|
||||
:border-radius 16
|
||||
:border-color (border-color theme)
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-95 theme)})
|
||||
|
||||
(defn row-1
|
||||
[loading?]
|
||||
{:padding 12
|
||||
:gap 8
|
||||
:align-items (if loading? :center :flex-end)
|
||||
:flex-direction :row})
|
||||
|
||||
(defn row-1-loader
|
||||
[theme]
|
||||
{:width 74
|
||||
:height 14
|
||||
:border-radius 6
|
||||
:background-color (loader-color theme)})
|
||||
|
||||
(def input-container
|
||||
{:flex 1
|
||||
:flex-direction :row
|
||||
:gap 5
|
||||
:height 32
|
||||
:align-items :flex-end})
|
||||
|
||||
(defn input
|
||||
[disabled? error? theme]
|
||||
(assoc typography/font-semi-bold
|
||||
:font-size 27
|
||||
:flex-shrink 1
|
||||
:padding 0
|
||||
:color (cond
|
||||
error? (colors/resolve-color :danger theme)
|
||||
disabled? (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:else (colors/theme-colors colors/neutral-100 colors/white theme))
|
||||
:line-height 32))
|
||||
|
||||
(defn token-symbol
|
||||
[theme]
|
||||
{:padding-bottom 3
|
||||
:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)})
|
||||
|
||||
(defn row-2
|
||||
[align-right?]
|
||||
{:flex-direction :row
|
||||
:justify-content (if align-right? :flex-end :space-between)
|
||||
:align-items :center
|
||||
:padding 12})
|
||||
|
||||
(defn row-2-loader
|
||||
[theme]
|
||||
{:width 80
|
||||
:height 10
|
||||
:margin-vertical 7
|
||||
:border-radius 6
|
||||
:background-color (loader-color theme)})
|
||||
|
||||
(def fiat-amount
|
||||
{:color colors/neutral-50})
|
||||
@@ -0,0 +1,121 @@
|
||||
(ns quo.components.wallet.swap-input.view
|
||||
(:require [oops.core :as oops]
|
||||
[quo.components.avatars.token-avatar.view :as token-avatar]
|
||||
[quo.components.buttons.button.view :as buttons]
|
||||
[quo.components.dividers.divider-line.view :as divider-line]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.tags.network-tags.view :as network-tag]
|
||||
[quo.components.wallet.approval-label.schema :as approval-label.schema]
|
||||
[quo.components.wallet.approval-label.view :as approval-label]
|
||||
[quo.components.wallet.swap-input.style :as style]
|
||||
[quo.foundations.colors :as colors]
|
||||
quo.theme
|
||||
[react-native.core :as rn]
|
||||
[schema.core :as schema]))
|
||||
|
||||
(def ?schema
|
||||
[:=>
|
||||
[:catn
|
||||
[:props
|
||||
[:map {:closed true}
|
||||
[:type {:optional true} [:maybe [:enum :pay :receive]]]
|
||||
[:status {:optional true} [:maybe [:enum :default :disabled :loading]]]
|
||||
[:token {:optional true} [:maybe :string]]
|
||||
[:value {:optional true} [:maybe :string]]
|
||||
[:default-value {:optional true} [:maybe :string]]
|
||||
[:currency-symbol {:optional true} [:maybe :string]]
|
||||
[:fiat-value {:optional true} [:maybe :string]]
|
||||
[:show-approval-label? {:optional true} [:maybe :boolean]]
|
||||
[:error? {:optional true} [:maybe :boolean]]
|
||||
[:show-keyboard? {:optional true} [:maybe :boolean]]
|
||||
[:approval-label-props {:optional true} [:maybe approval-label.schema/?schema]]
|
||||
[:network-tag-props {:optional true} [:maybe :map]]
|
||||
[:on-change-text {:optional true} [:maybe fn?]]
|
||||
[:enable-swap? {:optional true} [:maybe :boolean]]
|
||||
[:on-swap-press {:optional true} [:maybe fn?]]
|
||||
[:on-token-press {:optional true} [:maybe fn?]]
|
||||
[:on-max-press {:optional true} [:maybe fn?]]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
|
||||
[:container-style {:optional true} [:maybe :map]]]]]
|
||||
:any])
|
||||
|
||||
(defn view-internal
|
||||
[{:keys [type status token value fiat-value show-approval-label? error? network-tag-props
|
||||
approval-label-props default-value enable-swap?
|
||||
currency-symbol on-change-text show-keyboard?
|
||||
container-style on-swap-press on-token-press on-max-press]}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
pay? (= type :pay)
|
||||
disabled? (= status :disabled)
|
||||
loading? (= status :loading)
|
||||
controlled-input? (some? value)
|
||||
input-ref (rn/use-ref-atom nil)
|
||||
set-input-ref (rn/use-callback (fn [ref] (reset! input-ref ref)) [])
|
||||
focus-input (rn/use-callback (fn []
|
||||
(some-> @input-ref
|
||||
(oops/ocall "focus")))
|
||||
[input-ref])]
|
||||
[rn/view
|
||||
{:style container-style
|
||||
:accessibility-label :swap-input}
|
||||
[rn/view {:style (style/content theme)}
|
||||
[rn/view
|
||||
{:style (style/row-1 loading?)}
|
||||
[rn/pressable {:on-press on-token-press}
|
||||
[token-avatar/view
|
||||
{:type :asset
|
||||
:token token}]]
|
||||
(if loading?
|
||||
[rn/view {:style (style/row-1-loader theme)}]
|
||||
[:<>
|
||||
[rn/pressable
|
||||
{:style style/input-container
|
||||
:on-press focus-input}
|
||||
[rn/text-input
|
||||
(cond-> {:ref set-input-ref
|
||||
:style (style/input disabled? error? theme)
|
||||
:placeholder-text-color (colors/theme-colors colors/neutral-40
|
||||
colors/neutral-50
|
||||
theme)
|
||||
:keyboard-type :numeric
|
||||
:auto-focus true
|
||||
:on-change-text on-change-text
|
||||
:show-soft-input-on-focus show-keyboard?
|
||||
:default-value default-value
|
||||
:placeholder "0"}
|
||||
controlled-input? (assoc :value value))]
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :semi-bold
|
||||
:style (style/token-symbol theme)}
|
||||
token]]
|
||||
(when (and pay? enable-swap?)
|
||||
[buttons/button
|
||||
{:type :outline
|
||||
:size 32
|
||||
:on-press on-swap-press
|
||||
:icon-only? true}
|
||||
:i/reorder])])]
|
||||
[divider-line/view]
|
||||
[rn/view
|
||||
{:style (style/row-2 (or (not pay?) loading?))}
|
||||
(when-not loading?
|
||||
[:<>
|
||||
(when pay?
|
||||
[rn/pressable {:on-press on-max-press}
|
||||
[network-tag/view
|
||||
(assoc network-tag-props
|
||||
:status
|
||||
(if error? :error :default))]])
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:style style/fiat-amount
|
||||
:weight :medium}
|
||||
(str currency-symbol fiat-value)]])
|
||||
(when loading?
|
||||
[rn/view {:style (style/row-2-loader theme)}])]]
|
||||
(when (and (not= status :loading) (= type :pay) show-approval-label?)
|
||||
[approval-label/view
|
||||
approval-label-props])]))
|
||||
|
||||
(def view (schema/instrument #'view-internal ?schema))
|
||||
@@ -51,8 +51,7 @@
|
||||
|
||||
(defn prop-text
|
||||
[theme]
|
||||
{:margin-right 4
|
||||
:color (colors/theme-colors colors/neutral-100 colors/white theme)})
|
||||
{:color (colors/theme-colors colors/neutral-100 colors/white theme)})
|
||||
|
||||
(def icon-container
|
||||
{:width 32
|
||||
@@ -61,12 +60,15 @@
|
||||
|
||||
(def container
|
||||
{:flex-direction :row
|
||||
:flex 1
|
||||
:column-gap 8})
|
||||
|
||||
(def content-line
|
||||
{:flex-direction :row
|
||||
:margin-top 2
|
||||
:align-items :center})
|
||||
{:flex-direction :row
|
||||
:margin-top 2
|
||||
:align-items :center
|
||||
:column-gap 4
|
||||
:justify-content :flex-start})
|
||||
|
||||
(def icon-hole-view
|
||||
{:width 32
|
||||
|
||||
@@ -98,8 +98,11 @@
|
||||
|
||||
(defn prop-tag
|
||||
[props blur?]
|
||||
[rn/view {:style {:margin-right 4}}
|
||||
[context-tag/view (merge props {:size 24 :blur? blur?})]])
|
||||
[context-tag/view
|
||||
(assoc props
|
||||
:size 24
|
||||
:blur? blur?
|
||||
:container-style {:flex-shrink 1})])
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [state blur? first-tag second-tag third-tag fourth-tag on-press
|
||||
@@ -121,7 +124,7 @@
|
||||
:on-press-out on-press-out}
|
||||
[rn/view {:style style/container}
|
||||
[transaction-icon-view props theme]
|
||||
[rn/view
|
||||
[rn/view {:style {:flex 1}}
|
||||
[transaction-header props theme]
|
||||
[rn/view {:style style/content-line}
|
||||
(when first-tag [prop-tag first-tag blur?])
|
||||
|
||||
@@ -86,6 +86,7 @@
|
||||
quo.components.list-items.account-list-card.view
|
||||
quo.components.list-items.account.view
|
||||
quo.components.list-items.address.view
|
||||
quo.components.list-items.approval-info.view
|
||||
quo.components.list-items.channel.view
|
||||
quo.components.list-items.community.view
|
||||
quo.components.list-items.dapp.view
|
||||
@@ -120,6 +121,7 @@
|
||||
quo.components.overlay.view
|
||||
quo.components.password.password-tips.view
|
||||
quo.components.password.tips.view
|
||||
quo.components.pin-input.view
|
||||
quo.components.profile.collectible-list-item.view
|
||||
quo.components.profile.collectible.view
|
||||
quo.components.profile.expanded-collectible.view
|
||||
@@ -145,6 +147,7 @@
|
||||
quo.components.settings.settings-item.view
|
||||
quo.components.share.qr-code.view
|
||||
quo.components.share.share-qr-code.view
|
||||
quo.components.slideshow.slider-bar.view
|
||||
quo.components.switchers.group-messaging-card.view
|
||||
quo.components.tabs.account-selector
|
||||
quo.components.tabs.segmented-tab
|
||||
@@ -183,6 +186,7 @@
|
||||
quo.components.wallet.progress-bar.view
|
||||
quo.components.wallet.required-tokens.view
|
||||
quo.components.wallet.summary-info.view
|
||||
quo.components.wallet.swap-input.view
|
||||
quo.components.wallet.token-input.view
|
||||
quo.components.wallet.transaction-progress.view
|
||||
quo.components.wallet.transaction-summary.view
|
||||
@@ -320,6 +324,9 @@
|
||||
(def keyboard-key quo.components.numbered-keyboard.keyboard-key.view/view)
|
||||
(def numbered-keyboard quo.components.numbered-keyboard.numbered-keyboard.view/view)
|
||||
|
||||
;;;; PIN input
|
||||
(def pin-input quo.components.pin-input.view/view)
|
||||
|
||||
;;;; Links
|
||||
(def internal-link-card quo.components.links.internal-link-card.view/view)
|
||||
(def link-preview quo.components.links.link-preview.view/view)
|
||||
@@ -330,6 +337,7 @@
|
||||
(def account-item quo.components.list-items.account.view/view)
|
||||
(def account-list-card quo.components.list-items.account-list-card.view/view)
|
||||
(def address quo.components.list-items.address.view/view)
|
||||
(def approval-info quo.components.list-items.approval-info.view/view)
|
||||
(def channel quo.components.list-items.channel.view/view)
|
||||
(def community-list quo.components.list-items.community.view/view)
|
||||
(def dapp quo.components.list-items.dapp.view/view)
|
||||
@@ -412,6 +420,9 @@
|
||||
(def qr-code quo.components.share.qr-code.view/view)
|
||||
(def share-qr-code quo.components.share.share-qr-code.view/view)
|
||||
|
||||
;;;; Slideshow
|
||||
(def slider-bar quo.components.slideshow.slider-bar.view/view)
|
||||
|
||||
;;;; SWITCHER
|
||||
(def group-messaging-card quo.components.switchers.group-messaging-card.view/view)
|
||||
|
||||
@@ -462,6 +473,7 @@
|
||||
(def progress-bar quo.components.wallet.progress-bar.view/view)
|
||||
(def required-tokens quo.components.wallet.required-tokens.view/view)
|
||||
(def summary-info quo.components.wallet.summary-info.view/view)
|
||||
(def swap-input quo.components.wallet.swap-input.view/view)
|
||||
(def network-link quo.components.wallet.network-link.view/view)
|
||||
(def token-input quo.components.wallet.token-input.view/view)
|
||||
(def wallet-overview quo.components.wallet.wallet-overview.view/view)
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
quo.components.links.url-preview.component-spec
|
||||
quo.components.list-items.account.component-spec
|
||||
quo.components.list-items.address.component-spec
|
||||
quo.components.list-items.approval-info.component-spec
|
||||
quo.components.list-items.channel.component-spec
|
||||
quo.components.list-items.community.component-spec
|
||||
quo.components.list-items.dapp.component-spec
|
||||
@@ -86,6 +87,7 @@
|
||||
quo.components.settings.reorder-item.component-spec
|
||||
quo.components.settings.settings-item.component-spec
|
||||
quo.components.share.share-qr-code.component-spec
|
||||
quo.components.slideshow.slider-bar.component-spec
|
||||
quo.components.switchers.base-card.component-spec
|
||||
quo.components.switchers.group-messaging-card.component-spec
|
||||
quo.components.tags.collectible-tag.component-spec
|
||||
@@ -110,6 +112,7 @@
|
||||
quo.components.wallet.progress-bar.component-spec
|
||||
quo.components.wallet.required-tokens.component-spec
|
||||
quo.components.wallet.summary-info.component-spec
|
||||
quo.components.wallet.swap-input.component-spec
|
||||
quo.components.wallet.token-input.component-spec
|
||||
quo.components.wallet.transaction-progress.component-spec
|
||||
quo.components.wallet.transaction-summary.component-spec
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
:gnosis (js/require "../resources/images/networks/Gnosis.png")
|
||||
:hermez (js/require "../resources/images/networks/Hermez.png")
|
||||
:optimism (js/require "../resources/images/networks/Optimism.png")
|
||||
:paraswap (js/require "../resources/images/networks/Paraswap.png")
|
||||
:polygon (js/require "../resources/images/networks/Polygon.png")
|
||||
:scroll (js/require "../resources/images/networks/Scroll.png")
|
||||
:taiko (js/require "../resources/images/networks/Taiko.png")
|
||||
|
||||
@@ -1,33 +1,92 @@
|
||||
(ns react-native.wallet-connect
|
||||
(:require
|
||||
["@walletconnect/core" :refer [Core]]
|
||||
["@walletconnect/utils" :refer
|
||||
[buildApprovedNamespaces getSdkError parseUri]]
|
||||
["@walletconnect/web3wallet" :refer [Web3Wallet]]))
|
||||
["@walletconnect/core" :as wc-core]
|
||||
["@walletconnect/utils" :as wc-utils]
|
||||
["@walletconnect/web3wallet$default" :as Web3Wallet]
|
||||
[cljs-bean.core :as bean]
|
||||
[oops.core :as oops]))
|
||||
|
||||
(defn- wallet-connect-core
|
||||
[project-id]
|
||||
(Core. #js {:projectId project-id}))
|
||||
(new ^js wc-core/Core (clj->js {:projectId project-id})))
|
||||
|
||||
(defn init
|
||||
[project-id metadata]
|
||||
(let [core (wallet-connect-core project-id)]
|
||||
(Web3Wallet.init
|
||||
(clj->js {:core core
|
||||
:metadata metadata}))))
|
||||
(oops/ocall Web3Wallet
|
||||
"init"
|
||||
(bean/->js {:core core
|
||||
:metadata metadata}))))
|
||||
|
||||
(defn build-approved-namespaces
|
||||
[proposal supported-namespaces]
|
||||
(buildApprovedNamespaces
|
||||
(clj->js {:proposal proposal
|
||||
:supportedNamespaces supported-namespaces})))
|
||||
(oops/ocall wc-utils
|
||||
"buildApprovedNamespaces"
|
||||
(bean/->js {:proposal proposal
|
||||
:supportedNamespaces supported-namespaces})))
|
||||
|
||||
;; Get an error from this list:
|
||||
;; https://github.com/WalletConnect/walletconnect-monorepo/blob/c6e9529418a0c81d4efcc6ac4e61f242a50b56c5/packages/utils/src/errors.ts
|
||||
(defn get-sdk-error
|
||||
[error-key]
|
||||
(getSdkError error-key))
|
||||
(oops/ocall wc-utils "getSdkError" error-key))
|
||||
|
||||
(defn parse-uri
|
||||
[uri]
|
||||
(-> uri
|
||||
parseUri
|
||||
(js->clj :keywordize-keys true)))
|
||||
(-> (oops/ocall wc-utils "parseUri" uri)
|
||||
(bean/->clj)))
|
||||
|
||||
(defn respond-session-request
|
||||
[{:keys [web3-wallet topic id result error]}]
|
||||
(oops/ocall web3-wallet
|
||||
"respondSessionRequest"
|
||||
(bean/->js {:topic topic
|
||||
:response
|
||||
(merge {:id id
|
||||
:jsonrpc "2.0"}
|
||||
(when result
|
||||
{:result result})
|
||||
(when error
|
||||
{:error error}))})))
|
||||
|
||||
(defn reject-session
|
||||
[{:keys [web3-wallet id reason]}]
|
||||
(.rejectSession web3-wallet
|
||||
(clj->js {:id id
|
||||
:reason reason})))
|
||||
|
||||
(defn approve-session
|
||||
[{:keys [web3-wallet id approved-namespaces]}]
|
||||
(oops/ocall web3-wallet
|
||||
"approveSession"
|
||||
(bean/->js {:id id
|
||||
:namespaces approved-namespaces})))
|
||||
|
||||
(defn disconnect-session
|
||||
[{:keys [web3-wallet reason topic]}]
|
||||
(oops/ocall web3-wallet
|
||||
"disconnectSession"
|
||||
(bean/->js {:topic topic
|
||||
:reason reason})))
|
||||
|
||||
(defn get-active-sessions
|
||||
[web3-wallet]
|
||||
(oops/ocall web3-wallet "getActiveSessions"))
|
||||
|
||||
(defn core-pairing-pair
|
||||
[web3-wallet url]
|
||||
(oops/ocall web3-wallet
|
||||
"core.pairing.pair"
|
||||
(bean/->js {:uri url})))
|
||||
|
||||
(defn get-pairings
|
||||
[web3-wallet]
|
||||
(oops/ocall web3-wallet "core.pairing.getPairings"))
|
||||
|
||||
(defn register-handler
|
||||
[{:keys [web3-wallet event handler]}]
|
||||
(oops/ocall web3-wallet
|
||||
"on"
|
||||
event
|
||||
#(-> (bean/->clj %)
|
||||
handler)))
|
||||
|
||||
@@ -63,8 +63,10 @@
|
||||
(defn view
|
||||
[{:keys [hide? insets]}
|
||||
{:keys [content selected-item padding-bottom-override border-radius on-close shell?
|
||||
gradient-cover? customization-color hide-handle? blur-radius]
|
||||
:or {border-radius 12}}]
|
||||
gradient-cover? customization-color hide-handle? blur-radius
|
||||
hide-on-background-press?]
|
||||
:or {border-radius 12
|
||||
hide-on-background-press? true}}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
{window-height :height} (rn/get-window)
|
||||
[sheet-height set-sheet-height] (rn/use-state 0)
|
||||
@@ -119,7 +121,7 @@
|
||||
:on-layout handle-layout-height}
|
||||
;; backdrop
|
||||
[rn/pressable
|
||||
{:on-press #(rf/dispatch [:hide-bottom-sheet])
|
||||
{:on-press #(when hide-on-background-press? (rf/dispatch [:hide-bottom-sheet]))
|
||||
:style {:flex 1}}
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
(ns status-im.common.floating-button-page.floating-container.style
|
||||
(:require [react-native.safe-area :as safe-area]))
|
||||
(:require [quo.foundations.colors :as colors]
|
||||
[react-native.safe-area :as safe-area]))
|
||||
|
||||
(defn content-container
|
||||
[blur? keyboard-shown?]
|
||||
@@ -11,7 +12,12 @@
|
||||
:padding-horizontal 20}
|
||||
blur? (dissoc :padding-vertical :padding-horizontal))))
|
||||
|
||||
(def blur-inner-container
|
||||
{:background-color :transparent ; required, otherwise blur-view will shrink
|
||||
(defn blur-inner-container
|
||||
[theme shell-overlay?]
|
||||
{:background-color (colors/theme-colors colors/white-70-blur
|
||||
(if shell-overlay?
|
||||
colors/neutral-80-opa-80-blur
|
||||
colors/neutral-95-opa-70-blur)
|
||||
theme)
|
||||
:padding-vertical 12
|
||||
:padding-horizontal 20})
|
||||
|
||||
@@ -1,27 +1,25 @@
|
||||
(ns status-im.common.floating-button-page.floating-container.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.floating-button-page.floating-container.style :as style]))
|
||||
|
||||
(defn- blur-container
|
||||
[child]
|
||||
[child shell-overlay?]
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
[quo/blur
|
||||
{:blur-amount 52
|
||||
:blur-radius 20
|
||||
:blur-type :transparent
|
||||
:blur-overlay-color (colors/theme-colors colors/white-70-blur colors/neutral-95-opa-70-blur theme)}
|
||||
[rn/view {:style style/blur-inner-container}
|
||||
{:blur-amount 20
|
||||
:blur-type :transparent
|
||||
:overlay-color :transparent}
|
||||
[rn/view {:style (style/blur-inner-container theme shell-overlay?)}
|
||||
child]]))
|
||||
|
||||
(defn view
|
||||
[{:keys [on-layout keyboard-shown? blur?]} child]
|
||||
[{:keys [on-layout keyboard-shown? blur? shell-overlay?]} child]
|
||||
[rn/view
|
||||
{:style (style/content-container blur? keyboard-shown?)
|
||||
:on-layout on-layout}
|
||||
(if blur?
|
||||
[blur-container child]
|
||||
[blur-container child shell-overlay?]
|
||||
child)])
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
(defn view
|
||||
[{:keys [header footer customization-color footer-container-padding header-container-style
|
||||
content-container-style gradient-cover? keyboard-should-persist-taps]
|
||||
content-container-style gradient-cover? keyboard-should-persist-taps shell-overlay?]
|
||||
:or {footer-container-padding (safe-area/get-top)}}
|
||||
& children]
|
||||
(reagent/with-let [scroll-view-ref (atom nil)
|
||||
@@ -121,7 +121,8 @@
|
||||
[floating-container/view
|
||||
{:on-layout set-footer-container-height
|
||||
:keyboard-shown? keyboard-shown?
|
||||
:blur? show-background?}
|
||||
:blur? show-background?
|
||||
:shell-overlay? shell-overlay?}
|
||||
footer]]]])
|
||||
(finally
|
||||
(remove-listeners))))
|
||||
|
||||
@@ -144,6 +144,10 @@
|
||||
(fn [_ [opts]]
|
||||
{:keychain/save-password-and-auth-method opts}))
|
||||
|
||||
(defn- whisper-key-name
|
||||
[address]
|
||||
(str address "-whisper"))
|
||||
|
||||
;; NOTE: migrating the plaintext password in the keychain
|
||||
;; with the hashed one. Added due to the sync onboarding
|
||||
;; flow, where the password arrives already hashed.
|
||||
@@ -151,17 +155,38 @@
|
||||
:keychain/password-hash-migration
|
||||
(fn [{:keys [key-uid callback]
|
||||
:or {callback identity}}]
|
||||
(-> (get-password-migration! key-uid identity)
|
||||
(.then (fn [migrated?]
|
||||
(if migrated?
|
||||
(callback)
|
||||
(-> (get-user-password! key-uid identity)
|
||||
(.then security/hash-masked-password)
|
||||
(.then #(save-user-password! key-uid %))
|
||||
(.then #(save-password-migration! key-uid))
|
||||
(.then callback)))))
|
||||
(.catch (fn [err]
|
||||
(log/error "Failed to migrate the keychain password"
|
||||
{:error err
|
||||
:key-uid key-uid
|
||||
:event :keychain/password-hash-migration}))))))
|
||||
(keychain/get-credentials
|
||||
(whisper-key-name key-uid)
|
||||
(fn [whisper-key-data]
|
||||
(if whisper-key-data
|
||||
(callback) ;; we don't need to migrate keycard password
|
||||
(-> (get-password-migration! key-uid identity)
|
||||
(.then (fn [migrated?]
|
||||
(if migrated?
|
||||
(callback)
|
||||
(-> (get-user-password! key-uid identity)
|
||||
(.then security/hash-masked-password)
|
||||
(.then #(save-user-password! key-uid %))
|
||||
(.then #(save-password-migration! key-uid))
|
||||
(.then callback)))))
|
||||
(.catch (fn [err]
|
||||
(log/error "Failed to migrate the keychain password"
|
||||
{:error err
|
||||
:key-uid key-uid
|
||||
:event :keychain/password-hash-migration})))))))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keychain/get-keycard-keys
|
||||
(fn [[key-uid callback]]
|
||||
(keychain/get-credentials
|
||||
key-uid
|
||||
(fn [encryption-key-data]
|
||||
(if encryption-key-data
|
||||
(keychain/get-credentials
|
||||
(whisper-key-name key-uid)
|
||||
(fn [whisper-key-data]
|
||||
(if whisper-key-data
|
||||
(callback [(oops/oget encryption-key-data "password")
|
||||
(oops/oget whisper-key-data "password")])
|
||||
(callback nil))))
|
||||
(callback nil))))))
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
(ns status-im.common.metrics-confirmation-modal.style)
|
||||
|
||||
(def points-wrapper
|
||||
{:margin-top 11
|
||||
:margin-horizontal 20
|
||||
:gap 21
|
||||
:margin-bottom 15})
|
||||
|
||||
(def item-text
|
||||
{:margin-top 10
|
||||
:margin-left -4})
|
||||
|
||||
(def info-text
|
||||
{:margin-top -5})
|
||||
@@ -0,0 +1,79 @@
|
||||
(ns status-im.common.metrics-confirmation-modal.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.metrics-confirmation-modal.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- dismiss-keyboard
|
||||
[]
|
||||
(rf/dispatch [:dismiss-keyboard]))
|
||||
|
||||
(defn- hide-bottom-sheet
|
||||
[]
|
||||
(rf/dispatch [:hide-bottom-sheet]))
|
||||
|
||||
(defn- toggle-metrics
|
||||
[enabled?]
|
||||
(rf/dispatch [:centralized-metrics/toggle-centralized-metrics enabled?]))
|
||||
|
||||
(def ^:private will-receive-points
|
||||
[:t/ip-address
|
||||
:t/universally-unique-identifiers-of-device
|
||||
:t/logs-of-actions-withing-the-app])
|
||||
|
||||
(def ^:private not-receive-points
|
||||
[:t/your-profile-information
|
||||
:t/your-addresses
|
||||
:t/information-you-input-and-send])
|
||||
|
||||
(defn- bullet-points
|
||||
[{:keys [title points]}]
|
||||
[rn/view
|
||||
[quo/text {:weight :semi-bold}
|
||||
title]
|
||||
(for [label points]
|
||||
^{:key label}
|
||||
[quo/markdown-list
|
||||
{:description (i18n/label label)
|
||||
:blur? true
|
||||
:container-style style/item-text}])])
|
||||
|
||||
(defn- on-share-usage
|
||||
[]
|
||||
(toggle-metrics true)
|
||||
(hide-bottom-sheet))
|
||||
|
||||
(defn- on-do-not-share
|
||||
[]
|
||||
(toggle-metrics false)
|
||||
(hide-bottom-sheet))
|
||||
|
||||
(defn view
|
||||
[{:keys [settings?]}]
|
||||
(rn/use-mount #(dismiss-keyboard))
|
||||
[:<>
|
||||
[quo/drawer-top
|
||||
{:title (i18n/label :t/help-us-improve-status)
|
||||
:description (i18n/label :t/collecting-usage-data)}]
|
||||
[rn/view {:style style/points-wrapper}
|
||||
[bullet-points
|
||||
{:title (i18n/label :t/what-we-will-receive)
|
||||
:points will-receive-points}]
|
||||
[bullet-points
|
||||
{:title (i18n/label :t/what-we-wont-receive)
|
||||
:points not-receive-points}]
|
||||
(when-not settings?
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:style style/info-text}
|
||||
(i18n/label :t/sharing-usage-data-can-be-turned-off)])]
|
||||
[quo/bottom-actions
|
||||
{:actions :two-actions
|
||||
:blur? true
|
||||
:button-one-label (i18n/label :t/share-usage-data)
|
||||
:button-one-props {:on-press on-share-usage}
|
||||
:button-two-label (i18n/label (if settings? :t/do-not-share :t/not-now))
|
||||
:button-two-props {:type :grey
|
||||
:on-press on-do-not-share}}]])
|
||||
@@ -35,7 +35,9 @@
|
||||
user-in-syncing-devices-screen? (or (= (:view-id db) :screen/onboarding.syncing-progress)
|
||||
(= (:view-id db) :screen/profile.profiles)
|
||||
(= (:view-id db) :screen/onboarding.syncing-progress-intro))
|
||||
user-in-sign-in-intro-screen? (= (:view-id db) :screen/onboarding.sign-in-intro)]
|
||||
user-in-sign-in-intro-screen? (= (:view-id db) :screen/onboarding.sign-in-intro)
|
||||
keystore-files-transfer-action? (= action
|
||||
constants/local-pairing-action-keystore-files-transfer)]
|
||||
(merge {:db (cond-> db
|
||||
connection-success?
|
||||
(assoc-in [:syncing :pairing-status] :connected)
|
||||
@@ -61,7 +63,7 @@
|
||||
(and completed-pairing? receiver?)
|
||||
{:dispatch [:profile.login/local-paired-user]}
|
||||
|
||||
(and error-on-pairing? (some? error))
|
||||
(and error-on-pairing? (some? error) (not keystore-files-transfer-action?))
|
||||
{:dispatch [:toasts/upsert
|
||||
{:type :negative
|
||||
:text error}]}))))
|
||||
|
||||
@@ -25,7 +25,9 @@
|
||||
:invite-friends (js/require "../resources/images/ui2/invite-friends.png")
|
||||
:transaction-progress (js/require "../resources/images/ui2/transaction-progress.png")
|
||||
:welcome-illustration (js/require "../resources/images/ui2/welcome_illustration.png")
|
||||
:notifications (js/require "../resources/images/ui2/notifications.png")})
|
||||
:notifications (js/require "../resources/images/ui2/notifications.png")
|
||||
:nfc-prompt (js/require "../resources/images/ui2/nfc-prompt.png")
|
||||
:nfc-success (js/require "../resources/images/ui2/nfc-success.png")})
|
||||
|
||||
(def ui-themed
|
||||
{:angry-man
|
||||
|
||||
@@ -10,11 +10,14 @@
|
||||
|
||||
(defn authorize
|
||||
[{:keys [db]} [args]]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])
|
||||
keycard? (get-in db [:profile/profile :keycard-pairing])]
|
||||
{:fx [[:effects.biometric/check-if-available
|
||||
{:key-uid key-uid
|
||||
:on-success #(rf/dispatch [:standard-auth/authorize-with-biometric args])
|
||||
:on-fail #(rf/dispatch [:standard-auth/authorize-with-password args])}]]}))
|
||||
:on-fail (if keycard?
|
||||
#(rf/dispatch [:standard-auth/authorize-with-keycard args])
|
||||
#(rf/dispatch [:standard-auth/authorize-with-password args]))}]]}))
|
||||
|
||||
(schema/=> authorize events-schema/?authorize)
|
||||
(rf/reg-event-fx :standard-auth/authorize authorize)
|
||||
@@ -45,8 +48,11 @@
|
||||
|
||||
(defn on-biometric-success
|
||||
[{:keys [db]} [on-auth-success]]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])]
|
||||
{:fx [[:keychain/get-user-password [key-uid on-auth-success]]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])
|
||||
keycard? (get-in db [:profile/profile :keycard-pairing])]
|
||||
{:fx [(if keycard?
|
||||
[:keychain/get-keycard-keys [key-uid on-auth-success]]
|
||||
[:keychain/get-user-password [key-uid on-auth-success]])
|
||||
[:dispatch [:standard-auth/set-success true]]
|
||||
[:dispatch [:standard-auth/reset-login-password]]]}))
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
(goog-define ALCHEMY_OPTIMISM_GOERLI_TOKEN "")
|
||||
(goog-define ALCHEMY_OPTIMISM_SEPOLIA_TOKEN "")
|
||||
(goog-define WALLET_CONNECT_PROJECT_ID "87815d72a81d739d2a7ce15c2cfdefb3")
|
||||
(goog-define MIXPANEL_APP_ID "3350627")
|
||||
(goog-define MIXPANEL_TOKEN "5c73bda2d36a9f688a5ee45641fb6775")
|
||||
|
||||
(def mainnet-rpc-url (str "https://eth-archival.rpc.grove.city/v1/" POKT_TOKEN))
|
||||
(def goerli-rpc-url (str "https://goerli-archival.gateway.pokt.network/v1/lb/" POKT_TOKEN))
|
||||
@@ -39,6 +41,9 @@
|
||||
(def opensea-link "https://opensea.io")
|
||||
(def opensea-tesnet-link "https://testnets.opensea.io")
|
||||
|
||||
(def mixpanel-app-id MIXPANEL_APP_ID)
|
||||
(def mixpanel-token MIXPANEL_TOKEN)
|
||||
|
||||
(def opensea-api-key OPENSEA_API_KEY)
|
||||
(def bootnodes-settings-enabled? (enabled? (get-config :BOOTNODES_SETTINGS_ENABLED "1")))
|
||||
(def mailserver-confirmations-enabled? (enabled? (get-config :MAILSERVER_CONFIRMATIONS_ENABLED)))
|
||||
@@ -58,7 +63,6 @@
|
||||
(def quo-preview-enabled? (enabled? (get-config :ENABLE_QUO_PREVIEW "0")))
|
||||
(def database-management-enabled? (enabled? (get-config :DATABASE_MANAGEMENT_ENABLED "0")))
|
||||
(def debug-webview? (enabled? (get-config :DEBUG_WEBVIEW "0")))
|
||||
(def collectibles-enabled? (enabled? (get-config :COLLECTIBLES_ENABLED "1")))
|
||||
(def test-stateofus? (enabled? (get-config :TEST_STATEOFUS "0")))
|
||||
(def two-minutes-syncing? (enabled? (get-config :TWO_MINUTES_SYNCING "0")))
|
||||
(def swap-enabled? (enabled? (get-config :SWAP_ENABLED "0")))
|
||||
@@ -68,7 +72,7 @@
|
||||
|
||||
;; CONFIG VALUES
|
||||
(def log-level (string/upper-case (get-config :LOG_LEVEL "")))
|
||||
(def fleet (get-config :FLEET "waku.sandbox"))
|
||||
(def fleet (get-config :FLEET ""))
|
||||
(def apn-topic (get-config :APN_TOPIC "im.status.ethereum"))
|
||||
(def default-network (get-config :DEFAULT_NETWORK "goerli_rpc"))
|
||||
(def max-installations 2)
|
||||
|
||||
@@ -45,6 +45,11 @@
|
||||
(def ^:const activity-center-membership-status-accepted 2)
|
||||
(def ^:const activity-center-membership-status-declined 3)
|
||||
|
||||
;; Choose the maximum number of notifications that *usually/safely* fit on
|
||||
;; most screens, so that the UI doesn't have to needlessly render
|
||||
;; notifications.
|
||||
(def ^:const notifications-per-page 7)
|
||||
|
||||
(def ^:const mute-for-15-mins-type 1)
|
||||
(def ^:const mute-for-1-hour-type 2)
|
||||
(def ^:const mute-for-8-hours-type 3)
|
||||
@@ -126,6 +131,7 @@
|
||||
(def ^:const profile-pictures-visibility-none 3)
|
||||
|
||||
(def ^:const min-password-length 6)
|
||||
(def ^:const pincode-length 6)
|
||||
(def ^:const new-password-min-length 10)
|
||||
(def ^:const max-group-chat-participants 20)
|
||||
(def ^:const max-group-chat-name-length 24)
|
||||
@@ -275,15 +281,21 @@
|
||||
#{wallet-connect-personal-sign-method
|
||||
wallet-connect-eth-sign-method
|
||||
wallet-connect-eth-send-transaction-method
|
||||
wallet-connect-eth-sign-transaction-method
|
||||
;; NOTE: disabled, as we have no clear use cases for it and other wallets don't support it
|
||||
;; wallet-connect-eth-sign-transaction-method
|
||||
wallet-connect-eth-sign-typed-method
|
||||
wallet-connect-eth-sign-typed-v4-method})
|
||||
(def ^:const wallet-connect-supported-events #{"accountsChanged" "chainChanged"})
|
||||
(def ^:const wallet-connect-session-proposal-event "session_proposal")
|
||||
(def ^:const wallet-connect-session-request-event "session_request")
|
||||
(def ^:const wallet-connect-session-delete-event "session_delete")
|
||||
(def ^:const wallet-connect-user-rejected-error-key "USER_REJECTED")
|
||||
(def ^:const wallet-connect-user-disconnected-reason-key "USER_DISCONNECTED")
|
||||
|
||||
(def ^:const transaction-pending-type-wallet-connect-transfer "WalletConnectTransfer")
|
||||
|
||||
(def ^:const token-sort-priority {"SNT" 1 "STT" 1 "ETH" 2 "DAI" 3})
|
||||
|
||||
(def ^:const dapp-permission-contact-code "contact-code")
|
||||
(def ^:const dapp-permission-web3 "web3")
|
||||
(def ^:const dapp-permission-qr-code "qr-code")
|
||||
@@ -369,16 +381,18 @@
|
||||
(def ^:const local-pairing-role-receiver "receiver")
|
||||
|
||||
;; sender and receiver events
|
||||
(def ^:const local-pairing-event-peer-discovered "peer-discovered")
|
||||
(def ^:const local-pairing-event-connection-success "connection-success")
|
||||
(def ^:const local-pairing-event-connection-error "connection-error")
|
||||
(def ^:const local-pairing-event-transfer-success "transfer-success")
|
||||
(def ^:const local-pairing-event-transfer-error "transfer-error")
|
||||
(def ^:const local-pairing-event-received-installation "received-installation")
|
||||
|
||||
;; receiver events
|
||||
(def ^:const local-pairing-event-received-account "received-account")
|
||||
(def ^:const local-pairing-event-process-success "process-success")
|
||||
(def ^:const local-pairing-event-process-error "process-error")
|
||||
(def ^:const local-pairing-event-received-installation "received-installation")
|
||||
(def ^:const local-pairing-event-received-keystore-files "received-keystore-files")
|
||||
|
||||
(def ^:const local-pairing-event-errors
|
||||
#{local-pairing-event-connection-error
|
||||
@@ -389,6 +403,8 @@
|
||||
(def ^:const local-pairing-action-pairing-account 2)
|
||||
(def ^:const local-pairing-action-sync-device 3)
|
||||
(def ^:const local-pairing-action-pairing-installation 4)
|
||||
(def ^:const local-pairing-action-peer-discovery 5)
|
||||
(def ^:const local-pairing-action-keystore-files-transfer 6)
|
||||
|
||||
(def ^:const serialization-key
|
||||
"We pass this serialization key as a parameter to MultiformatSerializePublicKey
|
||||
@@ -500,6 +516,9 @@
|
||||
(def ^:const optimism-full-name "Optimism")
|
||||
(def ^:const arbitrum-full-name "Arbitrum")
|
||||
|
||||
(def ^:const sepolia-full-name "Sepolia")
|
||||
(def ^:const goerli-full-name "Goerli")
|
||||
|
||||
(def ^:const mainnet-network-name :mainnet)
|
||||
(def ^:const ethereum-network-name :ethereum)
|
||||
(def ^:const optimism-network-name :optimism)
|
||||
@@ -560,3 +579,9 @@
|
||||
(def ^:const default-slippage 0.5)
|
||||
(def ^:const max-recommended-slippage 5)
|
||||
(def ^:const max-slippage-decimal-places 2)
|
||||
(def ^:const swap-default-provider
|
||||
{:name :paraswap
|
||||
:full-name "Paraswap"
|
||||
:color :blue
|
||||
:contract-address "0xdef171fe48cf0115b1d80b88dc8eab59176fee57"
|
||||
:terms-and-conditions-url "https://files.paraswap.io/tos_v4.pdf"})
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
(ns status-im.contexts.centralized-metrics.effects
|
||||
(:require
|
||||
[native-module.core :as native-module]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/reg-fx :effects.centralized-metrics/toggle-metrics
|
||||
(fn [enabled?]
|
||||
(native-module/toggle-centralized-metrics enabled? #(log/debug "toggled-metrics" % enabled?))))
|
||||
@@ -0,0 +1,51 @@
|
||||
(ns status-im.contexts.centralized-metrics.events
|
||||
(:require
|
||||
[native-module.core :as native-module]
|
||||
[re-frame.interceptor :as interceptor]
|
||||
status-im.contexts.centralized-metrics.effects
|
||||
[status-im.contexts.centralized-metrics.tracking :as tracking]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(def ^:const user-confirmed-key :centralized-metrics/user-confirmed?)
|
||||
(def ^:const enabled-key :centralized-metrics/enabled?)
|
||||
|
||||
(defn show-confirmation-modal?
|
||||
[db]
|
||||
(not (user-confirmed-key db)))
|
||||
|
||||
(defn push-event?
|
||||
[db]
|
||||
(or (not (user-confirmed-key db))
|
||||
(enabled-key db)))
|
||||
|
||||
(defn centralized-metrics-interceptor
|
||||
[context]
|
||||
(when-let [event (tracking/tracked-event (interceptor/get-coeffect context :event))]
|
||||
(log/debug "tracking event" event)
|
||||
(when (push-event? (interceptor/get-coeffect context :db))
|
||||
(native-module/add-centralized-metric event)))
|
||||
context)
|
||||
|
||||
(def interceptor
|
||||
(interceptor/->interceptor
|
||||
:id :centralized-metrics
|
||||
:after centralized-metrics-interceptor))
|
||||
|
||||
(rf/reg-event-fx :centralized-metrics/toggle-centralized-metrics
|
||||
(fn [{:keys [db]} [enabled?]]
|
||||
{:fx [[:effects.centralized-metrics/toggle-metrics enabled?]]
|
||||
:db (assoc db
|
||||
user-confirmed-key
|
||||
true
|
||||
enabled-key
|
||||
enabled?)}))
|
||||
|
||||
(rf/reg-event-fx :centralized-metrics/check-modal
|
||||
(fn [{:keys [db]} [modal-view]]
|
||||
(when (show-confirmation-modal? db)
|
||||
{:fx [[:dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn [] [modal-view])
|
||||
:shell? true}]]]})))
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
(ns status-im.contexts.centralized-metrics.events-test
|
||||
(:require
|
||||
[cljs.test :refer-macros [deftest is testing]]
|
||||
matcher-combinators.test
|
||||
[status-im.contexts.centralized-metrics.events :as events]
|
||||
[status-im.contexts.centralized-metrics.tracking :as tracking]
|
||||
[test-helpers.unit :as h]))
|
||||
|
||||
(deftest show-confirmation-modal-test
|
||||
(testing "returns true if the user confirmed"
|
||||
(is (false? (events/show-confirmation-modal? {events/user-confirmed-key true})))
|
||||
(is (true? (events/show-confirmation-modal? {})))))
|
||||
|
||||
(deftest push-event-test
|
||||
(testing "returns correct boolean value"
|
||||
(is (true? (events/push-event? {:centralized-metrics/user-confirmed? false})))
|
||||
(is (true? (events/push-event? {:centralized-metrics/enabled? true})))
|
||||
(is (false? (events/push-event? {:centralized-metrics/user-confirmed? true
|
||||
:centralized-metrics/enabled? false})))))
|
||||
|
||||
(deftest centralized-metrics-interceptor-test
|
||||
(testing "processes context correctly"
|
||||
(with-redefs [tracking/tracked-event (fn [_] {:metric "mocked-event"})
|
||||
events/push-event? (fn [_] true)]
|
||||
(let [context {:coeffects {:event [:some-event]
|
||||
:db {:centralized-metrics/enabled? true}}}]
|
||||
(is (= context (events/centralized-metrics-interceptor context)))))))
|
||||
|
||||
(h/deftest-event :centralized-metrics/toggle-centralized-metrics
|
||||
[event-id dispatch]
|
||||
(testing "toggling value to true"
|
||||
(let [enabled? true
|
||||
expected-fxs {:db {:centralized-metrics/user-confirmed? true
|
||||
:centralized-metrics/enabled? enabled?}
|
||||
:fx [[:effects.centralized-metrics/toggle-metrics enabled?]]}]
|
||||
(is (match? expected-fxs (dispatch [event-id enabled?])))))
|
||||
(testing "toggling value to false"
|
||||
(let [enabled? false
|
||||
expected-fxs {:db {:centralized-metrics/user-confirmed? true
|
||||
:centralized-metrics/enabled? enabled?}
|
||||
:fx [[:effects.centralized-metrics/toggle-metrics enabled?]]}]
|
||||
(is (match? expected-fxs (dispatch [event-id enabled?]))))))
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user