Merge pull request #359 from status-im/feature/#218
Rework transactions sending
This commit is contained in:
commit
8011213ee9
|
@ -14,5 +14,5 @@ android {
|
|||
|
||||
dependencies {
|
||||
compile 'com.facebook.react:react-native:+'
|
||||
compile(group: 'status-im', name: 'status-go', version: '0.1.1', ext: 'aar')
|
||||
compile(group: 'status-im', name: 'status-go', version: 'test-jcp6', ext: 'aar')
|
||||
}
|
|
@ -5,12 +5,15 @@ import android.content.Intent;
|
|||
import android.os.*;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import com.github.status_im.status_go.cmd.Statusgo;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class StatusService extends Service {
|
||||
|
||||
|
@ -19,6 +22,8 @@ public class StatusService extends Service {
|
|||
private static boolean isNodeInitialized = false;
|
||||
private final Handler handler = new Handler();
|
||||
|
||||
private ExecutorService executor = null;
|
||||
|
||||
private static String dataFolder;
|
||||
|
||||
private static Messenger applicationMessenger = null;
|
||||
|
@ -74,6 +79,9 @@ public class StatusService extends Service {
|
|||
public void onDestroy() {
|
||||
|
||||
super.onDestroy();
|
||||
if (executor != null) {
|
||||
executor.shutdownNow();
|
||||
}
|
||||
//TODO: stop geth
|
||||
stopNode(null);
|
||||
//isNodeInitialized = false;
|
||||
|
@ -83,6 +91,9 @@ public class StatusService extends Service {
|
|||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
|
||||
if (executor == null) {
|
||||
executor = Executors.newCachedThreadPool();
|
||||
}
|
||||
return Service.START_STICKY;
|
||||
}
|
||||
|
||||
|
@ -155,7 +166,11 @@ public class StatusService extends Service {
|
|||
Statusgo.StartNode(dataFolder);
|
||||
Log.d(TAG, "Geth node started");
|
||||
Log.w(TAG, "adding peer");
|
||||
Statusgo.AddPeer("enode://e15869ba08a25e49be7568b951e15af5d77a472c8e4104a14a4951f99936d65f91240d5b5f23674aee44f1ac09d8adfc6a9bff75cd8c2df73a26442f313f2da4@162.243.63.248:30303");
|
||||
|
||||
Statusgo.AddPeer("enode://efe4e6899e05237180c0970aedb81cb5aecf5b200779c7c9e1f955783e8299b364c0b981c03f4c36ad5328ef972b417afde260bbf2c5a8db37ba7f5738033952@198.199.105.122:30303");
|
||||
Statusgo.AddPeer("enode://5a5839435f48d1e3f2f907e4582f0a134e0b7857afe507073978ca32cf09ea54989dac433605047d0bc4cd19a8c80affac6876069014283aa7c7bb4954d0e623@95.85.40.211:30303");
|
||||
Statusgo.AddPeer("enode://2f05d430b4cb1c0e2a0772d48da3a034f1b596ea7163ab80d3404802d10b7d55bde323897c2be0d36026181e1a68510ea1f42a646ef9494c27e61f61e4088b7d@188.166.229.119:30303");
|
||||
Statusgo.AddPeer("enode://ad61a21f83f12b0ca494611650f5e4b6427784e7c62514dcb729a3d65106de6f12836813acf39bdc35c12ecfd0e230723678109fd4e7091ce389697bd7da39b4@139.59.212.114:30303");
|
||||
isNodeInitialized = true;
|
||||
}
|
||||
createAndSendReply(message, StatusMessages.MSG_START_NODE, null);
|
||||
|
@ -256,12 +271,45 @@ public class StatusService extends Service {
|
|||
String chatId = data.getString("chatId");
|
||||
String path = data.getString("path");
|
||||
String params = data.getString("params");
|
||||
String callbackIdentifier = data.getString(StatusConnector.CALLBACK_IDENTIFIER);
|
||||
|
||||
Log.d(TAG, "Before StatusGo.Call");
|
||||
Callable<String> callable = new JailRequest(message.replyTo, chatId, path, params, callbackIdentifier);
|
||||
executor.submit(callable);
|
||||
}
|
||||
|
||||
public class JailRequest implements Callable<String> {
|
||||
|
||||
String chatId;
|
||||
String path;
|
||||
String params;
|
||||
String callbackIdentifier;
|
||||
Messenger messenger;
|
||||
|
||||
JailRequest(Messenger messenger, String chatId, String path, String params, String callbackIdentifier) {
|
||||
|
||||
this.messenger = messenger;
|
||||
this.chatId = chatId;
|
||||
this.path = path;
|
||||
this.params = params;
|
||||
this.callbackIdentifier = callbackIdentifier;
|
||||
}
|
||||
|
||||
public String call() throws Exception {
|
||||
Log.d(TAG, "StatusGo.Call");
|
||||
String result = Statusgo.Call(chatId, path, params);
|
||||
|
||||
Bundle replyData = new Bundle();
|
||||
replyData.putString("data", result);
|
||||
createAndSendReply(message, StatusMessages.MSG_JAIL_CALL, replyData);
|
||||
Message replyMessage = Message.obtain(null, StatusMessages.MSG_JAIL_CALL, 0, 0, null);
|
||||
Log.d(TAG, "Callback identifier: " + callbackIdentifier);
|
||||
replyData.putString(StatusConnector.CALLBACK_IDENTIFIER, callbackIdentifier);
|
||||
replyMessage.setData(replyData);
|
||||
sendReply(messenger, replyMessage);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static boolean isNodeInitialized() {
|
||||
|
|
|
@ -1,12 +1,22 @@
|
|||
#import "RCTStatus.h"
|
||||
|
||||
#import "RCTBridge.h"
|
||||
#import "RCTEventDispatcher.h"
|
||||
#import <Statusgo/Statusgo.h>
|
||||
|
||||
static bool isStatusInitialized;
|
||||
|
||||
static RCTBridge *bridge;
|
||||
@implementation Status{
|
||||
}
|
||||
|
||||
-(RCTBridge *)bridge
|
||||
{
|
||||
return bridge;
|
||||
}
|
||||
|
||||
-(void)setBridge:(RCTBridge *)newBridge
|
||||
{
|
||||
bridge = newBridge;
|
||||
}
|
||||
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
|
@ -41,8 +51,12 @@ RCT_EXPORT_METHOD(callJail:(NSString *)chatId
|
|||
#if DEBUG
|
||||
NSLog(@"CallJail() method called");
|
||||
#endif
|
||||
dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
char * result = Call((char *) [chatId UTF8String], (char *) [path UTF8String], (char *) [params UTF8String]);
|
||||
dispatch_async( dispatch_get_main_queue(), ^{
|
||||
callback(@[[NSString stringWithUTF8String: result]]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -69,7 +83,8 @@ RCT_EXPORT_METHOD(startNode:(RCTResponseSenderBlock)onResultCallback) {
|
|||
}else
|
||||
NSLog(@"folderName: %@", folderName);
|
||||
|
||||
NSString *peer = @"enode://e15869ba08a25e49be7568b951e15af5d77a472c8e4104a14a4951f99936d65f91240d5b5f23674aee44f1ac09d8adfc6a9bff75cd8c2df73a26442f313f2da4@162.243.63.248:30303";
|
||||
NSString *peer1 = @"enode://e15869ba08a25e49be7568b951e15af5d77a472c8e4104a14a4951f99936d65f91240d5b5f23674aee44f1ac09d8adfc6a9bff75cd8c2df73a26442f313f2da4@162.243.63.248:30303";
|
||||
NSString *peer2 = @"enode://ad61a21f83f12b0ca494611650f5e4b6427784e7c62514dcb729a3d65106de6f12836813acf39bdc35c12ecfd0e230723678109fd4e7091ce389697bd7da39b4@139.59.212.114:30303";
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
|
||||
^(void) {
|
||||
StartNode((char *) [folderName.path UTF8String]);
|
||||
|
@ -77,7 +92,8 @@ RCT_EXPORT_METHOD(startNode:(RCTResponseSenderBlock)onResultCallback) {
|
|||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)),
|
||||
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
|
||||
^(void) {
|
||||
AddPeer((char *) [peer UTF8String]);
|
||||
AddPeer((char *) [peer1 UTF8String]);
|
||||
AddPeer((char *) [peer2 UTF8String]);
|
||||
});
|
||||
onResultCallback(@[[NSNull null]]);
|
||||
return;
|
||||
|
@ -161,4 +177,15 @@ RCT_EXPORT_METHOD(setSoftInputMode: (NSInteger) i) {
|
|||
#endif
|
||||
}
|
||||
|
||||
+ (void)signalEvent:(char *) signal
|
||||
{
|
||||
NSString *sig = [NSString stringWithUTF8String:signal];
|
||||
#if DEBUG
|
||||
NSLog(@"SignalEvent");
|
||||
NSLog(sig);
|
||||
#endif
|
||||
[bridge.eventDispatcher sendAppEventWithName:@"gethEvent"
|
||||
body:@{@"jsonEvent": sig}];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
<artifactItem>
|
||||
<groupId>status-im</groupId>
|
||||
<artifactId>status-go-ios</artifactId>
|
||||
<version>0.1.2</version>
|
||||
<version>ios-signals</version>
|
||||
<type>zip</type>
|
||||
<overWrite>true</overWrite>
|
||||
<outputDirectory>./</outputDirectory>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
:url "http://example.com/FIXME"
|
||||
:license {:name "Eclipse Public License"
|
||||
:url "http://www.eclipse.org/legal/epl-v10.html"}
|
||||
:dependencies [[org.clojure/clojure "1.9.0-alpha12"]
|
||||
:dependencies [[org.clojure/clojure "1.9.0-alpha13"]
|
||||
[org.clojure/clojurescript "1.9.229"]
|
||||
[reagent "0.5.1" :exclusions [cljsjs/react]]
|
||||
[re-frame "0.7.0"]
|
||||
|
|
|
@ -62,8 +62,8 @@ status.command({
|
|||
}]
|
||||
});
|
||||
|
||||
function validateBalance(params) {
|
||||
if(!params.value){
|
||||
function validateBalance(params, context) {
|
||||
if (!params.amount) {
|
||||
return {
|
||||
errors: [
|
||||
status.components.validationMessage(
|
||||
|
@ -75,19 +75,19 @@ function validateBalance(params) {
|
|||
}
|
||||
|
||||
try {
|
||||
var val = web3.toWei(params.value, "ether");
|
||||
var val = web3.toWei(params.amount, "ether");
|
||||
} catch (err) {
|
||||
return {
|
||||
errors: [
|
||||
status.components.validationMessage(
|
||||
"Amount",
|
||||
"Amount is not valid number"//err.message
|
||||
"Amount is not valid number"
|
||||
)
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
var balance = web3.eth.getBalance(params.command.address);
|
||||
var balance = web3.eth.getBalance(context.from);
|
||||
if (bn(val).greaterThan(bn(balance))) {
|
||||
return {
|
||||
errors: [
|
||||
|
@ -102,15 +102,18 @@ function validateBalance(params) {
|
|||
}
|
||||
}
|
||||
|
||||
function sendTransaction(params) {
|
||||
function sendTransaction(params, context) {
|
||||
var data = {
|
||||
from: params.command.from,
|
||||
to: params.command.to,
|
||||
value: web3.toWei(params.value, "ether")
|
||||
from: context.from,
|
||||
to: context.to,
|
||||
value: web3.toWei(params.amount, "ether")
|
||||
};
|
||||
var hash = web3.eth.sendTransaction(data);
|
||||
|
||||
return {"transaction-hash": hash};
|
||||
try {
|
||||
return web3.eth.sendTransaction(data);
|
||||
} catch (err) {
|
||||
return {error: err};
|
||||
}
|
||||
}
|
||||
|
||||
status.command({
|
||||
|
@ -124,7 +127,7 @@ status.command({
|
|||
preview: function (params) {
|
||||
return status.components.text(
|
||||
{},
|
||||
params.value + " ETH"
|
||||
params.amount + " ETH"
|
||||
);
|
||||
},
|
||||
handler: sendTransaction,
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
var _status_catalog = {
|
||||
commands: {},
|
||||
responses: {}
|
||||
};
|
||||
},
|
||||
status = {};
|
||||
|
||||
function Command() {
|
||||
}
|
||||
|
@ -44,10 +45,25 @@ Response.prototype.onReceiveResponse = function (handler) {
|
|||
this.onReceive = handler;
|
||||
};
|
||||
|
||||
var context = {}
|
||||
|
||||
function addContext(ns, key, value) {
|
||||
context[ns][key] = value;
|
||||
}
|
||||
|
||||
function call(pathStr, paramsStr) {
|
||||
var params = JSON.parse(paramsStr),
|
||||
path = JSON.parse(pathStr),
|
||||
fn, res;
|
||||
fn, callResult, message_id;
|
||||
|
||||
if (typeof params.context !== "undefined" &&
|
||||
typeof params.context["message-id"] !== "undefined") {
|
||||
message_id = params.context["message-id"];
|
||||
} else {
|
||||
message_id = null;
|
||||
}
|
||||
context[message_id] = {};
|
||||
status.message_id = message_id;
|
||||
|
||||
fn = path.reduce(function (catalog, name) {
|
||||
if (catalog && catalog[name]) {
|
||||
|
@ -61,9 +77,13 @@ function call(pathStr, paramsStr) {
|
|||
return null;
|
||||
}
|
||||
|
||||
res = fn(params.parameters, params.context);
|
||||
callResult = fn(params.parameters, params.context);
|
||||
result = {
|
||||
returned: callResult,
|
||||
context: context[message_id]
|
||||
};
|
||||
|
||||
return JSON.stringify(res);
|
||||
return JSON.stringify(result);
|
||||
}
|
||||
|
||||
function text(options, s) {
|
||||
|
|
|
@ -275,11 +275,13 @@
|
|||
[{:keys [current-chat-id] :as db} [_ _ id]]
|
||||
(let [chat-id (or id current-chat-id)
|
||||
messages (get-in db [:chats chat-id :messages])
|
||||
db' (assoc db :current-chat-id chat-id)]
|
||||
db' (assoc db :current-chat-id chat-id)
|
||||
commands-loaded? (get-in db [:chats chat-id :commands-loaded])]
|
||||
(when (= current-chat-id wallet-chat-id)
|
||||
(dispatch [:cancel-command]))
|
||||
(dispatch [:load-requests! chat-id])
|
||||
(dispatch [:load-commands! chat-id])
|
||||
(when-not commands-loaded?
|
||||
(dispatch [:load-commands! chat-id]))
|
||||
(if (and (seq messages)
|
||||
(not= (count messages) 1))
|
||||
db'
|
||||
|
|
|
@ -91,7 +91,7 @@
|
|||
(fn [_ [_ {:keys [chat-id handler]} {:keys [error result]}]]
|
||||
;; todo handle error
|
||||
(when-not error
|
||||
(let [{:keys [errors validationHandler parameters]} result]
|
||||
(let [{:keys [errors validationHandler parameters]} (:returned result)]
|
||||
(cond errors
|
||||
(dispatch [::add-validation-errors chat-id errors])
|
||||
|
||||
|
@ -128,6 +128,7 @@
|
|||
:id (random/id)}]
|
||||
(-> db
|
||||
(commands/stage-command command-info)
|
||||
(assoc-in [:command->chat (:id command-info)] chat-id)
|
||||
(assoc :staged-command command-info)
|
||||
(assoc-in [:disable-staging chat-id] true)))))
|
||||
|
||||
|
@ -225,7 +226,7 @@
|
|||
|
||||
(register-handler ::start-command-validation!
|
||||
(u/side-effect!
|
||||
(fn [db [_ {:keys [command-input chat-id] :as data}]]
|
||||
(fn [db [_ {:keys [command-input chat-id address] :as data}]]
|
||||
(let [command-input' (or command-input (commands/get-command-input db))
|
||||
{:keys [parameter-idx params command]} command-input'
|
||||
{:keys [name type]} command
|
||||
|
@ -233,7 +234,8 @@
|
|||
:params
|
||||
(get parameter-idx)
|
||||
:name)
|
||||
context {:current-parameter current-parameter}
|
||||
context {:current-parameter current-parameter
|
||||
:from address}
|
||||
path [(if (= :command type) :commands :responses)
|
||||
name
|
||||
:validator]
|
||||
|
|
|
@ -16,14 +16,16 @@
|
|||
[taoensso.timbre :refer-macros [debug]]))
|
||||
|
||||
(defn prepare-command
|
||||
[identity chat-id {:keys [preview preview-string params command to-message]}]
|
||||
[identity chat-id
|
||||
{:keys [id preview preview-string params command to-message handler-data]}]
|
||||
(let [content {:command (command :name)
|
||||
:params params}]
|
||||
{:message-id (random/id)
|
||||
{:message-id id
|
||||
:from identity
|
||||
:to chat-id
|
||||
:timestamp (time/now-ms)
|
||||
:content (assoc content :preview preview-string)
|
||||
:content (assoc content :preview preview-string
|
||||
:handler-data handler-data)
|
||||
:content-type content-type-command
|
||||
:outgoing true
|
||||
:preview preview-string
|
||||
|
@ -55,7 +57,9 @@
|
|||
(fn [_ [_ {:keys [commands message] :as params}]]
|
||||
(doseq [{:keys [command] :as message} commands]
|
||||
(let [params' (assoc params :staged-command message)]
|
||||
(if (:sending message)
|
||||
(if (:sent-to-jail? message)
|
||||
;; todo there could be other reasons for "long-running"
|
||||
;; hanling of the command besides sendTransaction
|
||||
(dispatch [:navigate-to :confirm])
|
||||
(if (:has-handler command)
|
||||
(dispatch [::invoke-command-handlers! params'])
|
||||
|
@ -71,16 +75,18 @@
|
|||
(register-handler :prepare-command!
|
||||
(u/side-effect!
|
||||
(fn [{:keys [current-public-key] :as db}
|
||||
[_ {:keys [chat-id staged-command] :as params}]]
|
||||
(let [command' (->> staged-command
|
||||
[_ {:keys [chat-id staged-command handler-data] :as params}]]
|
||||
(let [command' (->> (assoc staged-command :handler-data handler-data)
|
||||
(prepare-command current-public-key chat-id)
|
||||
(cu/check-author-direction db chat-id))]
|
||||
(dispatch [::clear-command chat-id (:id staged-command)])
|
||||
(dispatch [:clear-command chat-id (:id staged-command)])
|
||||
(dispatch [::send-command! (assoc params :command command')])))))
|
||||
|
||||
(register-handler ::clear-command
|
||||
(register-handler :clear-command
|
||||
(fn [db [_ chat-id id]]
|
||||
(update-in db [:chats chat-id :staged-commands] dissoc id)))
|
||||
(if chat-id
|
||||
(update-in db [:chats chat-id :staged-commands] dissoc id)
|
||||
db)))
|
||||
|
||||
(register-handler ::send-command!
|
||||
(u/side-effect!
|
||||
|
@ -112,8 +118,9 @@
|
|||
|
||||
(register-handler ::invoke-command-handlers!
|
||||
(u/side-effect!
|
||||
(fn [db [_ {:keys [chat-id address staged-command] :as parameters}]]
|
||||
(let [{:keys [command params]} staged-command
|
||||
(fn [db [_ {:keys [chat-id address staged-command]
|
||||
:as parameters}]]
|
||||
(let [{:keys [id command params]} staged-command
|
||||
{:keys [type name]} command
|
||||
path [(if (= :command type) :commands :responses)
|
||||
name
|
||||
|
@ -121,12 +128,19 @@
|
|||
to (get-in db [:contacts chat-id :address])
|
||||
params {:parameters params
|
||||
:context {:from address
|
||||
:to to}}]
|
||||
(status/call-jail chat-id
|
||||
:to to
|
||||
:message-id id}}]
|
||||
(dispatch [::command-in-processing chat-id id])
|
||||
(status/call-jail
|
||||
chat-id
|
||||
path
|
||||
params
|
||||
#(dispatch [:command-handler! chat-id parameters %]))))))
|
||||
|
||||
(register-handler ::command-in-processing
|
||||
(fn [db [_ chat-id id]]
|
||||
(assoc-in db [:chats chat-id :staged-commands id :sent-to-jail?] true)))
|
||||
|
||||
(register-handler ::prepare-message
|
||||
(u/side-effect!
|
||||
(fn [db [_ {:keys [chat-id identity message] :as params}]]
|
||||
|
|
|
@ -10,11 +10,6 @@
|
|||
[status-im.constants :refer [console-chat-id]]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(defn init-render-command!
|
||||
[_ [chat-id command message-id data]]
|
||||
(status/call-jail chat-id [command :render] data
|
||||
#(dispatch [::render-command chat-id message-id %])))
|
||||
|
||||
(defn render-command
|
||||
[db [chat-id message-id markup]]
|
||||
(let [hiccup (generate-hiccup markup)]
|
||||
|
@ -31,14 +26,24 @@
|
|||
(def regular-events {})
|
||||
|
||||
(defn command-hadler!
|
||||
[_ [chat-id {:keys [command] :as parameters} {:keys [result error]}]]
|
||||
[_ [chat-id
|
||||
{:keys [staged-command] :as parameters}
|
||||
{:keys [result error]}]]
|
||||
(let [{:keys [context returned]} result
|
||||
{:keys [event params]
|
||||
handler-error :error} returned]
|
||||
(cond
|
||||
handler-error
|
||||
(log/debug :error-from-handler handler-error
|
||||
:chat-id chat-id
|
||||
:command staged-command)
|
||||
|
||||
result
|
||||
(let [{:keys [event params transaction-hash]} result
|
||||
command' (assoc command :handler-data result)
|
||||
(let [{:keys [event params]} returned
|
||||
command' (assoc staged-command :handler-data returned)
|
||||
parameters' (assoc parameters :command command')]
|
||||
(if transaction-hash
|
||||
(dispatch [:wait-for-transaction transaction-hash parameters'])
|
||||
(if (:eth_sendTransaction context)
|
||||
(dispatch [:wait-for-transaction (:id staged-command) parameters'])
|
||||
(let [events (if (= console-chat-id chat-id)
|
||||
(merge regular-events console-events)
|
||||
regular-events)
|
||||
|
@ -46,13 +51,15 @@
|
|||
(assoc parameters' :handler #(handler params command'))
|
||||
parameters')]
|
||||
(dispatch [:prepare-command! parameters'']))))
|
||||
(not error)
|
||||
|
||||
(not (or error handler-error))
|
||||
(dispatch [:prepare-command! parameters])
|
||||
:else nil))
|
||||
|
||||
:else nil)))
|
||||
|
||||
(defn suggestions-handler!
|
||||
[db [{:keys [chat-id]} {:keys [result]}]]
|
||||
(let [{:keys [markup webViewUrl]} result
|
||||
(let [{:keys [markup webViewUrl]} (:returned result)
|
||||
hiccup (generate-hiccup markup)]
|
||||
(-> db
|
||||
(assoc-in [:suggestions chat-id] (generate-hiccup markup))
|
||||
|
@ -68,12 +75,13 @@
|
|||
|
||||
(defn command-preview
|
||||
[db [chat-id command-id {:keys [result]}]]
|
||||
(if result
|
||||
(let [result' (:returned result)]
|
||||
(if result'
|
||||
(let [path [:chats chat-id :staged-commands command-id]]
|
||||
(update-in db path assoc
|
||||
:preview (generate-hiccup result)
|
||||
:preview-string (str result)))
|
||||
db))
|
||||
:preview (generate-hiccup result')
|
||||
:preview-string (str result')))
|
||||
db)))
|
||||
|
||||
(defn print-error-message! [message]
|
||||
(fn [_ params]
|
||||
|
@ -81,7 +89,6 @@
|
|||
(show-popup "Error" (s/join "\n" [message params]))
|
||||
(log/debug message params))))
|
||||
|
||||
(reg-handler :init-render-command! init-render-command!)
|
||||
(reg-handler ::render-command render-command)
|
||||
|
||||
(reg-handler :command-handler!
|
||||
|
@ -93,6 +100,8 @@
|
|||
(after (print-error-message! "Error on param suggestions"))
|
||||
(after (fn [_ [{:keys [command]}]]
|
||||
(when (= :on-send (keyword (:suggestions-trigger command)))
|
||||
#_(when (:webViewUrl (:returned result))
|
||||
(dispatch [:set-soft-input-mode :pan]))
|
||||
(r/dismiss-keyboard!))))]
|
||||
suggestions-handler!)
|
||||
(reg-handler :suggestions-event! (u/side-effect! suggestions-events-handler!))
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
(defn complete-transaction
|
||||
[hash password callback]
|
||||
(log/debug :complete-transaction (boolean status) hash password)
|
||||
(when status
|
||||
(.completeTransaction status hash password callback)))
|
||||
|
||||
|
|
|
@ -102,6 +102,7 @@
|
|||
(register-handler :signal-event
|
||||
(u/side-effect!
|
||||
(fn [_ [_ event-str]]
|
||||
(log/debug :event-str event-str)
|
||||
(let [{:keys [type event]} (t/json->clj event-str)]
|
||||
(case type
|
||||
"transaction.queued" (dispatch [:transaction-queued event])
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
[status-im.chat.screen :refer [chat]]
|
||||
[status-im.accounts.login.screen :refer [login]]
|
||||
[status-im.accounts.screen :refer [accounts]]
|
||||
[status-im.transactions.screen :refer [confirm]]
|
||||
[status-im.chats-list.screen :refer [chats-list]]
|
||||
[status-im.new-group.screen :refer [new-group]]
|
||||
[status-im.participants.views.add :refer [new-participants]]
|
||||
|
@ -83,6 +84,7 @@
|
|||
:profile-photo-capture profile-photo-capture
|
||||
:accounts accounts
|
||||
:login login
|
||||
:confirm confirm
|
||||
:my-profile my-profile)]
|
||||
[component]))))})))
|
||||
|
||||
|
|
|
@ -6,45 +6,62 @@
|
|||
[status-im.utils.types :as t]
|
||||
[status-im.components.status :as status]
|
||||
cljsjs.web3
|
||||
[clojure.string :as s]))
|
||||
[clojure.string :as s]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
;; flow:
|
||||
;; :accept-transactions
|
||||
;; ↓
|
||||
;; :transaction-completed
|
||||
;; ↓
|
||||
;; ::remove-transaction && [:set :wrong-password? false] <- on error
|
||||
;; ::remove-transaction <- when transaction is
|
||||
;; not from the jail
|
||||
;; ::add-transactions-hash
|
||||
;; && ::check-completed-transaction!
|
||||
;; && :navigation-replace <- on success
|
||||
|
||||
|
||||
(defmethod nav/preload-data! :confirm
|
||||
[{:keys [transactions-queue] :as db} _]
|
||||
(assoc db :transactions transactions-queue))
|
||||
|
||||
(defn on-unlock
|
||||
[hashes password]
|
||||
;; todo: add message about wrong password
|
||||
(do
|
||||
;(dispatch [:set :wrong-password? false])
|
||||
(doseq [hash hashes]
|
||||
[ids password previous-view-id]
|
||||
(dispatch [:set :wrong-password? false])
|
||||
(doseq [id ids]
|
||||
(status/complete-transaction
|
||||
hash
|
||||
id
|
||||
password
|
||||
#(dispatch [:transaction-completed hash %])))
|
||||
(dispatch [:navigate-back])))
|
||||
;(dispatch [:set :wrong-password? true])
|
||||
|
||||
#(dispatch [:transaction-completed
|
||||
{:id id
|
||||
:response %
|
||||
:previous-view-id previous-view-id}]))))
|
||||
|
||||
(register-handler :accept-transactions
|
||||
(u/side-effect!
|
||||
(fn [{:keys [transactions current-account-id]} [_ password]]
|
||||
(let [hashes (keys transactions)]
|
||||
(on-unlock hashes password)))))
|
||||
(fn [{:keys [transactions navigation-stack]} [_ password]]
|
||||
(let [ids (keys transactions)
|
||||
previous-view-id (second navigation-stack)]
|
||||
(on-unlock ids password previous-view-id)))))
|
||||
|
||||
(register-handler :deny-transactions
|
||||
(u/side-effect!
|
||||
(fn [{:keys [transactions]}]
|
||||
(let [hashes (keys transactions)]
|
||||
(dispatch [::remove-pending-messages hashes])
|
||||
(dispatch [::remove-trqqansactions hashes])
|
||||
(let [transactions' (vals transactions)
|
||||
messages-ids (map :message-id transactions')
|
||||
ids (map :id transactions')]
|
||||
(dispatch [::remove-pending-messages messages-ids])
|
||||
(dispatch [::remove-transactions ids])
|
||||
(dispatch [:navigate-back])))))
|
||||
|
||||
(register-handler :deny-transaction
|
||||
(u/side-effect!
|
||||
(fn [_ [_ hash]]
|
||||
(dispatch [::remove-pending-message hash])
|
||||
(dispatch [::remove-transaction hash]))))
|
||||
(fn [{:keys [transactions]} [_ id]]
|
||||
(let [{:keys [message-id] :as transaction} (get transactions id)]
|
||||
(when transaction
|
||||
(dispatch [::remove-pending-message message-id])
|
||||
(dispatch [::remove-transaction id]))))))
|
||||
|
||||
(register-handler ::remove-transactions
|
||||
(fn [db [_ hashes]]
|
||||
|
@ -58,55 +75,101 @@
|
|||
(update :transactions dissoc hash)
|
||||
(update :transactions-queue dissoc hash))))
|
||||
|
||||
(defn mark-command-as-pending [db chat-id id]
|
||||
(let [path [:chats chat-id :staged-commands id]]
|
||||
(if (get-in db path)
|
||||
(update-in db path assoc :pending true)
|
||||
db)))
|
||||
|
||||
(register-handler :wait-for-transaction
|
||||
(fn [db [_ hash {:keys [chat-id command] :as params}]]
|
||||
(after (fn [_ [_ message-id]]
|
||||
(dispatch [::check-completed-transaction!
|
||||
{:message-id message-id}])))
|
||||
(fn [db [_ message-id {:keys [chat-id command] :as params}]]
|
||||
(let [id (:id command)]
|
||||
(-> db
|
||||
(update-in [:chats chat-id :staged-commands id] assoc :pending true)
|
||||
(assoc-in [:transaction-subscribers hash] params)))))
|
||||
(mark-command-as-pending chat-id id)
|
||||
(assoc-in [:transaction-subscribers message-id] params)))))
|
||||
|
||||
(defn remove-pending-message [db hash]
|
||||
(let [{:keys [chat-id command]} (get-in db [:transaction-subscribers hash])
|
||||
(defn remove-pending-message
|
||||
[{:keys [command->chat] :as db} message-id]
|
||||
(let [chat-id (get command->chat message-id)
|
||||
path [:chats chat-id :staged-commands]]
|
||||
(if chat-id
|
||||
(-> db
|
||||
(update :transaction-subscribers dissoc hash)
|
||||
(update-in path dissoc (:id command)))))
|
||||
(update :transaction-subscribers dissoc message-id)
|
||||
(update-in path dissoc message-id))
|
||||
db)))
|
||||
|
||||
(register-handler ::remove-pending-messages
|
||||
(fn [db [_ hashes]]
|
||||
(reduce remove-pending-message db hashes)))
|
||||
(fn [db [_ ids]]
|
||||
(log/debug :message-ids ids)
|
||||
(reduce remove-pending-message db ids)))
|
||||
|
||||
(register-handler ::remove-pending-message
|
||||
(fn [db [_ hash]]
|
||||
(remove-pending-message db hash)))
|
||||
(fn [db [_ message-id]]
|
||||
(remove-pending-message db message-id)))
|
||||
|
||||
(register-handler :transaction-queued
|
||||
(after #(dispatch [:navigate-to :confirm]))
|
||||
(fn [db [_ {:keys [hash args]}]]
|
||||
(fn [db [_ {:keys [id message_id args]}]]
|
||||
(let [{:keys [from to value]} args
|
||||
transaction {:hash hash
|
||||
transaction {:id id
|
||||
:from from
|
||||
:to to
|
||||
:value (.toDecimal js/Web3.prototype value)}]
|
||||
(assoc-in db [:transactions-queue hash] transaction))))
|
||||
:value (.toDecimal js/Web3.prototype value)
|
||||
:message-id message_id}]
|
||||
(assoc-in db [:transactions-queue id] transaction))))
|
||||
|
||||
(register-handler :transaction-completed
|
||||
(u/side-effect!
|
||||
(fn [db [_ old-hash result-str]]
|
||||
(let [{:keys [hash error]} (t/json->clj result-str)]
|
||||
;; todo: handle error
|
||||
(when hash
|
||||
(dispatch [::send-pending-message old-hash hash])
|
||||
(dispatch [::remove-transaction old-hash]))))))
|
||||
(fn [{:keys [transactions command->chat]} [_ {:keys [id response previous-view-id]}]]
|
||||
(let [{:keys [hash error] :as parsed-response} (t/json->clj response)
|
||||
{:keys [message-id]} (transactions id)]
|
||||
(log/debug :parsed-response parsed-response)
|
||||
(if (and error (string? error) (not (s/blank? error)))
|
||||
;; todo: revisit this
|
||||
;; currently transaction is removed after attempt
|
||||
;; to complete it with wrong password
|
||||
(do
|
||||
(dispatch [::remove-transaction id])
|
||||
(dispatch [:set :wrong-password? true])
|
||||
(when-let [chat-id (get command->chat message-id)]
|
||||
(dispatch [:clear-command chat-id message-id])))
|
||||
(if message-id
|
||||
(do (dispatch [::add-transactions-hash {:id id
|
||||
:hash hash
|
||||
:message-id message-id}])
|
||||
(dispatch [::check-completed-transaction!
|
||||
{:message-id message-id}])
|
||||
(dispatch [:navigation-replace previous-view-id]))
|
||||
(dispatch [::remove-transaction id])))))))
|
||||
|
||||
(register-handler ::add-transactions-hash
|
||||
(fn [db [_ {:keys [id hash message-id]}]]
|
||||
(-> db
|
||||
(assoc-in [:transactions id :hash] hash)
|
||||
(assoc-in [:message-id->transaction-id message-id] id))))
|
||||
|
||||
(register-handler ::send-pending-message
|
||||
(u/side-effect!
|
||||
(fn [{:keys [transaction-subscribers] :as db} [_ old-hash new-hash]]
|
||||
(when-let [params (transaction-subscribers old-hash)]
|
||||
(let [params' (assoc-in params [:handler-data :transaction-hash] new-hash)]
|
||||
(fn [{:keys [transaction-subscribers]} [_ message-id hash]]
|
||||
(when-let [params (transaction-subscribers message-id)]
|
||||
(let [params' (assoc-in params [:handler-data :transaction-hash] hash)]
|
||||
(dispatch [:prepare-command! params']))
|
||||
(dispatch [::remove-transaction-subscriber old-hash])))))
|
||||
(dispatch [::remove-transaction-subscriber message-id])))))
|
||||
|
||||
(register-handler ::remove-transaction-subscriber
|
||||
(fn [db [_ old-hash]]
|
||||
(update db :transaction-subscribers dissoc old-hash)))
|
||||
|
||||
(register-handler ::check-completed-transaction!
|
||||
(u/side-effect!
|
||||
(fn [{:keys [message-id->transaction-id transactions transaction-subscribers]}
|
||||
[_ {:keys [message-id]}]]
|
||||
(let [id (get message-id->transaction-id message-id)
|
||||
{:keys [hash]} (get transactions id)
|
||||
pending-message (get transaction-subscribers message-id)]
|
||||
(when (and pending-message id hash)
|
||||
(dispatch [::send-pending-message message-id hash])
|
||||
(dispatch [::remove-transaction id]))))))
|
||||
|
|
|
@ -57,6 +57,3 @@
|
|||
:value password
|
||||
:label (label :t/password)
|
||||
:on-change-text #(dispatch [:set-in [:confirm-transactions :password] %])}]]])
|
||||
|
||||
|
||||
;(re-frame.core/dispatch [:set :view-id :confirm])
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
[status-im.i18n :refer [label label-pluralize]]
|
||||
cljsjs.web3))
|
||||
|
||||
(defn title-bar [title hash]
|
||||
(defn title-bar [title id]
|
||||
[view st/title-bar
|
||||
[text {:style st/title-bar-text} title]
|
||||
[touchable-highlight {:style st/icon-close-container
|
||||
:on-press #(dispatch [:deny-transaction hash])}
|
||||
:on-press #(dispatch [:deny-transaction id])}
|
||||
[view [image {:source {:uri :icon_close_gray}
|
||||
:style st/icon-close}]]]])
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
|||
[view st/transaction-info-column-value
|
||||
[text {:style st/transaction-info-value} value]]]])
|
||||
|
||||
(defview transaction-page [{:keys [hash from to value] :as transaction}]
|
||||
(defview transaction-page [{:keys [id from to value] :as transaction}]
|
||||
[{:keys [name] :as contact} [:contact-by-address to]]
|
||||
(let [eth-value (.fromWei js/Web3.prototype value "ether")
|
||||
title (str eth-value " ETH to " name)
|
||||
|
@ -39,8 +39,8 @@
|
|||
[(label :t/recipient) name]
|
||||
[(label :t/value) (str eth-value " ETH")]]]
|
||||
[view {:style st/transaction-page
|
||||
:key hash}
|
||||
[title-bar title hash]
|
||||
:key id}
|
||||
[title-bar title id]
|
||||
[view st/scroll-view-container
|
||||
[scroll-view {:style st/scroll-view
|
||||
:contentContainerStyle st/scroll-view-content
|
||||
|
|
|
@ -46,8 +46,8 @@
|
|||
(let [diff (t/in-seconds (t/interval time (t/now)))]
|
||||
(if (< diff 60)
|
||||
(label :t/active-online)
|
||||
(let [unit (first (drop-while #(or (>= diff (:limit %))
|
||||
(not (:limit %)))
|
||||
(let [unit (first (drop-while #(and (>= diff (:limit %))
|
||||
(:limit %))
|
||||
units))]
|
||||
(-> (/ diff (:in-second unit))
|
||||
Math/floor
|
||||
|
|
Loading…
Reference in New Issue