parent
e220ecbb0a
commit
84828891a0
Binary file not shown.
After Width: | Height: | Size: 194 B |
Binary file not shown.
After Width: | Height: | Size: 301 B |
Binary file not shown.
After Width: | Height: | Size: 426 B |
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "tiny-warning.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "tiny-warning@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "tiny-warning@3x.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 194 B |
Binary file not shown.
After Width: | Height: | Size: 301 B |
Binary file not shown.
After Width: | Height: | Size: 426 B |
|
@ -10,7 +10,6 @@
|
|||
[status-im.i18n :as i18n]
|
||||
[status-im.mailserver.core :as mailserver]
|
||||
[status-im.transport.message.protocol :as transport.protocol]
|
||||
[status-im.tribute-to-talk.core :as tribute-to-talk]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.screens.navigation :as navigation]
|
||||
|
@ -227,8 +226,7 @@
|
|||
(when platform/desktop?
|
||||
(mark-messages-seen chat-id))
|
||||
(when (and (one-to-one-chat? cofx chat-id) (not (contact.db/contact-exists? db chat-id)))
|
||||
(contact.core/create-contact chat-id))
|
||||
(tribute-to-talk/check-tribute chat-id)))
|
||||
(contact.core/create-contact chat-id))))
|
||||
|
||||
(fx/defn navigate-to-chat
|
||||
"Takes coeffects map and chat-id, returns effects necessary for navigation and preloading data"
|
||||
|
@ -294,5 +292,4 @@
|
|||
[cofx identity]
|
||||
(fx/merge (assoc-in cofx [:db :contacts/identity] identity)
|
||||
(contact.core/create-contact identity)
|
||||
(tribute-to-talk/check-tribute identity)
|
||||
(navigation/navigate-to-cofx :profile nil)))
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
[status-im.transport.message.protocol :as protocol]
|
||||
[status-im.transport.message.transit :as transit]
|
||||
[status-im.transport.utils :as transport.utils]
|
||||
[status-im.tribute-to-talk.core :as tribute-to-talk]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.utils.clocks :as utils.clocks]
|
||||
[status-im.utils.datetime :as time]
|
||||
|
@ -58,11 +57,31 @@
|
|||
:body (str body-first-line (:text content))
|
||||
:prioritary? (not (chat-model/multi-user-chat? cofx chat-id))}))
|
||||
|
||||
(fx/defn rebuild-message-list
|
||||
[{:keys [db]} chat-id]
|
||||
{:db (assoc-in db [:chats chat-id :message-list]
|
||||
(message-list/add-many nil (vals (get-in db [:chats chat-id :messages]))))})
|
||||
|
||||
(fx/defn hide-message
|
||||
"Hide chat message, rebuild message-list"
|
||||
[{:keys [db] :as cofx} chat-id {:keys [seen message-id]}]
|
||||
(fx/merge cofx
|
||||
{:db (update-in db [:chats chat-id :messages] dissoc message-id)}
|
||||
#(when (not seen)
|
||||
(fx/merge %
|
||||
{:db (update-in db [:chats chat-id]
|
||||
update
|
||||
:unviewed-messages-count dec)}
|
||||
(data-store.messages/mark-messages-seen chat-id [message-id])))
|
||||
(rebuild-message-list chat-id)))
|
||||
|
||||
(fx/defn add-message
|
||||
[{:keys [db] :as cofx}
|
||||
{{:keys [chat-id message-id timestamp from] :as message} :message
|
||||
{{:keys [chat-id message-id replace timestamp from] :as message} :message
|
||||
:keys [current-chat?]}]
|
||||
(let [current-public-key (multiaccounts.model/current-public-key cofx)
|
||||
message-to-be-removed (when replace
|
||||
(get-in db [:chats chat-id :messages replace]))
|
||||
prepared-message (prepare-message message chat-id current-chat?)]
|
||||
(when (and platform/desktop?
|
||||
(not= from current-public-key)
|
||||
|
@ -71,20 +90,23 @@
|
|||
(let [{:keys [title body prioritary?]} (build-desktop-notification cofx message)]
|
||||
(.displayNotification react/desktop-notification title body prioritary?)))
|
||||
(fx/merge cofx
|
||||
{:db (cond->
|
||||
(-> db
|
||||
;; We should not be always adding to the list, as it does not make sense
|
||||
;; if the chat has not been initialized, but run into
|
||||
;; some troubles disabling it, so next time
|
||||
(update-in [:chats chat-id :messages] assoc message-id prepared-message)
|
||||
(update-in [:chats chat-id :message-list] message-list/add prepared-message))
|
||||
(and (not current-chat?)
|
||||
(not= from current-public-key))
|
||||
(update-in [:chats chat-id :loaded-unviewed-messages-ids]
|
||||
(fnil conj #{}) message-id))}
|
||||
(when message-to-be-removed
|
||||
(hide-message chat-id message-to-be-removed))
|
||||
(fn [{:keys [db]}]
|
||||
{:db (cond->
|
||||
(-> db
|
||||
;; We should not be always adding to the list, as it does not make sense
|
||||
;; if the chat has not been initialized, but run into
|
||||
;; some troubles disabling it, so next time
|
||||
(update-in [:chats chat-id :messages] assoc message-id prepared-message)
|
||||
(update-in [:chats chat-id :message-list] message-list/add prepared-message))
|
||||
|
||||
(and (not current-chat?)
|
||||
(not= from current-public-key))
|
||||
(update-in [:chats chat-id :loaded-unviewed-messages-ids]
|
||||
(fnil conj #{}) message-id))})
|
||||
(when (and platform/desktop?
|
||||
(not (system-message? prepared-message)))
|
||||
|
||||
(chat-model/update-dock-badge-label)))))
|
||||
|
||||
(fx/defn add-received-message
|
||||
|
@ -175,11 +197,6 @@
|
|||
:on-error #(log/error "failed to re-send message" %)}]}
|
||||
(update-message-status chat-id message-id :sending)))
|
||||
|
||||
(fx/defn rebuild-message-list
|
||||
[{:keys [db]} chat-id]
|
||||
{:db (assoc-in db [:chats chat-id :message-list]
|
||||
(message-list/add-many nil (vals (get-in db [:chats chat-id :messages]))))})
|
||||
|
||||
(fx/defn delete-message
|
||||
"Deletes chat message, rebuild message-list"
|
||||
[{:keys [db] :as cofx} chat-id message-id]
|
||||
|
@ -200,10 +217,7 @@
|
|||
|
||||
(fx/defn send-message
|
||||
[{:keys [db now] :as cofx} {:keys [chat-id] :as message}]
|
||||
(let [{:keys [chats]} db
|
||||
message-data (-> message
|
||||
(tribute-to-talk/add-transaction-hash db))]
|
||||
(protocol/send-chat-message cofx message-data)))
|
||||
(protocol/send-chat-message cofx message))
|
||||
|
||||
(fx/defn toggle-expand-message
|
||||
[{:keys [db]} chat-id message-id]
|
||||
|
|
|
@ -131,19 +131,15 @@
|
|||
(.prev iter)
|
||||
e))
|
||||
|
||||
(defn insert-message
|
||||
"Insert a message in the list, pull it's left and right messages, calculate
|
||||
its positional metadata, and update the left & right messages if necessary,
|
||||
this operation is O(logN) for insertion, and O(logN) for the updates, as
|
||||
we need to re-find (there's probably a better way)"
|
||||
[old-message-list {:keys [key] :as prepared-message}]
|
||||
(let [tree (.insert old-message-list prepared-message prepared-message)
|
||||
iter (.find tree prepared-message)
|
||||
(defn update-message
|
||||
"Update the message and siblings with positional info"
|
||||
[tree message]
|
||||
(let [iter (.find tree message)
|
||||
previous-message (when (.-hasPrev iter)
|
||||
(get-prev-element iter))
|
||||
next-message (when (.-hasNext iter)
|
||||
(get-next-element iter))
|
||||
message-with-pos-data (add-group-info prepared-message previous-message next-message)]
|
||||
message-with-pos-data (add-group-info message previous-message next-message)]
|
||||
(cond->
|
||||
(.update iter message-with-pos-data)
|
||||
|
||||
|
@ -156,6 +152,28 @@
|
|||
(-> (.find previous-message)
|
||||
(.update (update-previous-message message-with-pos-data previous-message))))))
|
||||
|
||||
(defn remove-message
|
||||
"Remove a message in the list"
|
||||
[tree prepared-message]
|
||||
(let [iter (.find tree prepared-message)]
|
||||
(if (not iter)
|
||||
tree
|
||||
(let [new-tree (.remove iter)
|
||||
next-message (when (.-hasNext iter)
|
||||
(get-next-element iter))]
|
||||
(if (not next-message)
|
||||
new-tree
|
||||
(update-message new-tree next-message))))))
|
||||
|
||||
(defn insert-message
|
||||
"Insert a message in the list, pull it's left and right messages, calculate
|
||||
its positional metadata, and update the left & right messages if necessary,
|
||||
this operation is O(logN) for insertion, and O(logN) for the updates, as
|
||||
we need to re-find (there's probably a better way)"
|
||||
[old-message-list prepared-message]
|
||||
(let [tree (.insert old-message-list prepared-message prepared-message)]
|
||||
(update-message tree prepared-message)))
|
||||
|
||||
(defn add [message-list message]
|
||||
(insert-message (or message-list (dependencies/rb-tree compare-fn))
|
||||
(prepare-message message)))
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
(ns status-im.commands.core
|
||||
(:require
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.ethereum.core :as ethereum]
|
||||
[status-im.ethereum.json-rpc :as json-rpc]
|
||||
[status-im.utils.fx :as fx]))
|
||||
|
||||
(fx/defn handle-prepare-accept-request-address-for-transaction
|
||||
{:events [::prepare-accept-request-address-for-transaction]}
|
||||
[{:keys [db]} message]
|
||||
{:db (assoc db
|
||||
:commands/select-account
|
||||
{:message message
|
||||
:from (ethereum/get-default-account (:multiaccount/accounts db))})})
|
||||
|
||||
(fx/defn set-selected-account
|
||||
{:events [::set-selected-account]}
|
||||
[{:keys [db]} _ account]
|
||||
{:db (-> (assoc-in db [:commands/select-account :from] account)
|
||||
(assoc :bottom-sheet/show? false))})
|
||||
|
||||
(fx/defn handle-accept-request-address-for-transaction
|
||||
{:events [::accept-request-address-for-transaction]}
|
||||
[{:keys [db]} message-id address]
|
||||
{:db (dissoc db :commands/select-account)
|
||||
::json-rpc/call [{:method "shhext_acceptRequestAddressForTransaction"
|
||||
:params [message-id address]
|
||||
:on-success #(re-frame/dispatch [:transport/message-sent % 1])}]})
|
||||
|
||||
(fx/defn handle-decline-request-address-for-transaction
|
||||
{:events [::decline-request-address-for-transaction]}
|
||||
[cofx message-id]
|
||||
{::json-rpc/call [{:method "shhext_declineRequestAddressForTransaction"
|
||||
:params [message-id]
|
||||
:on-success #(re-frame/dispatch [:transport/message-sent % 1])}]})
|
||||
|
||||
(fx/defn handle-decline-request-transaction
|
||||
{:events [::decline-request-transaction]}
|
||||
[cofx message-id]
|
||||
{::json-rpc/call [{:method "shhext_declineRequestTransaction"
|
||||
:params [message-id]
|
||||
:on-success #(re-frame/dispatch [:transport/message-sent % 1])}]})
|
|
@ -7,15 +7,24 @@
|
|||
|
||||
(def ms-in-bg-for-require-bioauth 5000)
|
||||
|
||||
(def content-type-text 1)
|
||||
(def content-type-sticker 2)
|
||||
(def content-type-status 3)
|
||||
(def content-type-emoji 4)
|
||||
(def ^:const content-type-text 1)
|
||||
(def ^:const content-type-sticker 2)
|
||||
(def ^:const content-type-status 3)
|
||||
(def ^:const content-type-emoji 4)
|
||||
(def ^:const content-type-command 5)
|
||||
|
||||
(def message-type-one-to-one 1)
|
||||
(def message-type-public-group 2)
|
||||
(def message-type-private-group 3)
|
||||
(def message-type-private-group-system-message 4)
|
||||
(def ^:const message-type-one-to-one 1)
|
||||
(def ^:const message-type-public-group 2)
|
||||
(def ^:const message-type-private-group 3)
|
||||
(def ^:const message-type-private-group-system-message 4)
|
||||
|
||||
(def ^:const command-state-request-address-for-transaction 1)
|
||||
(def ^:const command-state-request-address-for-transaction-declined 2)
|
||||
(def ^:const command-state-request-address-for-transaction-accepted 3)
|
||||
(def ^:const command-state-request-transaction 4)
|
||||
(def ^:const command-state-request-transaction-declined 5)
|
||||
(def ^:const command-state-transaction-pending 6)
|
||||
(def ^:const command-state-transaction-sent 7)
|
||||
|
||||
(def desktop-content-types
|
||||
#{content-type-text content-type-emoji content-type-status})
|
||||
|
|
|
@ -19,7 +19,10 @@
|
|||
(fx/defn load-contacts
|
||||
{:events [::contacts-loaded]}
|
||||
[{:keys [db] :as cofx} all-contacts]
|
||||
(let [contacts-list (map #(vector (:public-key %) %) all-contacts)
|
||||
(let [contacts-list (map #(vector (:public-key %) (if (empty? (:address %))
|
||||
(dissoc % :address)
|
||||
%))
|
||||
all-contacts)
|
||||
contacts (into {} contacts-list)
|
||||
tr-to-talk-enabled? (-> db tribute-to-talk/get-settings tribute-to-talk/enabled?)]
|
||||
(fx/merge cofx
|
||||
|
@ -123,12 +126,10 @@
|
|||
(cond-> {:public-key public-key
|
||||
:photo-path profile-image
|
||||
:name name
|
||||
:address (or address
|
||||
(:address contact)
|
||||
(ethereum/public-key->address public-key))
|
||||
:last-updated timestamp-ms
|
||||
:system-tags (conj (get contact :system-tags #{})
|
||||
:contact/request-received)})]
|
||||
:contact/request-received)}
|
||||
address (assoc :address address))]
|
||||
(upsert-contact cofx contact-props)))))
|
||||
|
||||
(fx/defn initialize-contacts [cofx]
|
||||
|
|
|
@ -27,10 +27,10 @@
|
|||
(spec/def :contact/tribute (spec/nilable int?))
|
||||
(spec/def :contact/tribute-transaction (spec/nilable string?))
|
||||
|
||||
(spec/def :contact/contact (spec/keys :req-un [:contact/address
|
||||
:contact/public-key
|
||||
(spec/def :contact/contact (spec/keys :req-un [:contact/public-key
|
||||
:contact/system-tags]
|
||||
:opt-un [:contact/name
|
||||
:contact/address
|
||||
:contact/photo-path
|
||||
:contact/last-online
|
||||
:contact/last-updated
|
||||
|
@ -66,7 +66,6 @@
|
|||
(let [alias (gfycat/generate-gfy public-key)]
|
||||
{:alias alias
|
||||
:name alias
|
||||
:address (ethereum/public-key->address public-key)
|
||||
:identicon (identicon/identicon public-key)
|
||||
:public-key public-key
|
||||
:system-tags #{}}))
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
(-> message
|
||||
(clojure.set/rename-keys {:id :message-id
|
||||
:whisperTimestamp :whisper-timestamp
|
||||
:commandParameters :command-parameters
|
||||
:messageType :message-type
|
||||
:localChatId :chat-id
|
||||
:contentType :content-type
|
||||
|
@ -31,6 +32,8 @@
|
|||
:outgoingStatus :outgoing-status})
|
||||
|
||||
(update :outgoing-status keyword)
|
||||
(update :command-parameters clojure.set/rename-keys {:transactionHash :transaction-hash
|
||||
:commandState :command-state})
|
||||
(assoc :content {:chat-id (:chatId message)
|
||||
:text (:text message)
|
||||
:sticker (:sticker message)
|
||||
|
|
|
@ -66,6 +66,13 @@
|
|||
"shhext_deleteChat" {}
|
||||
"shhext_saveContact" {}
|
||||
"shhext_verifyENSNames" {}
|
||||
"shhext_requestAddressForTransaction" {}
|
||||
"shhext_requestTransaction" {}
|
||||
"shhext_acceptRequestAddressForTransaction" {}
|
||||
"shhext_declineRequestAddressForTransaction" {}
|
||||
"shhext_declineRequestTransaction" {}
|
||||
"shhext_sendTransaction" {}
|
||||
"shhext_acceptRequestTransaction" {}
|
||||
"status_chats" {}
|
||||
"wallet_getTransfers" {}
|
||||
"wallet_getTokensBalances" {}
|
||||
|
|
|
@ -119,15 +119,17 @@
|
|||
:BrowsersConfig {:Enabled true}
|
||||
:PermissionsConfig {:Enabled true}
|
||||
:MailserversConfig {:Enabled true}
|
||||
:EnableNTPSync true
|
||||
:WhisperConfig {:Enabled true
|
||||
:LightClient true
|
||||
:MinimumPoW 0.001
|
||||
:EnableNTPSync true}
|
||||
:MinimumPoW 0.001}
|
||||
:ShhextConfig
|
||||
{:BackupDisabledDataDir (utils.platform/no-backup-directory)
|
||||
:InstallationID installation-id
|
||||
:MaxMessageDeliveryAttempts config/max-message-delivery-attempts
|
||||
:MailServerConfirmations config/mailserver-confirmations-enabled?
|
||||
:VerifyTransactionURL "https://mainnet.infura.io/v3/f315575765b14720b32382a61a89341a"
|
||||
:VerifyTransactionChainID 1
|
||||
:DataSyncEnabled true
|
||||
:PFSEnabled true}
|
||||
:RequireTopics (get-topics current-network)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
[re-frame.core :as re-frame]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.ethereum.abi-spec :as abi-spec]
|
||||
[status-im.ethereum.json-rpc :as json-rpc]
|
||||
[status-im.ethereum.core :as ethereum]
|
||||
[status-im.ethereum.eip55 :as eip55]
|
||||
[status-im.ethereum.tokens :as tokens]
|
||||
|
@ -81,7 +82,8 @@
|
|||
{:events [:signing.ui/sign-is-pressed]}
|
||||
[{{:signing/keys [sign tx] :as db} :db :as cofx}]
|
||||
(let [{:keys [in-progress? password]} sign
|
||||
{:keys [tx-obj gas gasPrice message]} tx]
|
||||
{:keys [tx-obj gas gasPrice message]} tx
|
||||
hashed-password (ethereum/sha3 (security/safe-unmask-data password))]
|
||||
(if message
|
||||
(sign-message cofx)
|
||||
(let [tx-obj-to-send (merge tx-obj
|
||||
|
@ -92,8 +94,8 @@
|
|||
(when-not in-progress?
|
||||
{:db (update db :signing/sign assoc :error nil :in-progress? true)
|
||||
:signing/send-transaction-fx {:tx-obj tx-obj-to-send
|
||||
:hashed-password (ethereum/sha3 (security/safe-unmask-data password))
|
||||
:cb #(re-frame/dispatch [:signing/transaction-completed % tx-obj-to-send])}})))))
|
||||
:hashed-password hashed-password
|
||||
:cb #(re-frame/dispatch [:signing/transaction-completed % tx-obj-to-send hashed-password])}})))))
|
||||
|
||||
(fx/defn prepare-unconfirmed-transaction
|
||||
[{:keys [db now]} hash {:keys [value gasPrice gas data to from]} symbol amount]
|
||||
|
@ -203,11 +205,46 @@
|
|||
(when (and (not in-progress?) (seq queue))
|
||||
(show-sign cofx))))
|
||||
|
||||
(fx/defn send-transaction-message
|
||||
{:events [::send-transaction-message]}
|
||||
[cofx chat-id transaction-hash signature]
|
||||
{::json-rpc/call [{:method "shhext_sendTransaction"
|
||||
:params [chat-id transaction-hash (:result (types/json->clj signature))]
|
||||
:on-success #(re-frame/dispatch [:transport/message-sent % 1])}]})
|
||||
|
||||
(fx/defn send-accept-request-transaction-message
|
||||
{:events [::send-accept-transaction-message]}
|
||||
[cofx message-id transaction-hash signature]
|
||||
{::json-rpc/call [{:method "shhext_acceptRequestTransaction"
|
||||
:params [transaction-hash message-id (:result (types/json->clj signature))]
|
||||
:on-success #(re-frame/dispatch [:transport/message-sent % 1])}]})
|
||||
|
||||
(fx/defn transaction-result
|
||||
[{:keys [db] :as cofx} result tx-obj]
|
||||
(let [{:keys [on-result symbol amount]} (get db :signing/tx)]
|
||||
(fx/merge cofx
|
||||
{:db (dissoc db :signing/tx :signing/in-progress? :signing/sign)
|
||||
{:db (dissoc db :signing/tx :signing/in-progress? :signing/sign)
|
||||
:signing/show-transaction-result nil}
|
||||
(prepare-unconfirmed-transaction result tx-obj symbol amount)
|
||||
(check-queue)
|
||||
#(when on-result
|
||||
{:dispatch (conj on-result result)}))))
|
||||
|
||||
(fx/defn command-transaction-result
|
||||
[{:keys [db] :as cofx} result hashed-password tx-obj]
|
||||
(let [{:keys [on-result symbol amount]} (get db :signing/tx)]
|
||||
(fx/merge cofx
|
||||
{:db (dissoc db :signing/tx :signing/in-progress? :signing/sign)
|
||||
:signing.fx/sign-message
|
||||
{:params {:data (str (get-in db [:multiaccount :public-key])
|
||||
(subs result 2))
|
||||
:password hashed-password
|
||||
:account (:from tx-obj)}
|
||||
:on-completed
|
||||
#(re-frame/dispatch
|
||||
(if (:message-id tx-obj)
|
||||
[::send-accept-transaction-message (:message-id tx-obj) result %]
|
||||
[::send-transaction-message (:chat-id tx-obj) result %]))}
|
||||
:signing/show-transaction-result nil}
|
||||
(prepare-unconfirmed-transaction result tx-obj symbol amount)
|
||||
(check-queue)
|
||||
|
@ -241,12 +278,14 @@
|
|||
(fx/defn transaction-completed
|
||||
{:events [:signing/transaction-completed]
|
||||
:interceptors [(re-frame/inject-cofx :random-id-generator)]}
|
||||
[cofx response tx-obj]
|
||||
[cofx response tx-obj hashed-password]
|
||||
(let [cofx-in-progress-false (assoc-in cofx [:db :signing/sign :in-progress?] false)
|
||||
{:keys [result error]} (types/json->clj response)]
|
||||
(if error
|
||||
(transaction-error cofx-in-progress-false error)
|
||||
(transaction-result cofx-in-progress-false result tx-obj))))
|
||||
(if (:command? tx-obj)
|
||||
(command-transaction-result cofx-in-progress-false result hashed-password tx-obj)
|
||||
(transaction-result cofx-in-progress-false result tx-obj)))))
|
||||
|
||||
(fx/defn discard
|
||||
"Discrad transaction signing"
|
||||
|
|
|
@ -166,6 +166,9 @@
|
|||
(reg-root-key-sub :wallet/custom-token-screen :wallet/custom-token-screen)
|
||||
(reg-root-key-sub :wallet/prepare-transaction :wallet/prepare-transaction)
|
||||
|
||||
;;commands
|
||||
(reg-root-key-sub :commands/select-account :commands/select-account)
|
||||
|
||||
;;ethereum
|
||||
(reg-root-key-sub :ethereum/current-block :ethereum/current-block)
|
||||
|
||||
|
@ -599,54 +602,55 @@
|
|||
(fn [[contacts chats multiaccount]]
|
||||
(chat.db/active-chats contacts chats multiaccount)))
|
||||
|
||||
(defn enrich-current-one-to-one-chat
|
||||
[{:keys [contact] :as current-chat} my-public-key ttt-settings
|
||||
chain-keyword prices currency]
|
||||
(let [{:keys [tribute-to-talk]} contact
|
||||
{:keys [disabled? snt-amount message]} tribute-to-talk
|
||||
whitelisted-by? (whitelist/whitelisted-by? contact)
|
||||
loading? (and (not whitelisted-by?)
|
||||
(not tribute-to-talk))
|
||||
show-input? (or whitelisted-by?
|
||||
disabled?)
|
||||
token (case chain-keyword
|
||||
:mainnet :SNT
|
||||
:STT)
|
||||
tribute-status (if loading?
|
||||
:loading
|
||||
(tribute-to-talk.db/tribute-status contact))
|
||||
tribute-label (tribute-to-talk.db/status-label tribute-status snt-amount)]
|
||||
;; TODO: this is no useful without tribute to talk
|
||||
#_(defn enrich-current-one-to-one-chat
|
||||
[{:keys [contact] :as current-chat} my-public-key ttt-settings
|
||||
chain-keyword prices currency]
|
||||
(let [{:keys [tribute-to-talk]} contact
|
||||
{:keys [disabled? snt-amount message]} tribute-to-talk
|
||||
whitelisted-by? (whitelist/whitelisted-by? contact)
|
||||
loading? (and (not whitelisted-by?)
|
||||
(not tribute-to-talk))
|
||||
show-input? (or whitelisted-by?
|
||||
disabled?)
|
||||
token (case chain-keyword
|
||||
:mainnet :SNT
|
||||
:STT)
|
||||
tribute-status (if loading?
|
||||
:loading
|
||||
(tribute-to-talk.db/tribute-status contact))
|
||||
tribute-label (tribute-to-talk.db/status-label tribute-status snt-amount)]
|
||||
|
||||
(cond-> (assoc current-chat
|
||||
:tribute-to-talk/tribute-status tribute-status
|
||||
:tribute-to-talk/tribute-label tribute-label)
|
||||
(cond-> (assoc current-chat
|
||||
:tribute-to-talk/tribute-status tribute-status
|
||||
:tribute-to-talk/tribute-label tribute-label)
|
||||
|
||||
(#{:required :pending :paid} tribute-status)
|
||||
(assoc :tribute-to-talk/snt-amount
|
||||
(tribute-to-talk.db/from-wei snt-amount)
|
||||
:tribute-to-talk/message
|
||||
message
|
||||
:tribute-to-talk/fiat-amount (if snt-amount
|
||||
(money/fiat-amount-value
|
||||
snt-amount
|
||||
token
|
||||
(-> currency :code keyword)
|
||||
prices)
|
||||
"0")
|
||||
:tribute-to-talk/fiat-currency (:code currency)
|
||||
:tribute-to-talk/token (str " " (name token)))
|
||||
(#{:required :pending :paid} tribute-status)
|
||||
(assoc :tribute-to-talk/snt-amount
|
||||
(tribute-to-talk.db/from-wei snt-amount)
|
||||
:tribute-to-talk/message
|
||||
message
|
||||
:tribute-to-talk/fiat-amount (if snt-amount
|
||||
(money/fiat-amount-value
|
||||
snt-amount
|
||||
token
|
||||
(-> currency :code keyword)
|
||||
prices)
|
||||
"0")
|
||||
:tribute-to-talk/fiat-currency (:code currency)
|
||||
:tribute-to-talk/token (str " " (name token)))
|
||||
|
||||
(tribute-to-talk.db/enabled? ttt-settings)
|
||||
(assoc :tribute-to-talk/received? (tribute-to-talk.db/tribute-received?
|
||||
contact))
|
||||
(tribute-to-talk.db/enabled? ttt-settings)
|
||||
(assoc :tribute-to-talk/received? (tribute-to-talk.db/tribute-received?
|
||||
contact))
|
||||
|
||||
(= tribute-status :required)
|
||||
(assoc :tribute-to-talk/on-share-my-profile
|
||||
#(re-frame/dispatch
|
||||
[:profile/share-profile-link my-public-key]))
|
||||
(= tribute-status :required)
|
||||
(assoc :tribute-to-talk/on-share-my-profile
|
||||
#(re-frame/dispatch
|
||||
[:profile/share-profile-link my-public-key]))
|
||||
|
||||
show-input?
|
||||
(assoc :show-input? true))))
|
||||
show-input?
|
||||
(assoc :show-input? true))))
|
||||
|
||||
(defn enrich-current-chat
|
||||
[{:keys [messages chat-id might-have-join-time-messages?] :as chat}
|
||||
|
@ -683,16 +687,8 @@
|
|||
:<- [:mailserver/ranges]
|
||||
:<- [:chats/content-layout-height]
|
||||
:<- [:chats/current-chat-ui-prop :input-height]
|
||||
:<- [:tribute-to-talk/settings]
|
||||
:<- [:ethereum/chain-keyword]
|
||||
:<- [:prices]
|
||||
:<- [:wallet/currency]
|
||||
(fn [[{:keys [group-chat
|
||||
chat-id
|
||||
contact
|
||||
messages]
|
||||
:as current-chat} my-public-key ranges height
|
||||
input-height ttt-settings chain-keyword prices currency]]
|
||||
(fn [[{:keys [group-chat chat-id contact messages] :as current-chat}
|
||||
my-public-key ranges height input-height]]
|
||||
(when current-chat
|
||||
(cond-> (enrich-current-chat current-chat ranges height input-height)
|
||||
(empty? messages)
|
||||
|
@ -707,8 +703,14 @@
|
|||
(assoc :show-input? true)
|
||||
|
||||
(not group-chat)
|
||||
(enrich-current-one-to-one-chat my-public-key ttt-settings
|
||||
chain-keyword prices currency)))))
|
||||
(assoc :show-input? true)))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:current-chat/one-to-one-chat?
|
||||
:<- [:chats/current-raw-chat]
|
||||
(fn [current-chat]
|
||||
(not (or (chat.models/group-chat? current-chat)
|
||||
(chat.models/public-chat? current-chat)))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/current-chat-message
|
||||
|
@ -1124,6 +1126,13 @@
|
|||
"0"))
|
||||
"...")))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:wallet/chain-tokens
|
||||
:<- [:wallet/all-tokens]
|
||||
:<- [:ethereum/chain-keyword]
|
||||
(fn [[all-tokens chain]]
|
||||
(get all-tokens chain)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:wallet/sorted-chain-tokens
|
||||
:<- [:wallet/all-tokens]
|
||||
|
@ -1235,6 +1244,21 @@
|
|||
|
||||
;;WALLET TRANSACTIONS ==================================================================================================
|
||||
|
||||
(re-frame/reg-sub
|
||||
:wallet/accounts
|
||||
:<- [:wallet]
|
||||
(fn [wallet]
|
||||
(get wallet :accounts)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:wallet/account-by-transaction-hash
|
||||
:<- [:wallet/accounts]
|
||||
(fn [accounts [_ hash]]
|
||||
(some (fn [[address account]]
|
||||
(when-let [transaction (get-in account [:transactions hash])]
|
||||
(assoc transaction :address address)))
|
||||
accounts)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:wallet/transactions
|
||||
:<- [:wallet]
|
||||
|
@ -2038,6 +2062,32 @@
|
|||
(not (nil? amount))
|
||||
(not offline?))))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:wallet.request/prepare-transaction-with-balance
|
||||
:<- [:wallet/prepare-transaction]
|
||||
:<- [:wallet]
|
||||
:<- [:offline?]
|
||||
:<- [:wallet/all-tokens]
|
||||
:<- [:ethereum/chain-keyword]
|
||||
(fn [[{:keys [symbol from to amount-text] :as transaction}
|
||||
wallet offline? all-tokens chain]]
|
||||
(let [balance (get-in wallet [:accounts (:address from) :balance])
|
||||
{:keys [decimals] :as token} (tokens/asset-for all-tokens chain symbol)
|
||||
{:keys [value error]} (wallet.db/parse-amount amount-text decimals)
|
||||
amount (money/formatted->internal value symbol decimals)
|
||||
{:keys [amount-error] :as transaction-new}
|
||||
(assoc transaction
|
||||
:amount-error error)]
|
||||
(assoc transaction-new
|
||||
:amount amount
|
||||
:balance balance
|
||||
:token (assoc token :amount (get balance (:symbol token)))
|
||||
:sign-enabled? (and to
|
||||
from
|
||||
(nil? amount-error)
|
||||
(not (nil? amount))
|
||||
(not offline?))))))
|
||||
|
||||
;; NETWORK SETTINGS
|
||||
|
||||
(defn- filter-networks [network-type]
|
||||
|
|
|
@ -64,4 +64,4 @@
|
|||
|
||||
(views/defview animated-bottom-panel [val signing-view]
|
||||
(views/letsubs [{window-height :height} [:dimensions/window]]
|
||||
[bottom-panel (when val (select-keys val [:from :contact :amount :token :approve? :message])) signing-view window-height]))
|
||||
[bottom-panel (when val (select-keys val [:from :contact :amount :token :approve? :message])) signing-view window-height]))
|
||||
|
|
|
@ -54,7 +54,6 @@
|
|||
:caption {:font-size 12}
|
||||
|
||||
:timestamp {:font-size 10
|
||||
:letter-spacing 1
|
||||
:text-transform :uppercase}})
|
||||
|
||||
(defn get-style
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
:height panel-height
|
||||
:transform [{:translateY bottom-anim-value}]
|
||||
:opacity alpha-value}}
|
||||
[react/view
|
||||
[react/view {:style {:flex-direction :row}}
|
||||
[react/touchable-highlight
|
||||
{:on-press #(re-frame/dispatch [:wallet/prepare-transaction-from-chat])}
|
||||
[react/view {:width 128 :height 128 :justify-content :space-between
|
||||
|
@ -47,13 +47,12 @@
|
|||
:justify-content :center}
|
||||
[icons/icon :main-icons/send {:color colors/white}]]
|
||||
[react/text {:typography :medium} (i18n/label :t/send-transaction)]]]
|
||||
;;TODO not implemented yet
|
||||
#_[react/touchable-highlight
|
||||
{:on-press #(re-frame/dispatch [:wallet/prepare-transaction-from-chat])}
|
||||
[react/view {:width 128 :height 128 :justify-content :space-between
|
||||
:padding-horizontal 10 :padding-vertical 12 :margin-top 8
|
||||
:background-color (colors/alpha colors/orange 0.2) :border-radius 16 :margin-left 8}
|
||||
[react/view {:background-color colors/orange :width 40 :height 40 :border-radius 20 :align-items :center
|
||||
:justify-content :center}
|
||||
[icons/icon :main-icons/receive {:color colors/white}]]
|
||||
[react/text {:typography :medium} (i18n/label :t/request-transaction)]]]]]))
|
||||
[react/touchable-highlight
|
||||
{:on-press #(re-frame/dispatch [:wallet/prepare-request-transaction-from-chat])}
|
||||
[react/view {:width 128 :height 128 :justify-content :space-between
|
||||
:padding-horizontal 10 :padding-vertical 12
|
||||
:background-color (colors/alpha colors/orange 0.2) :border-radius 16 :margin-left 8}
|
||||
[react/view {:background-color colors/orange :width 40 :height 40 :border-radius 20 :align-items :center
|
||||
:justify-content :center}
|
||||
[icons/icon :main-icons/receive {:color colors/white}]]
|
||||
[react/text {:typography :medium} (i18n/label :t/request-transaction)]]]]]))
|
||||
|
|
|
@ -155,6 +155,7 @@
|
|||
input-text [:chats/current-chat-input-text]
|
||||
result-box [:chats/current-chat-ui-prop :result-box]
|
||||
input-bottom-sheet [:chats/current-chat-ui-prop :input-bottom-sheet]
|
||||
one-to-one-chat? [:current-chat/one-to-one-chat?]
|
||||
state-text (reagent/atom "")]
|
||||
{:component-will-unmount #(when platform/desktop?
|
||||
(re-frame/dispatch [:chat.ui/set-chat-input-text @state-text]))
|
||||
|
@ -176,7 +177,7 @@
|
|||
[input-view {:single-line-input? single-line-input? :set-text set-text :state-text state-text}]
|
||||
(when (and input-text-empty? mainnet?)
|
||||
[stickers/button (= :stickers input-bottom-sheet)])
|
||||
(when (and input-text-empty?) ;;TODO show only for 1-1 chats?
|
||||
(when (and one-to-one-chat? input-text-empty? mainnet?)
|
||||
[extensions/button (= :extensions input-bottom-sheet)])
|
||||
(when-not input-text-empty?
|
||||
(if platform/desktop?
|
||||
|
|
|
@ -1,15 +1,20 @@
|
|||
(ns status-im.ui.screens.chat.message.message
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.commands.core :as commands]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.utils.http :as http]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ethereum.eip55 :as eip55]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.utils.security :as security]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.list-selection :as list-selection]
|
||||
[status-im.ui.components.popup-menu.views :as desktop.pop-up]
|
||||
[status-im.ui.components.chat-icon.screen :as chat-icon]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.utils.money :as money]
|
||||
[status-im.ethereum.transactions.core :as transactions]
|
||||
[status-im.ui.screens.chat.message.sheets :as sheets]
|
||||
[status-im.ui.screens.chat.photos :as photos]
|
||||
[status-im.ui.screens.chat.styles.message.message :as style]
|
||||
|
@ -201,6 +206,244 @@
|
|||
[react/image {:style {:margin 10 :width 140 :height 140}
|
||||
:source {:uri (contenthash/url (-> content :sticker :hash))}}]])
|
||||
|
||||
(defn- final-status? [command-state]
|
||||
(or (= command-state constants/command-state-request-address-for-transaction-declined)
|
||||
(= command-state constants/command-state-request-transaction-declined)
|
||||
(= command-state constants/command-state-transaction-sent)))
|
||||
|
||||
(defn- command-pending-status
|
||||
[command-state direction to transaction-type]
|
||||
[react/view {:style {:flex-direction :row
|
||||
:height 28
|
||||
:align-items :center
|
||||
:border-width 1
|
||||
:border-color colors/gray-lighter
|
||||
:border-radius 16
|
||||
:padding-horizontal 8
|
||||
:margin-right 12
|
||||
:margin-bottom 2}}
|
||||
[vector-icons/icon :tiny-icons/tiny-pending
|
||||
{:width 16
|
||||
:height 16
|
||||
:color colors/gray
|
||||
:container-style {:margin-right 6}}]
|
||||
[react/text {:style {:color colors/gray
|
||||
:font-weight "500"
|
||||
:line-height 16
|
||||
:margin-right 4
|
||||
:font-size 13}}
|
||||
(if (and (or (= command-state constants/command-state-request-transaction)
|
||||
(= command-state constants/command-state-request-address-for-transaction-accepted))
|
||||
(= direction :incoming))
|
||||
(str (i18n/label :t/shared) " '" (:name @(re-frame/subscribe [:account-by-address to])) "'")
|
||||
(i18n/label (cond
|
||||
(= command-state constants/command-state-transaction-pending)
|
||||
:t/status-pending
|
||||
(= command-state constants/command-state-request-address-for-transaction)
|
||||
:t/address-requested
|
||||
(= command-state constants/command-state-request-address-for-transaction-accepted)
|
||||
:t/address-request-accepted
|
||||
(= command-state constants/command-state-transaction-sent)
|
||||
(case transaction-type
|
||||
:pending :t/status-pending
|
||||
:failed :t/transaction-failed
|
||||
:t/status-confirmed)
|
||||
(= command-state constants/command-state-request-transaction)
|
||||
:t/address-received)))]])
|
||||
|
||||
(defn- command-final-status
|
||||
[command-state direction transaction-type]
|
||||
[react/view {:style {:flex-direction :row
|
||||
:height 28
|
||||
:align-items :center
|
||||
:border-width 1
|
||||
:border-color colors/gray-lighter
|
||||
:border-radius 16
|
||||
:padding-horizontal 8
|
||||
:margin-right 12
|
||||
:margin-bottom 2}}
|
||||
(if (or (= command-state constants/command-state-request-address-for-transaction-declined)
|
||||
(= command-state constants/command-state-request-transaction-declined)
|
||||
(= :failed transaction-type))
|
||||
[vector-icons/icon :tiny-icons/tiny-warning
|
||||
{:width 16
|
||||
:height 16
|
||||
:container-style {:margin-right 6}}]
|
||||
(if (= :pending transaction-type)
|
||||
[vector-icons/icon :tiny-icons/tiny-pending
|
||||
{:color colors/gray
|
||||
:width 16
|
||||
:height 16
|
||||
:container-style {:margin-right 6}}]
|
||||
[vector-icons/icon :tiny-icons/tiny-check
|
||||
{:width 16
|
||||
:height 16
|
||||
:container-style {:margin-right 6}}]))
|
||||
[react/text {:style (merge {:margin-right 4
|
||||
:line-height 16
|
||||
:font-size 13}
|
||||
(if (= transaction-type :pending)
|
||||
{:color colors/gray}
|
||||
{:font-weight "500"}))}
|
||||
(i18n/label (if (or (= command-state constants/command-state-request-address-for-transaction-declined)
|
||||
(= command-state constants/command-state-request-transaction-declined))
|
||||
:t/transaction-declined
|
||||
(case direction
|
||||
:outgoing (case transaction-type
|
||||
:pending :t/status-pending
|
||||
:failed :t/transaction-failed
|
||||
:t/status-confirmed)
|
||||
:incoming :t/status-confirmed)))]])
|
||||
|
||||
(defn- command-status-and-timestamp
|
||||
[command-state direction to timestamp-str transaction-type]
|
||||
[react/view {:style {:flex-direction :row
|
||||
:align-items :flex-end
|
||||
:justify-content :space-between}}
|
||||
(if (final-status? command-state)
|
||||
[command-final-status command-state direction transaction-type]
|
||||
[command-pending-status command-state direction to transaction-type])
|
||||
[react/text {:style {:font-size 10
|
||||
:line-height 12
|
||||
:text-align-vertical :bottom
|
||||
:color colors/gray}}
|
||||
timestamp-str]])
|
||||
|
||||
(defn- command-actions
|
||||
[accept-label on-accept on-decline]
|
||||
[react/view
|
||||
[react/touchable-highlight
|
||||
{:on-press #(do (react/dismiss-keyboard!)
|
||||
(on-accept))
|
||||
:style {:border-color colors/gray-lighter
|
||||
:border-top-width 1
|
||||
:margin-top 8
|
||||
:margin-horizontal -12
|
||||
:padding-horizontal 15
|
||||
:padding-vertical 10}}
|
||||
[react/text {:style {:text-align :center
|
||||
:color colors/blue
|
||||
:font-weight "500"
|
||||
:font-size 15
|
||||
:line-height 22}}
|
||||
(i18n/label accept-label)]]
|
||||
(when on-decline
|
||||
[react/touchable-highlight
|
||||
{:on-press on-decline
|
||||
:style {:border-color colors/gray-lighter
|
||||
:border-top-width 1
|
||||
:margin-horizontal -12
|
||||
:padding-top 10}}
|
||||
[react/text {:style {:text-align :center
|
||||
:color colors/blue
|
||||
:font-size 15
|
||||
:line-height 22}}
|
||||
(i18n/label :t/decline)]])])
|
||||
|
||||
(defn- command-transaction-info
|
||||
[contract value]
|
||||
(let [{:keys [symbol icon decimals color] :as token}
|
||||
(if (seq contract)
|
||||
(get @(re-frame/subscribe [:wallet/chain-tokens])
|
||||
contract
|
||||
transactions/default-erc20-token)
|
||||
@(re-frame/subscribe [:ethereum/native-currency]))
|
||||
amount (money/internal->formatted value symbol decimals)
|
||||
{:keys [code] :as currency}
|
||||
@(re-frame/subscribe [:wallet/currency])
|
||||
prices @(re-frame/subscribe [:prices])
|
||||
amount-fiat
|
||||
(money/fiat-amount-value amount symbol (keyword code) prices)]
|
||||
[react/view {:style {:flex-direction :row
|
||||
:margin-top 8
|
||||
:margin-bottom 12}}
|
||||
(if icon
|
||||
[react/image (-> icon
|
||||
(update :source #(%))
|
||||
(assoc-in [:style :height] 24)
|
||||
(assoc-in [:style :width] 24))]
|
||||
[react/view {:style {:margin-right 14
|
||||
:padding-vertical 2
|
||||
:justify-content :flex-start
|
||||
:max-width 40
|
||||
:align-items :center
|
||||
:align-self :stretch}}
|
||||
[chat-icon/custom-icon-view-list (:name token) color 24]])
|
||||
[react/view {:style {:margin-left 6}}
|
||||
[react/text {:style {:margin-bottom 2
|
||||
:font-size 20
|
||||
:line-height 24}}
|
||||
(str amount " " (name symbol))]
|
||||
[react/text {:style {:font-size 12
|
||||
:line-height 16
|
||||
:color colors/gray}}
|
||||
(str amount-fiat " " code)]]]))
|
||||
|
||||
(defn calculate-direction [outgoing command-state]
|
||||
(case command-state
|
||||
(constants/command-state-request-address-for-transaction-accepted
|
||||
constants/command-state-request-address-for-transaction-declined
|
||||
constants/command-state-request-transaction)
|
||||
(if outgoing :incoming :outgoing)
|
||||
(if outgoing :outgoing :incoming)))
|
||||
|
||||
(defmethod message-content constants/content-type-command
|
||||
[wrapper {:keys [message-id
|
||||
chat-id
|
||||
outgoing
|
||||
command-parameters
|
||||
timestamp-str] :as message}]
|
||||
(let [{:keys [contract value address command-state transaction-hash]} command-parameters
|
||||
direction (calculate-direction outgoing command-state)
|
||||
transaction (when transaction-hash
|
||||
@(re-frame/subscribe
|
||||
[:wallet/account-by-transaction-hash
|
||||
transaction-hash]))]
|
||||
[wrapper (assoc message :outgoing (= direction :outgoing))
|
||||
[react/touchable-highlight
|
||||
{:on-press #(when (:address transaction)
|
||||
(re-frame/dispatch [:wallet.ui/show-transaction-details
|
||||
transaction-hash (:address transaction)]))}
|
||||
[react/view {:padding-horizontal 12
|
||||
:padding-bottom 10
|
||||
:padding-top 10
|
||||
:margin-top 4
|
||||
:border-width 1
|
||||
:border-color colors/gray-lighter
|
||||
:border-radius 16
|
||||
(case direction
|
||||
:outgoing :border-bottom-right-radius
|
||||
:incoming :border-bottom-left-radius) 4
|
||||
:background-color :white}
|
||||
[react/text {:style {:font-size 13
|
||||
:line-height 18
|
||||
:font-weight "500"
|
||||
:color colors/gray}}
|
||||
(case direction
|
||||
:outgoing (str "↑ " (i18n/label :t/outgoing-transaction))
|
||||
:incoming (str "↓ " (i18n/label :t/incoming-transaction)))]
|
||||
[command-transaction-info contract value]
|
||||
[command-status-and-timestamp
|
||||
command-state direction address timestamp-str (:type transaction)]
|
||||
(when (not outgoing)
|
||||
(cond
|
||||
(= command-state constants/command-state-request-transaction)
|
||||
[command-actions
|
||||
:t/sign-and-send
|
||||
#(re-frame/dispatch [:wallet.ui/accept-request-transaction-button-clicked-from-command chat-id command-parameters])
|
||||
#(re-frame/dispatch [::commands/decline-request-transaction message-id])]
|
||||
|
||||
(= command-state constants/command-state-request-address-for-transaction-accepted)
|
||||
[command-actions
|
||||
:t/sign-and-send
|
||||
#(re-frame/dispatch [:wallet.ui/accept-request-transaction-button-clicked-from-command chat-id command-parameters])]
|
||||
|
||||
(= command-state constants/command-state-request-address-for-transaction)
|
||||
[command-actions
|
||||
:t/accept-and-share-address
|
||||
#(re-frame/dispatch [::commands/prepare-accept-request-address-for-transaction message])
|
||||
#(re-frame/dispatch [::commands/decline-request-address-for-transaction message-id])]))]]]))
|
||||
|
||||
(defmethod message-content :default
|
||||
[wrapper {:keys [content-type] :as message}]
|
||||
[wrapper message
|
||||
|
@ -215,14 +458,16 @@
|
|||
(defn message-not-sent-text
|
||||
[chat-id message-id]
|
||||
[react/touchable-highlight
|
||||
{:on-press (fn [] (if platform/desktop?
|
||||
(desktop.pop-up/show-desktop-menu
|
||||
(desktop.pop-up/get-message-menu-items chat-id message-id))
|
||||
(do
|
||||
(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||
{:content (sheets/options chat-id message-id)
|
||||
:content-height 200}])
|
||||
(react/dismiss-keyboard!))))}
|
||||
{:on-press
|
||||
(fn [] (if platform/desktop?
|
||||
(desktop.pop-up/show-desktop-menu
|
||||
(desktop.pop-up/get-message-menu-items chat-id message-id))
|
||||
(do
|
||||
(re-frame/dispatch
|
||||
[:bottom-sheet/show-sheet
|
||||
{:content (sheets/options chat-id message-id)
|
||||
:content-height 200}])
|
||||
(react/dismiss-keyboard!))))}
|
||||
[react/view style/not-sent-view
|
||||
[react/text {:style style/not-sent-text}
|
||||
(i18n/label (if platform/desktop?
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
[re-frame.core :as re-frame]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.ui.screens.wallet.send.views :as wallet.send]
|
||||
[status-im.ui.screens.mobile-network-settings.view :as mobile-network-settings]
|
||||
[status-im.ui.screens.keycard.views :as keycard]
|
||||
[status-im.ui.screens.home.sheet.views :as home.sheet]
|
||||
|
@ -170,6 +169,8 @@
|
|||
:persistNavigationState (when js/goog.DEBUG persist-state)
|
||||
:loadNavigationState (when js/goog.DEBUG load-state)}]
|
||||
[wallet/prepare-transaction]
|
||||
[wallet/request-transaction]
|
||||
[wallet/select-account]
|
||||
[signing/signing]
|
||||
[bottom-sheet]
|
||||
[popover/popover]]]))})))
|
||||
|
|
|
@ -19,19 +19,19 @@
|
|||
(:code currency)
|
||||
#(re-frame/dispatch [:wallet.send/set-symbol (:symbol %)]))}]))
|
||||
|
||||
(defn render-account [field]
|
||||
(defn render-account [field event]
|
||||
(fn [account]
|
||||
[list-item/list-item
|
||||
{:icon [chat-icon/custom-icon-view-list (:name account) (:color account)]
|
||||
:title (:name account)
|
||||
:on-press #(re-frame/dispatch [:wallet.send/set-field field account])}]))
|
||||
:on-press #(re-frame/dispatch [event field account])}]))
|
||||
|
||||
(views/defview accounts-list [field]
|
||||
(views/defview accounts-list [field event]
|
||||
(views/letsubs [accounts [:multiaccount/accounts]
|
||||
accounts-whithout-watch [:accounts-without-watch-only]]
|
||||
[list/flat-list {:data (if (= :to field) accounts accounts-whithout-watch)
|
||||
:key-fn :address
|
||||
:render-fn (render-account field)}]))
|
||||
:render-fn (render-account field event)}]))
|
||||
|
||||
(defn- request-camera-permissions []
|
||||
(let [options {:handler :wallet.send/qr-scanner-result
|
||||
|
@ -50,7 +50,7 @@
|
|||
(defn show-accounts-list []
|
||||
(re-frame/dispatch [:bottom-sheet/hide-sheet])
|
||||
(js/setTimeout #(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||
{:content (fn [] [accounts-list :to])
|
||||
{:content (fn [] [accounts-list :to :wallet.send/set-field])
|
||||
:content-height 300}]) 400))
|
||||
|
||||
(defn choose-recipient []
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
(:require-macros [status-im.utils.views :refer [defview letsubs] :as views])
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.commands.core :as commands]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.toolbar :as toolbar]
|
||||
[status-im.ui.screens.wallet.send.styles :as styles]
|
||||
|
@ -19,24 +20,24 @@
|
|||
[status-im.utils.utils :as utils]
|
||||
[status-im.ui.components.button :as button]))
|
||||
|
||||
(defn header [small-screen?]
|
||||
(defn header [{:keys [label small-screen? on-cancel]}]
|
||||
[react/view (styles/header small-screen?)
|
||||
[react/view {:flex 1}
|
||||
[react/text {:style (merge {:typography :title-bold} (when small-screen? {:font-size 15}))}
|
||||
(i18n/label :t/send-transaction)]]
|
||||
(i18n/label (or label :t/send-transaction))]]
|
||||
[button/button {:type :secondary
|
||||
:container-style {:padding-horizontal 24}
|
||||
:label (i18n/label :t/cancel)
|
||||
:on-press #(re-frame/dispatch [:set :wallet/prepare-transaction nil])}]])
|
||||
:on-press on-cancel}]])
|
||||
|
||||
(defn asset-selector [{:keys [token from]}]
|
||||
(defn asset-selector [{:keys [request? token from]}]
|
||||
(let [{:keys [name icon color]} token]
|
||||
[react/touchable-highlight
|
||||
{:on-press #(do
|
||||
(re-frame/dispatch [:dismiss-keyboard])
|
||||
(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||
{:content (fn [] [sheets/assets (:address from)])
|
||||
:content-height 300}]))}
|
||||
{:on-press (when-not request? #(do
|
||||
(re-frame/dispatch [:dismiss-keyboard])
|
||||
(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||
{:content (fn [] [sheets/assets (:address from)])
|
||||
:content-height 300}])))}
|
||||
[react/view {:style {:flex-direction :row
|
||||
:align-items :center
|
||||
:margin-left 16}
|
||||
|
@ -47,9 +48,10 @@
|
|||
[chat-icon/custom-icon-view-list name color 32])
|
||||
[react/text {:style {:margin-left 8}}
|
||||
(wallet.utils/display-symbol token)]
|
||||
[icons/icon :main-icons/dropdown {:color colors/gray}]]]))
|
||||
(when-not request?
|
||||
[icons/icon :main-icons/dropdown {:color colors/gray}])]]))
|
||||
|
||||
(defn render-account [account {:keys [amount decimals] :as token}]
|
||||
(defn render-account [account {:keys [amount decimals] :as token} event]
|
||||
[list-item/list-item
|
||||
{:icon [chat-icon/custom-icon-view-list (:name account) (:color account)]
|
||||
:title (:name account)
|
||||
|
@ -60,7 +62,7 @@
|
|||
:on-press #(do
|
||||
(re-frame/dispatch [:dismiss-keyboard])
|
||||
(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||
{:content (fn [] [sheets/accounts-list :from])
|
||||
{:content (fn [] [sheets/accounts-list :from event])
|
||||
:content-height 300}]))}])
|
||||
|
||||
(defn render-contact [contact from-chat?]
|
||||
|
@ -80,13 +82,75 @@
|
|||
:accessories [:chevron]}]))
|
||||
|
||||
(views/defview sheet [_]
|
||||
(views/letsubs [{:keys [amount-error amount-text from token to sign-enabled? from-chat?] :as tx}
|
||||
(views/letsubs [{:keys [amount-error amount-text
|
||||
request?
|
||||
from token to sign-enabled? from-chat?] :as tx}
|
||||
[:wallet.send/prepare-transaction-with-balance]
|
||||
window-height [:dimensions/window-height]
|
||||
keyboard-height [:keyboard-height]]
|
||||
(let [small-screen? (< (- window-height keyboard-height) 450)]
|
||||
[react/view {:style (styles/sheet small-screen?)}
|
||||
[header small-screen?]
|
||||
[header {:small-screen? small-screen?
|
||||
:on-cancel #(re-frame/dispatch [:wallet/cancel-transaction-command])}]
|
||||
[react/view {:flex-direction :row :padding-horizontal 24 :align-items :center
|
||||
:margin-vertical (if small-screen? 8 16)}
|
||||
[react/text-input
|
||||
{:style {:font-size (if small-screen? 24 38)
|
||||
:color (when amount-error colors/red)
|
||||
:flex-shrink 1}
|
||||
:keyboard-type :numeric
|
||||
:accessibility-label :amount-input
|
||||
:default-value amount-text
|
||||
:editable (not request?)
|
||||
:auto-focus true
|
||||
:on-change-text #(re-frame/dispatch [:wallet.send/set-amount-text %])
|
||||
:placeholder "0.0 "}]
|
||||
[asset-selector tx]
|
||||
(when amount-error
|
||||
[tooltip/tooltip (if from
|
||||
amount-error
|
||||
(i18n/label :t/select-account-first))
|
||||
{:bottom-value 2
|
||||
:font-size 12}])]
|
||||
[components/separator]
|
||||
(when-not small-screen?
|
||||
[list-item/list-item {:type :section-header :title :t/from}])
|
||||
[react/view {:flex-direction :row :flex 1 :align-items :center}
|
||||
(when small-screen?
|
||||
[react/i18n-text {:style {:width 50 :text-align :right :color colors/gray} :key :t/from}])
|
||||
[react/view {:flex 1}
|
||||
[render-account from token :wallet.send/set-field]]]
|
||||
(when-not small-screen?
|
||||
[list-item/list-item {:type :section-header :title :t/to}])
|
||||
[react/view {:flex-direction :row :flex 1 :align-items :center}
|
||||
(when small-screen?
|
||||
[react/i18n-text {:style {:width 50 :text-align :right :color colors/gray} :key :t/to}])
|
||||
[react/view {:flex 1}
|
||||
[render-contact to from-chat?]]]
|
||||
[toolbar/toolbar
|
||||
{:center
|
||||
{:label :t/wallet-send
|
||||
:accessibility-label :send-transaction-bottom-sheet
|
||||
:disabled? (not sign-enabled?)
|
||||
:on-press #(re-frame/dispatch
|
||||
[(cond
|
||||
request?
|
||||
:wallet.ui/sign-transaction-button-clicked-from-request
|
||||
from-chat?
|
||||
:wallet.ui/sign-transaction-button-clicked-from-chat
|
||||
:else
|
||||
:wallet.ui/sign-transaction-button-clicked) tx])}}]])))
|
||||
|
||||
(views/defview request-sheet [_]
|
||||
(views/letsubs [{:keys [amount-error amount-text from token to sign-enabled? from-chat?] :as tx}
|
||||
[:wallet.request/prepare-transaction-with-balance]
|
||||
window-height [:dimensions/window-height]
|
||||
keyboard-height [:keyboard-height]]
|
||||
(let [small-screen? (< (- window-height keyboard-height) 450)]
|
||||
[react/view {:style (styles/sheet small-screen?)}
|
||||
[header {:small-screen? small-screen?
|
||||
:label :t/request-transaction
|
||||
:on-cancel #(re-frame/dispatch [:wallet/cancel-transaction-command])}]
|
||||
[react/view {:flex-direction :row :padding-horizontal 24 :align-items :center
|
||||
:margin-vertical (if small-screen? 8 16)}
|
||||
[react/text-input
|
||||
|
@ -97,32 +161,54 @@
|
|||
:accessibility-label :amount-input
|
||||
:default-value amount-text
|
||||
:auto-focus true
|
||||
:on-change-text #(re-frame/dispatch [:wallet.send/set-amount-text %])
|
||||
:on-change-text #(re-frame/dispatch [:wallet.request/set-amount-text %])
|
||||
:placeholder "0.0 "}]
|
||||
[asset-selector tx]
|
||||
(when amount-error
|
||||
[tooltip/tooltip amount-error {:bottom-value 2
|
||||
:font-size 12}])]
|
||||
[components/separator]
|
||||
(when-not small-screen?
|
||||
[list-item/list-item {:type :section-header :title :t/from}])
|
||||
[react/view {:flex-direction :row :flex 1 :align-items :center}
|
||||
(when small-screen?
|
||||
[react/i18n-text {:style {:width 50 :text-align :right :color colors/gray} :key :t/from}])
|
||||
[react/view {:flex 1}
|
||||
[render-account from token]]]
|
||||
(when-not small-screen?
|
||||
[list-item/list-item {:type :section-header :title :t/to}])
|
||||
[react/view {:flex-direction :row :flex 1 :align-items :center}
|
||||
(when small-screen?
|
||||
[react/i18n-text {:style {:width 50 :text-align :right :color colors/gray} :key :t/to}])
|
||||
[react/view {:flex 1}
|
||||
[render-contact to from-chat?]]]
|
||||
[render-account from token :wallet.request/set-field]]]
|
||||
[toolbar/toolbar
|
||||
{:center {:label :t/wallet-send
|
||||
:accessibility-label :send-transaction-bottom-sheet
|
||||
:disabled? (not sign-enabled?)
|
||||
:on-press #(re-frame/dispatch [:wallet.ui/sign-transaction-button-clicked tx])}}]])))
|
||||
{:center
|
||||
{:label :t/wallet-request
|
||||
:accessibility-label :request-transaction-bottom-sheet
|
||||
:disabled? (not sign-enabled?)
|
||||
:on-press #(re-frame/dispatch
|
||||
[:wallet.ui/request-transaction-button-clicked tx])}}]])))
|
||||
|
||||
(views/defview select-account-sheet [{:keys [from message]}]
|
||||
(views/letsubs [window-height [:dimensions/window-height]
|
||||
keyboard-height [:keyboard-height]]
|
||||
(let [small-screen? (< (- window-height keyboard-height) 450)]
|
||||
[react/view {:style (styles/sheet small-screen?)}
|
||||
[header {:small-screen? small-screen?
|
||||
:label :t/select-account
|
||||
:on-cancel #(re-frame/dispatch [:set :commands/select-account nil])}]
|
||||
[react/view {:flex-direction :row :padding-horizontal 24 :align-items :center
|
||||
:margin-vertical (if small-screen? 8 16)}]
|
||||
(when-not small-screen?
|
||||
[list-item/list-item {:type :section-header :title :t/from}])
|
||||
[react/view {:flex-direction :row :flex 1 :align-items :center}
|
||||
(when small-screen?
|
||||
[react/i18n-text {:style {:width 50 :text-align :right :color colors/gray} :key :t/from}])
|
||||
[react/view {:flex 1}
|
||||
[render-account from nil ::commands/set-selected-account]]]
|
||||
[toolbar/toolbar
|
||||
{:center
|
||||
{:label :t/select
|
||||
:accessibility-label :select-account-bottom-sheet
|
||||
:disabled? (nil? from)
|
||||
:on-press #(re-frame/dispatch
|
||||
[::commands/accept-request-address-for-transaction
|
||||
(:message-id message)
|
||||
(:address from)])}}]])))
|
||||
|
||||
(defview prepare-transaction []
|
||||
(letsubs [tx [:wallet/prepare-transaction]]
|
||||
|
@ -130,6 +216,26 @@
|
|||
;;we use select-keys here because we don't want to update view if other keys in map are changed
|
||||
;; and because modal screen (qr code scanner) can't be opened over bottom sheet we have to use :modal-opened?
|
||||
;; to hide our transaction panel
|
||||
(when (and tx (not (:modal-opened? tx)))
|
||||
(when (and tx
|
||||
(not (:modal-opened? tx))
|
||||
(not (:request-command? tx)))
|
||||
(select-keys tx [:from-chat?]))
|
||||
sheet]))
|
||||
sheet]))
|
||||
|
||||
(defview request-transaction []
|
||||
(letsubs [tx [:wallet/prepare-transaction]]
|
||||
[bottom-panel/animated-bottom-panel
|
||||
;;we use select-keys here because we don't want to update view if other keys in map are changed
|
||||
;; and because modal screen (qr code scanner) can't be opened over bottom sheet we have to use :modal-opened?
|
||||
;; to hide our transaction panel
|
||||
(when (and tx
|
||||
(not (:modal-opened? tx))
|
||||
(:request-command? tx))
|
||||
(select-keys tx [:from-chat? :request?]))
|
||||
request-sheet]))
|
||||
|
||||
(defview select-account []
|
||||
(letsubs [data [:commands/select-account]]
|
||||
[bottom-panel/animated-bottom-panel
|
||||
data
|
||||
select-account-sheet]))
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
[re-frame.core :as re-frame]
|
||||
[status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.chat.models.message :as chat.message]
|
||||
[status-im.ethereum.core :as ethereum]
|
||||
[status-im.ethereum.eip55 :as eip55]
|
||||
[status-im.ethereum.json-rpc :as json-rpc]
|
||||
|
@ -343,7 +344,6 @@
|
|||
(flatten (map keys (vals balances))))]
|
||||
(fx/merge cofx
|
||||
(multiaccounts.update/multiaccount-update
|
||||
cofx
|
||||
:wallet/visible-tokens (assoc visible-tokens
|
||||
chain
|
||||
chain-visible-tokens)
|
||||
|
@ -366,29 +366,151 @@
|
|||
[{:keys [db]} amount]
|
||||
{:db (assoc-in db [:wallet/prepare-transaction :amount-text] amount)})
|
||||
|
||||
(fx/defn set-and-validate-request-amount
|
||||
{:events [:wallet.request/set-amount-text]}
|
||||
[{:keys [db]} amount]
|
||||
{:db (assoc-in db [:wallet/prepare-transaction :amount-text] amount)})
|
||||
|
||||
(fx/defn sign-transaction-button-clicked-from-chat
|
||||
{:events [:wallet.ui/sign-transaction-button-clicked-from-chat]}
|
||||
[{:keys [db] :as cofx} {:keys [to amount from token request? from-chat? gas gasPrice]}]
|
||||
(let [{:keys [symbol address]} token
|
||||
to-norm (ethereum/normalized-hex (if (string? to) to (:address to)))
|
||||
from-address (:address from)
|
||||
identity (:current-chat-id db)]
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(update-in [:chat-ui-props identity] dissoc :input-bottom-sheet)
|
||||
(dissoc :wallet/prepare-transaction))
|
||||
;;TODO from chat, send request message or if ens name sign tx and send tx message
|
||||
::json-rpc/call [{:method "shhext_requestAddressForTransaction"
|
||||
:params [(:current-chat-id db)
|
||||
from-address
|
||||
amount
|
||||
(when-not (= symbol :ETH)
|
||||
address)]
|
||||
:on-success #(re-frame/dispatch [:transport/message-sent % 1])}]})))
|
||||
|
||||
(fx/defn request-transaction-button-clicked-from-chat
|
||||
{:events [:wallet.ui/request-transaction-button-clicked]}
|
||||
[{:keys [db] :as cofx} {:keys [to amount from token from-chat? gas gasPrice]}]
|
||||
(let [{:keys [symbol address]} token
|
||||
to-norm (ethereum/normalized-hex (if (string? to) to (:address to)))
|
||||
from-address (:address from)
|
||||
identity (:current-chat-id db)]
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(update-in [:chat-ui-props identity] dissoc :input-bottom-sheet)
|
||||
(dissoc db :wallet/prepare-transaction))
|
||||
::json-rpc/call [{:method "shhext_requestTransaction"
|
||||
:params [(:public-key to)
|
||||
amount
|
||||
(when-not (= symbol :ETH)
|
||||
address)
|
||||
from-address]
|
||||
:on-success #(re-frame/dispatch [:transport/message-sent % 1])}]})))
|
||||
|
||||
(fx/defn accept-request-transaction-button-clicked-from-command
|
||||
{:events [:wallet.ui/accept-request-transaction-button-clicked-from-command]}
|
||||
[{:keys [db] :as cofx} chat-id {:keys [address value from id contract] :as request-parameters}]
|
||||
(let [identity (:current-chat-id db)
|
||||
all-tokens (:wallet/all-tokens db)
|
||||
current-network-string (:networks/current-network db)
|
||||
prices (:prices db)
|
||||
all-networks (:networks/networks db)
|
||||
current-network (get all-networks current-network-string)
|
||||
chain (ethereum/network->chain-keyword current-network)
|
||||
{:keys [symbol icon decimals] :as token}
|
||||
(if (seq contract)
|
||||
(get (get all-tokens chain) contract)
|
||||
(tokens/native-currency chain))
|
||||
amount-text (str (money/internal->formatted value symbol decimals))]
|
||||
{:db (assoc db :wallet/prepare-transaction
|
||||
{:from (ethereum/get-default-account (:multiaccount/accounts db))
|
||||
:to (or (get-in db [:contacts/contacts identity])
|
||||
(-> identity
|
||||
contact.db/public-key->new-contact
|
||||
contact.db/enrich-contact))
|
||||
:request-parameters request-parameters
|
||||
:chat-id chat-id
|
||||
:symbol symbol
|
||||
:amount-text amount-text
|
||||
:request? true
|
||||
:from-chat? true})}))
|
||||
|
||||
(fx/defn sign-transaction-button-clicked-from-request
|
||||
{:events [:wallet.ui/sign-transaction-button-clicked-from-request]}
|
||||
[{:keys [db] :as cofx} {:keys [to amount from token gas gasPrice]}]
|
||||
(let [{:keys [request-parameters]} (:wallet/prepare-transaction db)
|
||||
{:keys [symbol address]} token
|
||||
amount-hex (str "0x" (abi-spec/number-to-hex amount))
|
||||
to-norm (:address request-parameters)
|
||||
from-address (:address from)]
|
||||
(fx/merge cofx
|
||||
{:db (dissoc db :wallet/prepare-transaction)}
|
||||
(fn [cofx]
|
||||
(signing/sign cofx {:tx-obj (if (= symbol :ETH)
|
||||
{:to to-norm
|
||||
:from from-address
|
||||
:message-id (:id request-parameters)
|
||||
:command? true
|
||||
:value amount-hex}
|
||||
{:to (ethereum/normalized-hex address)
|
||||
:from from-address
|
||||
:command? true
|
||||
:message-id (:id request-parameters)
|
||||
:data (abi-spec/encode
|
||||
"transfer(address,uint256)"
|
||||
[to-norm amount-hex])
|
||||
;;Note: data from qr (eip681)
|
||||
:gas gas
|
||||
:gasPrice gasPrice})})))))
|
||||
|
||||
(fx/defn sign-transaction-button-clicked
|
||||
{:events [:wallet.ui/sign-transaction-button-clicked]}
|
||||
[{:keys [db] :as cofx} {:keys [to amount from token from-chat? gas gasPrice]}]
|
||||
[{:keys [db] :as cofx} {:keys [to amount from token gas gasPrice]}]
|
||||
(let [{:keys [symbol address]} token
|
||||
amount-hex (str "0x" (abi-spec/number-to-hex amount))
|
||||
to-norm (ethereum/normalized-hex (if (string? to) to (:address to)))
|
||||
from-address (:address from)]
|
||||
(fx/merge cofx
|
||||
{:db (dissoc db :wallet/prepare-transaction)}
|
||||
#(if from-chat?
|
||||
nil;;TODO from chat, send request message or if ens name sign tx and send tx message
|
||||
(signing/sign % {:tx-obj (if (= symbol :ETH)
|
||||
{:to to-norm
|
||||
:from from-address
|
||||
:value amount-hex}
|
||||
{:to (ethereum/normalized-hex address)
|
||||
:from from-address
|
||||
:data (abi-spec/encode
|
||||
"transfer(address,uint256)"
|
||||
[to-norm amount-hex])
|
||||
;;Note: data from qr (eip681)
|
||||
:gas gas
|
||||
:gasPrice gasPrice})})))))
|
||||
(fn [cofx]
|
||||
(signing/sign cofx {:tx-obj (if (= symbol :ETH)
|
||||
{:to to-norm
|
||||
:from from-address
|
||||
:value amount-hex}
|
||||
{:to (ethereum/normalized-hex address)
|
||||
:from from-address
|
||||
:data (abi-spec/encode
|
||||
"transfer(address,uint256)"
|
||||
[to-norm amount-hex])
|
||||
;;Note: data from qr (eip681)
|
||||
:gas gas
|
||||
:gasPrice gasPrice})})))))
|
||||
|
||||
(fx/defn sign-transaction-button-clicked-from-command
|
||||
{:events [:wallet.ui/sign-transaction-button-clicked]}
|
||||
[{:keys [db] :as cofx} {:keys [to amount from token gas gasPrice]}]
|
||||
(let [{:keys [symbol address]} token
|
||||
amount-hex (str "0x" (abi-spec/number-to-hex amount))
|
||||
to-norm (ethereum/normalized-hex (if (string? to) to (:address to)))
|
||||
from-address (:address from)]
|
||||
(fx/merge cofx
|
||||
{:db (dissoc db :wallet/prepare-transaction)}
|
||||
(fn [cofx]
|
||||
(signing/sign cofx {:tx-obj (if (= symbol :ETH)
|
||||
{:to to-norm
|
||||
:from from-address
|
||||
:value amount-hex}
|
||||
{:to (ethereum/normalized-hex address)
|
||||
:from from-address
|
||||
:data (abi-spec/encode
|
||||
"transfer(address,uint256)"
|
||||
[to-norm amount-hex])
|
||||
;;Note: data from qr (eip681)
|
||||
:gas gas
|
||||
:gasPrice gasPrice})})))))
|
||||
|
||||
(fx/defn set-and-validate-amount-request
|
||||
{:events [:wallet.request/set-and-validate-amount]}
|
||||
|
@ -410,7 +532,7 @@
|
|||
[{:keys [db]}]
|
||||
(let [identity (:current-chat-id db)]
|
||||
{:db (assoc db :wallet/prepare-transaction
|
||||
{:from (ethereum/get-default-account (get db [:multiaccount/accounts]))
|
||||
{:from (ethereum/get-default-account (:multiaccount/accounts db))
|
||||
:to (or (get-in db [:contacts/contacts identity])
|
||||
(-> identity
|
||||
contact.db/public-key->new-contact
|
||||
|
@ -418,6 +540,20 @@
|
|||
:symbol :ETH
|
||||
:from-chat? true})}))
|
||||
|
||||
(fx/defn prepare-request-transaction-from-chat
|
||||
{:events [:wallet/prepare-request-transaction-from-chat]}
|
||||
[{:keys [db]}]
|
||||
(let [identity (:current-chat-id db)]
|
||||
{:db (assoc db :wallet/prepare-transaction
|
||||
{:from (ethereum/get-default-account (:multiaccount/accounts db))
|
||||
:to (or (get-in db [:contacts/contacts identity])
|
||||
(-> identity
|
||||
contact.db/public-key->new-contact
|
||||
contact.db/enrich-contact))
|
||||
:symbol :ETH
|
||||
:from-chat? true
|
||||
:request-command? true})}))
|
||||
|
||||
(fx/defn prepare-transaction-from-wallet
|
||||
{:events [:wallet/prepare-transaction-from-wallet]}
|
||||
[{:keys [db]} account]
|
||||
|
@ -427,6 +563,24 @@
|
|||
:symbol :ETH
|
||||
:from-chat? false})})
|
||||
|
||||
(fx/defn cancel-transaction-command
|
||||
{:events [:wallet/cancel-transaction-command]}
|
||||
[{:keys [db]}]
|
||||
(let [identity (:current-chat-id db)]
|
||||
{:db (-> db
|
||||
(dissoc :wallet/prepare-transaction)
|
||||
(update-in [:chat-ui-props identity] dissoc :input-bottom-sheet))}))
|
||||
|
||||
(fx/defn finalize-transaction-from-command
|
||||
{:events [:wallet/finalize-transaction-from-command]}
|
||||
[{:keys [db]} account to symbol amount]
|
||||
{:db (assoc db :wallet/prepare-transaction
|
||||
{:from account
|
||||
:to to
|
||||
:symbol symbol
|
||||
:amount amount
|
||||
:from-command? true})})
|
||||
|
||||
(fx/defn qr-scanner-allowed
|
||||
{:events [:wallet.send/qr-scanner-allowed]}
|
||||
[{:keys [db] :as cofx} options]
|
||||
|
@ -449,6 +603,13 @@
|
|||
{:db (assoc-in db [:wallet/prepare-transaction field] value)}
|
||||
(bottom-sheet/hide-bottom-sheet)))
|
||||
|
||||
(fx/defn wallet-request-set-field
|
||||
{:events [:wallet.request/set-field]}
|
||||
[{:keys [db] :as cofx} field value]
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:wallet/prepare-transaction field] value)}
|
||||
(bottom-sheet/hide-bottom-sheet)))
|
||||
|
||||
(fx/defn navigate-to-recipient-code
|
||||
{:events [:wallet.send/navigate-to-recipient-code]}
|
||||
[{:keys [db] :as cofx}]
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
"owner": "status-im",
|
||||
"repo": "status-go",
|
||||
"version": "v0.39.2",
|
||||
"commit-sha1": "5546ce8c3001b76a5d741a20177497dce3e30653",
|
||||
"src-sha256": "1h72gld4hhrhz6g9c2anzzbawxzapswg47d1vdn9w7q7zwm8pisb"
|
||||
"commit-sha1": "88a1d0111e9a9d51370f14ad6b2c998f4514639b",
|
||||
"src-sha256": "0vdkjxi3vj6fv5ypq98g6swrq4v020dzm45n9d3vwbk3j7ln6p40"
|
||||
}
|
||||
|
|
|
@ -128,6 +128,12 @@
|
|||
:timestamp 3
|
||||
:whisper-timestamp 3}]
|
||||
current-list (s/add-many nil current-messages)]
|
||||
(testing "removing a message"
|
||||
(let [updated-list (-> (s/remove-message current-list {:clock-value 106
|
||||
:message-id "106"})
|
||||
(s/->seq))]
|
||||
(is (= 2 (count updated-list)))
|
||||
(is (= 103 (-> (nth updated-list 1) :clock-value)))))
|
||||
(testing "inserting a newer message"
|
||||
(let [new-message {:timestamp 12
|
||||
:clock-value 112
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
|
||||
contacts {"0x04985040682b77a32bb4bb58268a0719bd24ca4d07c255153fe1eb2ccd5883669627bd1a092d7cc76e8e4b9104327667b19dcda3ac469f572efabe588c38c1985f"
|
||||
{:last-updated 0,
|
||||
:address "eca8218b5ebeb2c47ba94c1b6e0a779d78fff7bc",
|
||||
:name "User B",
|
||||
:photo-path "photo1",
|
||||
:last-online 0,
|
||||
|
@ -23,7 +22,6 @@
|
|||
"0x04985040682b77a32bb4bb58268a0719bd24ca4d07c255153fe1eb2ccd5883669627bd1a092d7cc76e8e4b9104327667b19dcda3ac469f572efabe588c38c1985f"
|
||||
:system-tags #{}}}
|
||||
current-multiaccount {:last-updated 0,
|
||||
:address "f23d28f538fd8cd4a90c2d96ca89f5bccca5383f",
|
||||
:signed-up? true,
|
||||
:sharing-usage-data? false,
|
||||
:name "User A",
|
||||
|
@ -38,7 +36,6 @@
|
|||
:identicon "generated"
|
||||
:alias "generated"
|
||||
:admin? true
|
||||
:address "71adb0644e2b590e37dafdfea8bd58f0c7668c7f"
|
||||
:public-key "0x04fcf40c526b09ff9fb22f4a5dbd08490ef9b64af700870f8a0ba2133f4251d5607ed83cd9047b8c2796576bc83fa0de23a13a4dced07654b8ff137fe744047917"
|
||||
:system-tags #{}}
|
||||
{:name "User A"
|
||||
|
@ -47,7 +44,6 @@
|
|||
{:last-updated 0
|
||||
:name "User B"
|
||||
:photo-path "photo1"
|
||||
:address "eca8218b5ebeb2c47ba94c1b6e0a779d78fff7bc"
|
||||
:last-online 0
|
||||
:public-key "0x04985040682b77a32bb4bb58268a0719bd24ca4d07c255153fe1eb2ccd5883669627bd1a092d7cc76e8e4b9104327667b19dcda3ac469f572efabe588c38c1985f"
|
||||
:system-tags #{}}]))))))
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
:response-to "a"}
|
||||
:whisper-timestamp 1
|
||||
:outgoing-status :sending
|
||||
:command-parameters nil
|
||||
:outgoing true
|
||||
:message-type 0
|
||||
:clock-value 2
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
[status-im.contact.core :as model]))
|
||||
|
||||
(def public-key "0x04fcf40c526b09ff9fb22f4a5dbd08490ef9b64af700870f8a0ba2133f4251d5607ed83cd9047b8c2796576bc83fa0de23a13a4dced07654b8ff137fe744047917")
|
||||
(def address "71adb0644e2b590e37dafdfea8bd58f0c7668c7f")
|
||||
|
||||
(deftest handle-contact-update-test
|
||||
(with-redefs [json-rpc/call (constantly nil)]
|
||||
|
@ -16,16 +15,14 @@
|
|||
public-key
|
||||
1
|
||||
{:name "name"
|
||||
:profile-image "image"
|
||||
:address "address"})
|
||||
:profile-image "image"})
|
||||
contact (get-in actual [:db :contacts/contacts public-key])]
|
||||
(testing "it adds a new contact"
|
||||
(is (= {:public-key public-key
|
||||
:photo-path "image"
|
||||
:name "name"
|
||||
:last-updated 1000
|
||||
:system-tags #{:contact/request-received}
|
||||
:address "address"}
|
||||
:system-tags #{:contact/request-received}}
|
||||
contact)))))
|
||||
(testing "the contact is already in contacts"
|
||||
(testing "timestamp is greater than last-updated"
|
||||
|
@ -35,13 +32,11 @@
|
|||
:photo-path "old-image"
|
||||
:name "old-name"
|
||||
:last-updated 0
|
||||
:system-tags #{:contact/added}
|
||||
:address "old-address"}}}}
|
||||
:system-tags #{:contact/added}}}}}
|
||||
public-key
|
||||
1
|
||||
{:name "new-name"
|
||||
:profile-image "new-image"
|
||||
:address "new-address"})
|
||||
:profile-image "new-image"})
|
||||
contact (get-in actual [:db :contacts/contacts public-key])]
|
||||
(testing "it updates the contact and adds contact/request-received to system tags"
|
||||
(is (= {:public-key public-key
|
||||
|
@ -49,8 +44,7 @@
|
|||
:name "new-name"
|
||||
:last-updated 1000
|
||||
|
||||
:system-tags #{:contact/added :contact/request-received}
|
||||
:address "new-address"}
|
||||
:system-tags #{:contact/added :contact/request-received}}
|
||||
contact)))))
|
||||
(testing "timestamp is equal to last-updated"
|
||||
(let [actual (model/handle-contact-update
|
||||
|
@ -59,13 +53,11 @@
|
|||
:photo-path "old-image"
|
||||
:name "old-name"
|
||||
:last-updated 1000
|
||||
:system-tags #{:contact/added}
|
||||
:address "old-address"}}}}
|
||||
:system-tags #{:contact/added}}}}}
|
||||
public-key
|
||||
1
|
||||
{:name "new-name"
|
||||
:profile-image "new-image"
|
||||
:address "new-address"})
|
||||
:profile-image "new-image"})
|
||||
contact (get-in actual [:db :contacts/contacts public-key])]
|
||||
(testing "it does nothing"
|
||||
(is (nil? actual)))))
|
||||
|
@ -76,13 +68,11 @@
|
|||
:photo-path "old-image"
|
||||
:name "old-name"
|
||||
:last-updated 1000
|
||||
:system-tags #{:contact/added :contact/request-received}
|
||||
:address "old-address"}}}}
|
||||
:system-tags #{:contact/added :contact/request-received}}}}}
|
||||
public-key
|
||||
0
|
||||
{:name "new-name"
|
||||
:profile-image "new-image"
|
||||
:address "new-address"})
|
||||
:profile-image "new-image"})
|
||||
contact (get-in actual [:db :contacts/contacts public-key])]
|
||||
(testing "it does nothing"
|
||||
(is (nil? actual))))))
|
||||
|
@ -106,8 +96,7 @@
|
|||
:name "new-name"
|
||||
|
||||
:last-updated 1000
|
||||
:system-tags #{:contact/added :contact/request-received}
|
||||
:address address} contact)))))
|
||||
:system-tags #{:contact/added :contact/request-received}} contact)))))
|
||||
(testing "the message is coming from us"
|
||||
(testing "it does not update contacts"
|
||||
(is (nil? (model/handle-contact-update {:db {:multiaccount {:public-key "me"}}} "me" 1 {})))))))
|
||||
|
@ -121,7 +110,6 @@
|
|||
expected {(str "0x" pk1) {:alias "generated"
|
||||
:identicon "generated"
|
||||
:name "name-1"
|
||||
:address "6dd28d3d14c6ded091ed38a6735350ce92fe1956"
|
||||
:ens-verified true
|
||||
:ens-verified-at 1
|
||||
:public-key (str "0x" pk1)
|
||||
|
@ -129,7 +117,6 @@
|
|||
(str "0x" pk2) {:alias "generated"
|
||||
:name "name-2"
|
||||
:identicon "generated"
|
||||
:address "7ab91a68f65c1365d8071302a71599273acb68a2"
|
||||
:ens-verified false
|
||||
:ens-verified-at 2
|
||||
:public-key (str "0x" pk2)
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
"about-names-content": "No one can pretend to be you! You’re anonymous by default and never have to reveal your real name. You can register a custom name for a small fee.",
|
||||
"about-names-title": "Names can’t be changed",
|
||||
"access-key": "Access existing keys",
|
||||
"accept-and-share-address": "Accept and share address",
|
||||
"account-added": "Account added",
|
||||
"account-color": "Account color",
|
||||
"account-name": "Account name",
|
||||
|
@ -28,6 +29,9 @@
|
|||
"add-to-contacts": "Add to contacts",
|
||||
"add-to-contacts-text": "By adding a user to your contact list, you share your wallet address",
|
||||
"address": "Address",
|
||||
"address-received": "Address received",
|
||||
"address-requested": "Address requested",
|
||||
"address-request-accepted": "Address request accepted",
|
||||
"advanced": "Advanced",
|
||||
"advanced-settings": "Advanced settings",
|
||||
"agree-by-continuing": "By continuing you agree\n to our ",
|
||||
|
@ -306,6 +310,7 @@
|
|||
"datetime-today": "today",
|
||||
"datetime-yesterday": "yesterday",
|
||||
"decimals": "Decimals",
|
||||
"decline": "Decline",
|
||||
"decryption-failed-confirm": "Apply",
|
||||
"decryption-failed-content": "We were not able to decrypt your data, you might need to create new multiaccount and erase your old data by tapping “Apply”. Clicking on “Cancel”, will try again",
|
||||
"decryption-failed-title": "We were not able to decrypt your data",
|
||||
|
@ -518,6 +523,7 @@
|
|||
"importing-keycard-multiaccount": "Importing keycard multiaccount",
|
||||
"in-contacts": "In contacts",
|
||||
"incoming": "Incoming",
|
||||
"incoming-transaction": "Incoming transaction",
|
||||
"incorrect-code": [
|
||||
"str",
|
||||
"Sorry the code was incorrect, please enter it again"
|
||||
|
@ -755,6 +761,7 @@
|
|||
"or": "OR",
|
||||
"or-choose-a-contact": "Or choose a contact",
|
||||
"outgoing": "Outgoing",
|
||||
"outgoing-transaction": "Outgoing transaction",
|
||||
"pair": "Pair devices",
|
||||
"pair-card": "Pair to this device",
|
||||
"pair-card-question": "Card is ready to pair",
|
||||
|
@ -876,8 +883,11 @@
|
|||
"security": "Security",
|
||||
"see-details": "See details",
|
||||
"see-it-again": "SEE IT AGAIN",
|
||||
"select-account-first": "Select an account first",
|
||||
"select-chat": "Select chat to start messaging",
|
||||
"selected": "Selected",
|
||||
"select": "Select",
|
||||
"select-account": "Select account",
|
||||
"selected-for-you": "Selected for you",
|
||||
"send-command-payment": "Send a payment",
|
||||
"send-logs": "Report a bug",
|
||||
|
@ -901,6 +911,7 @@
|
|||
"set-dapp-access-permissions": "Set DApp access permissions",
|
||||
"settings": "Settings",
|
||||
"share": "Share",
|
||||
"shared": "Shared",
|
||||
"share-address": "Share address",
|
||||
"share-chat": "Share chat",
|
||||
"share-contact-code": "Share my chat key",
|
||||
|
@ -917,6 +928,7 @@
|
|||
"show-more": "Show more",
|
||||
"show-qr": "Show QR code",
|
||||
"sidechain-text": "You’re on the {{sidechain}} Sidechain.",
|
||||
"sign-and-send": "Sign and send",
|
||||
"sign-in": "Unlock",
|
||||
"sign-in-to-another": "Unlock another multiaccount",
|
||||
"sign-in-to-status": "Unlock Status",
|
||||
|
@ -981,6 +993,7 @@
|
|||
"token-details": "Token details",
|
||||
"topic-name-error": "Use only lowercase letters (a to z), numbers & dashes (-). Do not use chat keys",
|
||||
"transaction": "Transaction",
|
||||
"transaction-declined": "Transaction declined",
|
||||
"transaction-description": "Consider it complete after 12 confirmations on the network.",
|
||||
"transaction-details": "Transaction details",
|
||||
"transaction-failed": "Transaction failed",
|
||||
|
|
Loading…
Reference in New Issue