qr testing mode, fixed qr pure address and EIP681 issues
Signed-off-by: Andrey Shovkoplyas <motor4ik@gmail.com>
This commit is contained in:
parent
e813d1e4e4
commit
45dae49fc0
1
.env
1
.env
|
@ -23,3 +23,4 @@ MOBILE_UI_FOR_DESKTOP=1
|
|||
STATUS_GO_PROTOCOL=0
|
||||
STATUS_GO_ENABLE_NIMBUS=0
|
||||
KEYCARD_TEST_MENU=0
|
||||
QR_READ_TEST_MENU=1
|
1
.env.e2e
1
.env.e2e
|
@ -23,3 +23,4 @@ BLANK_PREVIEW=0
|
|||
TOOLTIP_EVENTS=1
|
||||
COMMANDS_ENABLED=1
|
||||
KEYCARD_TEST_MENU=1
|
||||
QR_READ_TEST_MENU=1
|
|
@ -25,7 +25,7 @@
|
|||
(def key-value-format (str "([^" parameter-separator key-value-separator "]+)"))
|
||||
(def query-pattern (re-pattern (str key-value-format key-value-separator key-value-format)))
|
||||
|
||||
(def valid-native-arguments #{:value :gas :gasPrice})
|
||||
(def valid-native-arguments #{:value :gas :gasPrice :gasLimit})
|
||||
|
||||
(defn- parse-query [s]
|
||||
(into {} (for [[_ k v] (re-seq query-pattern (or s ""))]
|
||||
|
@ -51,26 +51,28 @@
|
|||
Invalid URI will be parsed as `nil`."
|
||||
[s]
|
||||
(when (string? s)
|
||||
(let [[_ authority-path query] (re-find uri-pattern s)]
|
||||
(when authority-path
|
||||
(let [[_ raw-address chain-id function-name] (re-find authority-path-pattern authority-path)]
|
||||
(when (or (ethereum/address? raw-address)
|
||||
(if (string/starts-with? raw-address "pay-")
|
||||
(let [pay-address (string/replace-first raw-address "pay-" "")]
|
||||
(or (ens/is-valid-eth-name? pay-address)
|
||||
(ethereum/address? pay-address)))))
|
||||
(let [address (if (string/starts-with? raw-address "pay-")
|
||||
(string/replace-first raw-address "pay-" "")
|
||||
raw-address)]
|
||||
(when-let [arguments (parse-arguments function-name query)]
|
||||
(let [contract-address (get-in arguments [:function-arguments :address])]
|
||||
(if-not (or (not contract-address) (or (ens/is-valid-eth-name? contract-address) (ethereum/address? contract-address)))
|
||||
nil
|
||||
(merge {:address address
|
||||
:chain-id (if chain-id
|
||||
(js/parseInt chain-id)
|
||||
(ethereum/chain-keyword->chain-id :mainnet))}
|
||||
arguments)))))))))))
|
||||
(if (ethereum/address? s)
|
||||
{:address s}
|
||||
(let [[_ authority-path query] (re-find uri-pattern s)]
|
||||
(when authority-path
|
||||
(let [[_ raw-address chain-id function-name] (re-find authority-path-pattern authority-path)]
|
||||
(when (or (ethereum/address? raw-address)
|
||||
(if (string/starts-with? raw-address "pay-")
|
||||
(let [pay-address (string/replace-first raw-address "pay-" "")]
|
||||
(or (ens/is-valid-eth-name? pay-address)
|
||||
(ethereum/address? pay-address)))))
|
||||
(let [address (if (string/starts-with? raw-address "pay-")
|
||||
(string/replace-first raw-address "pay-" "")
|
||||
raw-address)]
|
||||
(when-let [arguments (parse-arguments function-name query)]
|
||||
(let [contract-address (get-in arguments [:function-arguments :address])]
|
||||
(if-not (or (not contract-address) (or (ens/is-valid-eth-name? contract-address) (ethereum/address? contract-address)))
|
||||
nil
|
||||
(merge {:address address
|
||||
:chain-id (if chain-id
|
||||
(js/parseInt chain-id)
|
||||
(ethereum/chain-keyword->chain-id :mainnet))}
|
||||
arguments))))))))))))
|
||||
|
||||
(defn parse-eth-value [s]
|
||||
"Takes a map as returned by `parse-uri` and returns value as BigNumber"
|
||||
|
@ -79,20 +81,21 @@
|
|||
n (money/bignumber (string/replace s "ETH" ""))]
|
||||
(if eth? (.times n 1e18) n))))
|
||||
|
||||
(defn extract-request-details [{:keys [value address chain-id function-name function-arguments]} all-tokens]
|
||||
(defn extract-request-details [{:keys [value address function-name function-arguments] :as details} all-tokens]
|
||||
"Return a map encapsulating request details (with keys `value`, `address` and `symbol`) from a parsed URI.
|
||||
Supports ethereum and erc20 token."
|
||||
(when address
|
||||
(case function-name
|
||||
nil
|
||||
{:value (parse-eth-value value)
|
||||
:symbol :ETH
|
||||
:address address}
|
||||
"transfer"
|
||||
{:value (money/bignumber (:uint256 function-arguments))
|
||||
:symbol (:symbol (tokens/address->token all-tokens (ethereum/chain-id->chain-keyword chain-id) address))
|
||||
:address (:address function-arguments)}
|
||||
nil)))
|
||||
(merge details
|
||||
(case function-name
|
||||
nil
|
||||
{:value (parse-eth-value value)
|
||||
:symbol :ETH
|
||||
:address address}
|
||||
"transfer"
|
||||
{:value (money/bignumber (:uint256 function-arguments))
|
||||
:symbol (:symbol (tokens/address->token all-tokens address))
|
||||
:address (:address function-arguments)}
|
||||
nil))))
|
||||
|
||||
(defn- generate-query-string [m]
|
||||
(string/join parameter-separator
|
||||
|
@ -118,8 +121,8 @@
|
|||
|
||||
(defn generate-erc20-uri
|
||||
"Generate a EIP 681 URI encapsulating ERC20 token transfer"
|
||||
[address {:keys [symbol value chain-id] :as m} all-tokens]
|
||||
(when-let [token (tokens/symbol->token all-tokens (if chain-id (ethereum/chain-id->chain-keyword chain-id) :mainnet) symbol)]
|
||||
[address {:keys [symbol value] :as m} all-tokens]
|
||||
(when-let [token (tokens/symbol->token all-tokens symbol)]
|
||||
(generate-uri (:address token)
|
||||
(merge (dissoc m :value :symbol)
|
||||
{:function-name "transfer"
|
||||
|
|
|
@ -27,7 +27,10 @@
|
|||
"In react-native arguments to require must be static strings.
|
||||
Resolve all icons at compilation time so no variable is used."
|
||||
[network tokens]
|
||||
(mapv #(assoc-in % [:icon :source] (token->icon network %)) tokens))
|
||||
(mapv #(-> %
|
||||
(assoc-in [:icon :source] (token->icon network %))
|
||||
(update :address string/lower-case))
|
||||
tokens))
|
||||
|
||||
(defn network->icon [network]
|
||||
(let [s (str "./resources/images/tokens/" (name network) "/0-native.png")
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
(ns status-im.ethereum.subscriptions
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.ethereum.eip55 :as eip55]
|
||||
[status-im.ethereum.core :as ethereum]
|
||||
[status-im.ethereum.json-rpc :as json-rpc]
|
||||
[status-im.ethereum.tokens :as tokens]
|
||||
(:require [status-im.ethereum.eip55 :as eip55]
|
||||
[status-im.wallet.db :as wallet]
|
||||
[status-im.ethereum.transactions.core :as transactions]
|
||||
[status-im.utils.fx :as fx]
|
||||
|
@ -26,28 +21,24 @@
|
|||
|
||||
(fx/defn new-block
|
||||
[{:keys [db] :as cofx} historical? block-number accounts transactions-per-account]
|
||||
(let [{:keys [:wallet/all-tokens]} db
|
||||
chain (ethereum/chain-keyword db)
|
||||
chain-tokens (into {} (map (juxt :address identity)
|
||||
(tokens/tokens-for all-tokens chain)))]
|
||||
(log/debug "[wallet-subs] new-block"
|
||||
"accounts" accounts
|
||||
"block" block-number
|
||||
"transactions-per-account" transactions-per-account)
|
||||
(fx/merge cofx
|
||||
(cond-> {}
|
||||
(not historical?)
|
||||
(assoc :db (assoc db :ethereum/current-block block-number))
|
||||
(log/debug "[wallet-subs] new-block"
|
||||
"accounts" accounts
|
||||
"block" block-number
|
||||
"transactions-per-account" transactions-per-account)
|
||||
(fx/merge cofx
|
||||
(cond-> {}
|
||||
(not historical?)
|
||||
(assoc :db (assoc db :ethereum/current-block block-number))
|
||||
|
||||
;;NOTE only get transfers if the new block contains some
|
||||
;; from/to one of the multiaccount accounts
|
||||
(not-empty accounts)
|
||||
(assoc :transactions/get-transfers
|
||||
{:chain-tokens chain-tokens
|
||||
:addresses accounts
|
||||
:before-block block-number
|
||||
:historical? historical?}))
|
||||
(transactions/check-watched-transactions))))
|
||||
;;NOTE only get transfers if the new block contains some
|
||||
;; from/to one of the multiaccount accounts
|
||||
(not-empty accounts)
|
||||
(assoc :transactions/get-transfers
|
||||
{:chain-tokens (:wallet/all-tokens db)
|
||||
:addresses accounts
|
||||
:before-block block-number
|
||||
:historical? historical?}))
|
||||
(transactions/check-watched-transactions)))
|
||||
|
||||
(fx/defn reorg
|
||||
[{:keys [db] :as cofx} {:keys [blockNumber accounts]}]
|
||||
|
@ -68,28 +59,24 @@
|
|||
(log/debug "[wallet-subs] recent-history-fetching-ended"
|
||||
"accounts" accounts
|
||||
"block" blockNumber)
|
||||
(let [{:keys [:wallet/all-tokens]} db
|
||||
chain (ethereum/chain-keyword db)
|
||||
chain-tokens (into {} (map (juxt :address identity)
|
||||
(tokens/tokens-for all-tokens chain)))]
|
||||
{:db (-> db
|
||||
(update-in [:wallet :accounts]
|
||||
wallet/remove-transactions-since-block blockNumber)
|
||||
(transactions/update-fetching-status accounts :recent? false))
|
||||
:transactions/get-transfers
|
||||
{:chain-tokens chain-tokens
|
||||
:addresses (reduce
|
||||
(fn [v address]
|
||||
(let [normalized-address
|
||||
(eip55/address->checksum address)]
|
||||
(if (contains? v normalized-address)
|
||||
v
|
||||
(conj v address))))
|
||||
[]
|
||||
accounts)
|
||||
:before-block blockNumber
|
||||
:limit 20
|
||||
:historical? true}}))
|
||||
{:db (-> db
|
||||
(update-in [:wallet :accounts]
|
||||
wallet/remove-transactions-since-block blockNumber)
|
||||
(transactions/update-fetching-status accounts :recent? false))
|
||||
:transactions/get-transfers
|
||||
{:chain-tokens (:wallet/all-tokens db)
|
||||
:addresses (reduce
|
||||
(fn [v address]
|
||||
(let [normalized-address
|
||||
(eip55/address->checksum address)]
|
||||
(if (contains? v normalized-address)
|
||||
v
|
||||
(conj v address))))
|
||||
[]
|
||||
accounts)
|
||||
:before-block blockNumber
|
||||
:limit 20
|
||||
:historical? true}})
|
||||
|
||||
(fx/defn new-wallet-event
|
||||
[cofx {:keys [type blockNumber accounts newTransactions] :as event}]
|
||||
|
|
|
@ -543,35 +543,24 @@
|
|||
|
||||
:custom []})
|
||||
|
||||
;; TODO all these should be improved, we don't need to recalculate this each time, it can be done only once
|
||||
(defn tokens-for
|
||||
"makes sure all addresses are lower-case
|
||||
TODO: token list should be speced and not accept non-lower-cased addresses"
|
||||
[all-tokens chain]
|
||||
(mapv #(update % :address string/lower-case) (vals (get all-tokens chain))))
|
||||
(defn nfts-for [all-tokens]
|
||||
(filter :nft? (vals all-tokens)))
|
||||
|
||||
(defn nfts-for [all-tokens chain]
|
||||
(filter :nft? (tokens-for all-tokens chain)))
|
||||
|
||||
(defn token-for [chain all-tokens token]
|
||||
(some #(when (= token (name (:symbol %))) %) (tokens-for all-tokens chain)))
|
||||
|
||||
(defn sorted-tokens-for [all-tokens chain]
|
||||
(->> (tokens-for all-tokens chain)
|
||||
(defn sorted-tokens-for [all-tokens]
|
||||
(->> (vals all-tokens)
|
||||
(filter #(not (:hidden? %)))
|
||||
(sort #(compare (string/lower-case (:name %1))
|
||||
(string/lower-case (:name %2))))))
|
||||
|
||||
(defn symbol->token [all-tokens chain symbol]
|
||||
(some #(when (= symbol (:symbol %)) %) (tokens-for all-tokens chain)))
|
||||
(defn symbol->token [all-tokens symbol]
|
||||
(some #(when (= symbol (:symbol %)) %) (vals all-tokens)))
|
||||
|
||||
(defn address->token [all-tokens chain address]
|
||||
(some #(when (= (string/lower-case address)
|
||||
(string/lower-case (:address %))) %) (tokens-for all-tokens chain)))
|
||||
(defn address->token [all-tokens address]
|
||||
(get all-tokens (string/lower-case address)))
|
||||
|
||||
(defn asset-for [all-tokens chain symbol]
|
||||
(let [native-coin (native-currency chain)]
|
||||
(if (or (= (:symbol-display native-coin) symbol)
|
||||
(= (:symbol native-coin) symbol))
|
||||
native-coin
|
||||
(symbol->token all-tokens chain symbol))))
|
||||
(symbol->token all-tokens symbol))))
|
||||
|
|
|
@ -275,20 +275,13 @@
|
|||
(fx/defn fetch-more-tx
|
||||
{:events [:transactions/fetch-more]}
|
||||
[{:keys [db] :as cofx} address]
|
||||
(let [all-tokens (:wallet/all-tokens db)
|
||||
chain (ethereum/chain-keyword db)
|
||||
chain-tokens (into
|
||||
{}
|
||||
(map (juxt :address identity)
|
||||
(tokens/tokens-for
|
||||
all-tokens chain)))
|
||||
min-known-block (or (get-min-known-block db address)
|
||||
(let [min-known-block (or (get-min-known-block db address)
|
||||
(:ethereum/current-block db))
|
||||
min-block-transfers-count (or (min-block-transfers-count db address) 0)]
|
||||
(fx/merge
|
||||
cofx
|
||||
{:transactions/get-transfers
|
||||
{:chain-tokens chain-tokens
|
||||
{:chain-tokens (:wallet/all-tokens db)
|
||||
:addresses [address]
|
||||
:before-block min-known-block
|
||||
:historical? true
|
||||
|
|
|
@ -106,8 +106,7 @@
|
|||
|
||||
(fx/defn prepare-unconfirmed-transaction
|
||||
[{:keys [db now]} hash {:keys [value gasPrice gas data to from]} symbol amount]
|
||||
(let [all-tokens (:wallet/all-tokens db)
|
||||
token (tokens/symbol->token all-tokens (ethereum/chain-keyword db) symbol)]
|
||||
(let [token (tokens/symbol->token (:wallet/all-tokens db) symbol)]
|
||||
{:db (assoc-in db [:wallet :accounts from :transactions hash]
|
||||
{:timestamp (str now)
|
||||
:to to
|
||||
|
@ -133,7 +132,7 @@
|
|||
:approve-and-call))
|
||||
|
||||
(defn get-transfer-token [db to data]
|
||||
(let [{:keys [symbol decimals] :as token} (tokens/address->token (:wallet/all-tokens db) (ethereum/chain-keyword db) to)]
|
||||
(let [{:keys [symbol decimals] :as token} (tokens/address->token (:wallet/all-tokens db) to)]
|
||||
(when (and token data (string? data))
|
||||
(when-let [type (get-method-type data)]
|
||||
(let [[address value _] (abi-spec/decode
|
||||
|
|
|
@ -1118,18 +1118,21 @@
|
|||
0))
|
||||
acc)) 0 balance))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:wallet/token->decimals
|
||||
:<- [:wallet/all-tokens]
|
||||
(fn [all-tokens]
|
||||
(into {} (map #(vector (:symbol %) (:decimals %)) (vals all-tokens)))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:portfolio-value
|
||||
:<- [:balances]
|
||||
:<- [:prices]
|
||||
:<- [:wallet/currency]
|
||||
:<- [:ethereum/chain-keyword]
|
||||
:<- [:wallet/all-tokens]
|
||||
(fn [[balances prices currency chain all-tokens]]
|
||||
:<- [:wallet/token->decimals]
|
||||
(fn [[balances prices currency token->decimals]]
|
||||
(if (and balances prices)
|
||||
(let [assets (tokens/tokens-for all-tokens chain)
|
||||
token->decimals (into {} (map #(vector (:symbol %) (:decimals %)) assets))
|
||||
currency-key (-> currency :code keyword)
|
||||
(let [currency-key (-> currency :code keyword)
|
||||
balance-total-value (apply + (map #(get-balance-total-value % prices currency-key token->decimals) balances))]
|
||||
(if (pos? balance-total-value)
|
||||
(-> balance-total-value
|
||||
|
@ -1145,13 +1148,10 @@
|
|||
[(re-frame/subscribe [:balance address])
|
||||
(re-frame/subscribe [:prices])
|
||||
(re-frame/subscribe [:wallet/currency])
|
||||
(re-frame/subscribe [:ethereum/chain-keyword])
|
||||
(re-frame/subscribe [:wallet/all-tokens])])
|
||||
(fn [[balance prices currency chain all-tokens]]
|
||||
(re-frame/subscribe [:wallet/token->decimals])])
|
||||
(fn [[balance prices currency token->decimals]]
|
||||
(if (and balance prices)
|
||||
(let [assets (tokens/tokens-for all-tokens chain)
|
||||
token->decimals (into {} (map #(vector (:symbol %) (:decimals %)) assets))
|
||||
currency-key (-> currency :code keyword)
|
||||
(let [currency-key (-> currency :code keyword)
|
||||
balance-total-value (get-balance-total-value balance prices currency-key token->decimals)]
|
||||
(if (pos? balance-total-value)
|
||||
(-> balance-total-value
|
||||
|
@ -1162,22 +1162,14 @@
|
|||
"...")))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:wallet/chain-tokens
|
||||
:wallet/sorted-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]
|
||||
:<- [:ethereum/chain-keyword]
|
||||
(fn [[all-tokens chain]]
|
||||
(tokens/sorted-tokens-for all-tokens chain)))
|
||||
(fn [all-tokens]
|
||||
(tokens/sorted-tokens-for all-tokens)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:wallet/grouped-chain-tokens
|
||||
:<- [:wallet/sorted-chain-tokens]
|
||||
:<- [:wallet/sorted-tokens]
|
||||
:<- [:wallet/visible-tokens-symbols]
|
||||
(fn [[all-tokens visible-tokens]]
|
||||
(let [vt-set (set visible-tokens)]
|
||||
|
@ -1228,10 +1220,9 @@
|
|||
:wallet/visible-assets
|
||||
:<- [:ethereum/chain-keyword]
|
||||
:<- [:wallet/visible-tokens-symbols]
|
||||
:<- [:wallet/all-tokens]
|
||||
(fn [[chain visible-tokens-symbols all-tokens]]
|
||||
(conj (filter #(contains? visible-tokens-symbols (:symbol %))
|
||||
(tokens/sorted-tokens-for all-tokens chain))
|
||||
:<- [:wallet/sorted-tokens]
|
||||
(fn [[chain visible-tokens-symbols all-tokens-sorted]]
|
||||
(conj (filter #(contains? visible-tokens-symbols (:symbol %)) all-tokens-sorted)
|
||||
(tokens/native-currency chain))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
|
|
|
@ -146,7 +146,7 @@
|
|||
[contract value]
|
||||
(let [{:keys [symbol icon decimals color] :as token}
|
||||
(if (seq contract)
|
||||
(get @(re-frame/subscribe [:wallet/chain-tokens])
|
||||
(get @(re-frame/subscribe [:wallet/all-tokens])
|
||||
contract
|
||||
transactions/default-erc20-token)
|
||||
@(re-frame/subscribe [:ethereum/native-currency]))
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.toolbar.view :as topbar]
|
||||
[status-im.ui.screens.qr-scanner.styles :as styles]
|
||||
[status-im.ui.components.colors :as colors]))
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.utils.config :as config]
|
||||
[status-im.ui.components.button :as button]))
|
||||
|
||||
(defn- topbar [camera-flashlight {:keys [title] :as opts}]
|
||||
[topbar/toolbar
|
||||
|
@ -23,6 +25,25 @@
|
|||
:icon-opts {:color colors/white}
|
||||
:handler #(re-frame/dispatch [:wallet/toggle-flashlight])}]]])
|
||||
|
||||
(defn qr-test-view [opts]
|
||||
(let [text-value (atom "")]
|
||||
[react/safe-area-view {:style {:flex 1
|
||||
:background-color colors/black-persist}}
|
||||
[topbar nil opts]
|
||||
[react/view {:flex 1
|
||||
:align-items :center
|
||||
:justify-content :center}
|
||||
[react/text-input {:multiline true
|
||||
:style {:color colors/white-persist}
|
||||
:on-change-text #(reset! text-value %)}]
|
||||
[react/view {:flex-direction :row}
|
||||
[button/button
|
||||
{:label "Cancel"
|
||||
:on-press #(re-frame/dispatch [:qr-scanner.callback/scan-qr-code-cancel opts])}]
|
||||
[button/button
|
||||
{:label "OK"
|
||||
:on-press #(re-frame/dispatch [:qr-scanner.callback/scan-qr-code-success opts @text-value])}]]]]))
|
||||
|
||||
(defn corner [border1 border2 corner]
|
||||
[react/view (assoc {:border-color colors/white-persist :width 60 :height 60} border1 5 border2 5 corner 32)])
|
||||
|
||||
|
@ -44,15 +65,17 @@
|
|||
{:keys [height width]} [:dimensions/window]
|
||||
camera-flashlight [:wallet.send/camera-flashlight]
|
||||
opts [:get-screen-params]]
|
||||
[react/safe-area-view {:style {:flex 1
|
||||
:background-color colors/black-persist}}
|
||||
[topbar camera-flashlight opts]
|
||||
[react/with-activity-indicator
|
||||
{}
|
||||
[camera/camera
|
||||
{:style {:flex 1}
|
||||
:captureAudio false
|
||||
:onBarCodeRead #(when-not @read-once?
|
||||
(reset! read-once? true)
|
||||
(on-barcode-read opts %))}]]
|
||||
[viewfinder (int (* 2 (/ (min height width) 3)))]]))
|
||||
(if config/qr-test-menu-enabled?
|
||||
[qr-test-view opts]
|
||||
[react/safe-area-view {:style {:flex 1
|
||||
:background-color colors/black-persist}}
|
||||
[topbar camera-flashlight opts]
|
||||
[react/with-activity-indicator
|
||||
{}
|
||||
[camera/camera
|
||||
{:style {:flex 1}
|
||||
:captureAudio false
|
||||
:onBarCodeRead #(when-not @read-once?
|
||||
(reset! read-once? true)
|
||||
(on-barcode-read opts %))}]]
|
||||
[viewfinder (int (* 2 (/ (min height width) 3)))]])))
|
||||
|
|
|
@ -37,7 +37,8 @@
|
|||
|
||||
(defn- request-camera-permissions []
|
||||
(let [options {:handler :wallet.send/qr-scanner-result
|
||||
:cancel-handler :wallet.send/qr-scanner-cancel}]
|
||||
:cancel-handler :wallet.send/qr-scanner-cancel
|
||||
:modal-opened? true}]
|
||||
(re-frame/dispatch
|
||||
[:request-permissions
|
||||
{:permissions [:camera]
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
(def waku-enabled? (enabled? (get-config :WAKU_ENABLED "0")))
|
||||
(def commands-enabled? (enabled? (get-config :COMMANDS_ENABLED "0")))
|
||||
(def keycard-test-menu-enabled? (enabled? (get-config :KEYCARD_TEST_MENU "0")))
|
||||
(def qr-test-menu-enabled? (enabled? (get-config :QR_READ_TEST_MENU "0")))
|
||||
|
||||
;; CONFIG VALUES
|
||||
(def log-level
|
||||
|
|
|
@ -102,8 +102,8 @@
|
|||
|
||||
(fx/defn handle-eip681 [cofx url]
|
||||
(fx/merge cofx
|
||||
(choose-recipient/resolve-ens-addresses url)
|
||||
(navigation/navigate-to-cofx :wallet nil)))
|
||||
(choose-recipient/parse-eip681-uri-and-resolve-ens url)
|
||||
(navigation/navigate-to-cofx :wallet nil)))
|
||||
|
||||
(defn handle-not-found [full-url]
|
||||
(log/info "universal-links: no handler for " full-url))
|
||||
|
|
|
@ -271,8 +271,7 @@
|
|||
(fx/defn view-only-qr-scanner-result
|
||||
{:events [:wallet.add-new/qr-scanner-result]}
|
||||
[{db :db :as cofx} data _]
|
||||
(let [address (or (when (ethereum/address? data) data)
|
||||
(:address (eip681/parse-uri data)))]
|
||||
(let [address (:address (eip681/parse-uri data))]
|
||||
(fx/merge cofx
|
||||
(merge {:db (-> db
|
||||
(assoc-in [:add-account :scanned-address] address)
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
(ns status-im.wallet.choose-recipient.core
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contact.db :as contact.db]
|
||||
[status-im.ethereum.core :as ethereum]
|
||||
[status-im.ethereum.eip55 :as eip55]
|
||||
|
@ -23,51 +22,6 @@
|
|||
(defn- find-address-name [db address]
|
||||
(:name (contact.db/find-contact-by-address (:contacts/contacts db) address)))
|
||||
|
||||
(defn- fill-request-details [db {:keys [address name value symbol gas gasPrice public-key from-chat?]} request?]
|
||||
{:pre [(not (nil? address))]}
|
||||
(let [name (or name (find-address-name db address))
|
||||
;;TODO request isn't implemented
|
||||
data-path (if request?
|
||||
:wallet/prepare-transaction
|
||||
:wallet/prepare-transaction)]
|
||||
(update db data-path
|
||||
(fn [{old-symbol :symbol :as old-transaction}]
|
||||
(let [symbol-changed? (not= old-symbol symbol)]
|
||||
(cond-> (assoc old-transaction
|
||||
:to address :to-name name :public-key public-key
|
||||
:gas (money/bignumber gas)
|
||||
:gas-price (money/bignumber gasPrice))
|
||||
value (assoc :amount value)
|
||||
symbol (assoc :symbol symbol)
|
||||
from-chat? (assoc :from-chat? from-chat?)))))))
|
||||
|
||||
;;TODO request isn't implemented
|
||||
(fx/defn fill-request-from-contact
|
||||
{:events [:wallet/fill-request-from-contact]}
|
||||
[{db :db} {:keys [address name public-key]} request?]
|
||||
{:db (fill-request-details db {:address address :name name :public-key public-key} request?)
|
||||
:dispatch [:navigate-back]})
|
||||
|
||||
(defn- extract-details
|
||||
"First try to parse as EIP681 URI, if not assume this is an address directly.
|
||||
Returns a map containing at least the `address` and `chain-id` keys"
|
||||
[m chain-id all-tokens]
|
||||
(or (merge m (eip681/extract-request-details m all-tokens))
|
||||
(when (ethereum/address? m)
|
||||
{:address m :chain-id chain-id})))
|
||||
|
||||
;; NOTE(janherich) - whenever changing assets, we want to clear the previusly set amount/amount-text
|
||||
(defn changed-asset [{:keys [db] :as fx} old-symbol new-symbol]
|
||||
(-> fx
|
||||
(assoc-in [:db :wallet/prepare-transaction :amount] nil)
|
||||
(assoc-in [:db :wallet/prepare-transaction :amount-text] nil)
|
||||
(assoc-in [:db :wallet/prepare-transaction :asset-error]
|
||||
(i18n/label :t/changed-asset-warning {:old old-symbol :new new-symbol}))))
|
||||
|
||||
(defn changed-amount-warning [fx old-amount new-amount]
|
||||
(assoc-in fx [:db :wallet/prepare-transaction :amount-error]
|
||||
(i18n/label :t/changed-amount-warning {:old old-amount :new new-amount})))
|
||||
|
||||
(defn use-default-eth-gas [fx]
|
||||
(assoc-in fx [:db :wallet :send-transaction :gas]
|
||||
ethereum/default-transaction-gas))
|
||||
|
@ -115,44 +69,54 @@
|
|||
:else
|
||||
{:ui/show-error (i18n/label :t/wallet-invalid-address {:data recipient})})))
|
||||
|
||||
(defn- fill-prepare-transaction-details
|
||||
[db
|
||||
{:keys [address name value symbol gas gasPrice gasLimit]
|
||||
:or {symbol :ETH}}
|
||||
all-tokens]
|
||||
(assoc db :wallet/prepare-transaction
|
||||
(cond-> {:to address
|
||||
:to-name (or name (find-address-name db address))
|
||||
:from (ethereum/get-default-account
|
||||
(get db :multiaccount/accounts))}
|
||||
gas (assoc :gas (money/bignumber gas))
|
||||
gasLimit (assoc :gas (money/bignumber gasLimit))
|
||||
gasPrice (assoc :gasPrice (money/bignumber gasPrice))
|
||||
value (assoc :amount-text
|
||||
(if (= :ETH symbol)
|
||||
(str (money/internal->formatted value symbol (get all-tokens symbol)))
|
||||
(str value)))
|
||||
symbol (assoc :symbol symbol))))
|
||||
|
||||
(fx/defn request-uri-parsed
|
||||
{:events [:wallet/request-uri-parsed]}
|
||||
[{{:networks/keys [networks current-network] :wallet/keys [all-tokens] :as db} :db} data uri]
|
||||
(let [current-chain-id (get-in networks [current-network :config :NetworkId])
|
||||
{:keys [address chain-id] :as details} (extract-details data current-chain-id all-tokens)
|
||||
valid-network? (boolean (= current-chain-id chain-id))
|
||||
previous-state (get db :wallet/prepare-transaction)
|
||||
old-symbol (:symbol previous-state)
|
||||
new-symbol (:symbol details)
|
||||
old-amount (:amount previous-state)
|
||||
new-amount (:value details)
|
||||
symbol-changed? (and old-symbol new-symbol (not= old-symbol new-symbol))
|
||||
amount-changed? (and old-amount new-amount (not= old-amount new-amount))]
|
||||
(cond-> {:db db}
|
||||
(and address valid-network?) (update :db #(fill-request-details % details false))
|
||||
symbol-changed? (changed-asset old-symbol new-symbol)
|
||||
amount-changed? (changed-amount-warning old-amount new-amount)
|
||||
(not (:from previous-state))
|
||||
(update :db assoc-in [:wallet/prepare-transaction :from]
|
||||
(ethereum/get-default-account (get db :multiaccount/accounts)))
|
||||
(not old-symbol)
|
||||
(update :db assoc-in [:wallet/prepare-transaction :symbol] (or new-symbol :ETH))
|
||||
(not address) (assoc :ui/show-error (i18n/label :t/wallet-invalid-address {:data uri}))
|
||||
(and address (not valid-network?))
|
||||
(assoc :ui/show-error (i18n/label :t/wallet-invalid-chain-id
|
||||
{:data uri :chain current-chain-id})))))
|
||||
[{{:networks/keys [networks current-network]
|
||||
:wallet/keys [all-tokens] :as db} :db}
|
||||
{:keys [chain-id] :as data}
|
||||
uri]
|
||||
(let [{:keys [address] :as details}
|
||||
(eip681/extract-request-details data all-tokens)]
|
||||
(if address
|
||||
(if (:wallet/prepare-transaction db)
|
||||
{:db (update db :wallet/prepare-transaction assoc
|
||||
:to address :to-name (find-address-name db address))}
|
||||
(let [current-chain-id (get-in networks [current-network :config :NetworkId])]
|
||||
(merge {:db (fill-prepare-transaction-details db details all-tokens)}
|
||||
(when (and chain-id (not= current-chain-id chain-id))
|
||||
{:ui/show-error (i18n/label :t/wallet-invalid-chain-id
|
||||
{:data uri :chain current-chain-id})}))))
|
||||
{:ui/show-error (i18n/label :t/wallet-invalid-address {:data uri})})))
|
||||
|
||||
(fx/defn qr-scanner-cancel
|
||||
{:events [:wallet.send/qr-scanner-cancel]}
|
||||
[{db :db} _]
|
||||
{:db (assoc-in db [:wallet/prepare-transaction :modal-opened?] false)})
|
||||
|
||||
(fx/defn resolve-ens-addresses
|
||||
{:events [:wallet.send/resolve-ens-addresses :wallet.send/qr-code-request-scanned]}
|
||||
[{{:networks/keys [current-network] :wallet/keys [all-tokens] :as db} :db :as cofx} uri]
|
||||
(fx/defn parse-eip681-uri-and-resolve-ens
|
||||
[{db :db :as cofx} uri]
|
||||
(if-let [message (eip681/parse-uri uri)]
|
||||
;; first we get a vector of ens-names to resolve and a vector of paths of
|
||||
;; these names
|
||||
;; first we get a vector of ens-names to resolve and a vector of paths of
|
||||
;; these names
|
||||
(let [{:keys [paths ens-names]}
|
||||
(reduce (fn [acc path]
|
||||
(let [address (get-in message path)]
|
||||
|
@ -163,8 +127,9 @@
|
|||
acc)))
|
||||
{:paths [] :ens-names []}
|
||||
[[:address] [:function-arguments :address]])]
|
||||
(println "message" message)
|
||||
(if (empty? ens-names)
|
||||
;; if there is no ens-names, we dispatch request-uri-parsed immediately
|
||||
;; if there are no ens-names, we dispatch request-uri-parsed immediately
|
||||
(request-uri-parsed cofx message uri)
|
||||
{::resolve-addresses
|
||||
{:registry (get ens/ens-registries (ethereum/chain-keyword db))
|
||||
|
@ -173,8 +138,8 @@
|
|||
(fn [addresses]
|
||||
(re-frame/dispatch
|
||||
[:wallet/request-uri-parsed
|
||||
;; we replace the ens-names at their path in the message by their
|
||||
;; actual address
|
||||
;; we replace ens-names at their path in the message by their
|
||||
;; actual address
|
||||
(reduce (fn [message [path address]]
|
||||
(assoc-in message path address))
|
||||
message
|
||||
|
@ -185,6 +150,8 @@
|
|||
{:events [:wallet.send/qr-scanner-result]}
|
||||
[{db :db :as cofx} data opts]
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:wallet/prepare-transaction :modal-opened?] false)}
|
||||
(navigation/navigate-back)
|
||||
(resolve-ens-addresses data)))
|
||||
(parse-eip681-uri-and-resolve-ens data)
|
||||
(fn [{:keys [db]}]
|
||||
(when (get-in db [:wallet/prepare-transaction :modal-opened?])
|
||||
{:db (assoc-in db [:wallet/prepare-transaction :modal-opened?] false)}))))
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
|
||||
(defmulti load-collectibles-fx (fn [_ symbol _ _ _] symbol))
|
||||
|
||||
(defmethod load-collectibles-fx :default [all-tokens symbol items-number address chain]
|
||||
{:load-collectibles-fx [all-tokens symbol items-number address chain]})
|
||||
(defmethod load-collectibles-fx :default [all-tokens symbol items-number address]
|
||||
{:load-collectibles-fx [all-tokens symbol items-number address]})
|
||||
|
||||
(defn load-token [i items-number contract address symbol]
|
||||
(when (< i items-number)
|
||||
|
@ -31,21 +31,18 @@
|
|||
|
||||
(re-frame/reg-fx
|
||||
:load-collectibles-fx
|
||||
(fn [[all-tokens symbol items-number address chain]]
|
||||
(let [contract (:address (tokens/symbol->token all-tokens chain symbol))]
|
||||
(fn [[all-tokens symbol items-number address]]
|
||||
(let [contract (:address (tokens/symbol->token all-tokens symbol))]
|
||||
(load-token 0 items-number contract address symbol))))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:show-collectibles-list
|
||||
(fn [{:keys [db]} [_ {:keys [symbol amount] :as collectible} address]]
|
||||
(let [{:networks/keys [current-network networks]} db
|
||||
chain (ethereum/chain-id->chain-keyword
|
||||
(get-in networks [current-network :config :NetworkId]))
|
||||
all-tokens (:wallet/all-tokens db)
|
||||
(let [all-tokens (:wallet/all-tokens db)
|
||||
items-number (money/to-number amount)
|
||||
loaded-items-number (count (get-in db [:collectibles symbol]))]
|
||||
(merge (when (not= items-number loaded-items-number)
|
||||
(load-collectibles-fx all-tokens symbol items-number address chain))
|
||||
(load-collectibles-fx all-tokens symbol items-number address))
|
||||
{:dispatch [:navigate-to :collectibles-list collectible]}))))
|
||||
|
||||
;; Crypto Kitties
|
||||
|
@ -101,16 +98,12 @@
|
|||
(def kudos :KDO)
|
||||
|
||||
(defmethod load-collectible-fx kudos [{db :db} symbol id]
|
||||
(let [{:networks/keys [current-network networks]} db
|
||||
chain-id (get-in networks [current-network :config :NetworkId])
|
||||
all-tokens (:wallet/all-tokens db)]
|
||||
{:erc721-token-uri [all-tokens symbol id chain-id]}))
|
||||
{:erc721-token-uri [(:wallet/all-tokens db) symbol id]})
|
||||
|
||||
(re-frame/reg-fx
|
||||
:erc721-token-uri
|
||||
(fn [[all-tokens symbol tokenId chain-id]]
|
||||
(let [chain (ethereum/chain-id->chain-keyword chain-id)
|
||||
contract (:address (tokens/symbol->token all-tokens chain symbol))]
|
||||
(fn [[all-tokens symbol tokenId]]
|
||||
(let [contract (:address (tokens/symbol->token all-tokens symbol))]
|
||||
(erc721/token-uri contract
|
||||
tokenId
|
||||
#(re-frame/dispatch [:token-uri-success
|
||||
|
|
|
@ -200,9 +200,9 @@
|
|||
(update-in db [:wallet :errors] dissoc error-type))
|
||||
|
||||
(defn tokens-symbols
|
||||
[visible-token-symbols all-tokens chain]
|
||||
[visible-token-symbols all-tokens]
|
||||
(set/difference (set visible-token-symbols)
|
||||
(set (map :symbol (tokens/nfts-for all-tokens chain)))))
|
||||
(set (map :symbol (tokens/nfts-for all-tokens)))))
|
||||
|
||||
(defn rpc->token [tokens]
|
||||
(reduce (fn [acc {:keys [address] :as token}]
|
||||
|
@ -213,21 +213,14 @@
|
|||
tokens))
|
||||
|
||||
(fx/defn initialize-tokens
|
||||
[{:keys [db] :as cofx} custom-tokens]
|
||||
(let [chain (ethereum/chain-keyword db)
|
||||
custom-tokens {chain (rpc->token custom-tokens)}
|
||||
;;TODO why do we need all tokens ? chain can be changed only through relogin
|
||||
all-tokens (merge-with
|
||||
merge
|
||||
(utils.core/map-values #(utils.core/index-by :address %)
|
||||
tokens/all-default-tokens)
|
||||
custom-tokens)]
|
||||
(fx/merge
|
||||
cofx
|
||||
(merge
|
||||
{:db (assoc db :wallet/all-tokens all-tokens)}
|
||||
(when config/erc20-contract-warnings-enabled?
|
||||
{:wallet/validate-tokens (get tokens/all-default-tokens chain)})))))
|
||||
[{:keys [db]} custom-tokens]
|
||||
(let [default-tokens (utils.core/index-by :address (get tokens/all-default-tokens
|
||||
(ethereum/chain-keyword db)))
|
||||
all-tokens (merge default-tokens (rpc->token custom-tokens))]
|
||||
(merge
|
||||
{:db (assoc db :wallet/all-tokens all-tokens)}
|
||||
(when config/erc20-contract-warnings-enabled?
|
||||
{:wallet/validate-tokens default-tokens}))))
|
||||
|
||||
(fx/defn update-balances
|
||||
[{{:keys [network-status :wallet/all-tokens
|
||||
|
@ -239,7 +232,7 @@
|
|||
assets (get visible-tokens chain)
|
||||
init? (or (empty? assets)
|
||||
(= assets (constants/default-visible-tokens chain)))
|
||||
tokens (->> (tokens/tokens-for all-tokens chain)
|
||||
tokens (->> (vals all-tokens)
|
||||
(remove #(or (:hidden? %)
|
||||
;;if not init remove not visible tokens
|
||||
(and (not init?)
|
||||
|
@ -269,7 +262,7 @@
|
|||
(let [chain (ethereum/chain-keyword db)
|
||||
mainnet? (= :mainnet chain)
|
||||
assets (get visible-tokens chain #{})
|
||||
tokens (tokens-symbols assets all-tokens chain)
|
||||
tokens (tokens-symbols assets all-tokens)
|
||||
currency (get constants/currencies currency)]
|
||||
(when (not= network-status :offline)
|
||||
{:wallet/get-prices
|
||||
|
@ -446,7 +439,7 @@
|
|||
chain (ethereum/network->chain-keyword current-network)
|
||||
{:keys [symbol decimals]}
|
||||
(if (seq contract)
|
||||
(get (get all-tokens chain) contract)
|
||||
(get all-tokens contract)
|
||||
(tokens/native-currency chain))
|
||||
amount-text (str (money/internal->formatted value symbol decimals))]
|
||||
{:db (assoc db :wallet/prepare-transaction
|
||||
|
@ -608,7 +601,8 @@
|
|||
{:events [:wallet.send/qr-scanner-allowed]}
|
||||
[{:keys [db] :as cofx} options]
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:wallet/prepare-transaction :modal-opened?] true)}
|
||||
(when (:modal-opened? options)
|
||||
{:db (assoc-in db [:wallet/prepare-transaction :modal-opened?] true)})
|
||||
(bottom-sheet/hide-bottom-sheet)
|
||||
(navigation/navigate-to-cofx :qr-scanner options)))
|
||||
|
||||
|
|
|
@ -85,10 +85,9 @@
|
|||
(string/trim %)]))))
|
||||
|
||||
(defn field-exists?
|
||||
[{:wallet/keys [all-tokens] :as db} field-key field-value]
|
||||
(let [chain-key (ethereum/chain-keyword db)]
|
||||
(some #(= field-value (get % field-key))
|
||||
(vals (get all-tokens chain-key)))))
|
||||
[{:wallet/keys [all-tokens]} field-key field-value]
|
||||
(some #(= field-value (get % field-key))
|
||||
(vals all-tokens)))
|
||||
|
||||
(fx/defn total-supply-result
|
||||
[{:keys [db]} contract total-supply]
|
||||
|
@ -100,10 +99,8 @@
|
|||
:error (i18n/label :t/wrong-contract)})}))
|
||||
|
||||
(defn token-in-list?
|
||||
[{:wallet/keys [all-tokens] :as db} contract]
|
||||
(let [chain-key (ethereum/chain-keyword db)
|
||||
addresses (set (map string/lower-case (keys (get all-tokens chain-key))))]
|
||||
(not (nil? (get addresses (string/lower-case contract))))))
|
||||
[{:wallet/keys [all-tokens]} contract]
|
||||
(not (nil? (get all-tokens (string/lower-case contract)))))
|
||||
|
||||
(fx/defn contract-address-is-changed
|
||||
[{:keys [db]} contract]
|
||||
|
@ -177,7 +174,7 @@
|
|||
:decimals (int decimals)
|
||||
:color (rand-nth colors/chat-colors)}]
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:wallet/all-tokens chain-key contract]
|
||||
{:db (assoc-in db [:wallet/all-tokens contract]
|
||||
(assoc new-token :custom? true))
|
||||
::json-rpc/call [{:method "wallet_addCustomToken"
|
||||
:params [new-token]
|
||||
|
@ -191,7 +188,7 @@
|
|||
[{:keys [db] :as cofx} {:keys [address] :as token} navigate-back?]
|
||||
(let [chain-key (ethereum/chain-keyword db)]
|
||||
(fx/merge cofx
|
||||
{:db (update-in db [:wallet/all-tokens chain-key] dissoc address)
|
||||
{:db (update db :wallet/all-tokens dissoc address)
|
||||
::json-rpc/call [{:method "wallet_deleteCustomToken"
|
||||
:params [address]
|
||||
:on-success #()}]}
|
||||
|
|
|
@ -16,34 +16,73 @@
|
|||
(is (= nil (eip681/parse-uri "ethereum:pay-gimme.ether?value=1e18")))
|
||||
(is (= nil (eip681/parse-uri "ethereum:pay-snt.thetoken.ether/transfer?address=gimme.eth&uint256=1&gas=100")))
|
||||
(is (= nil (eip681/parse-uri "ethereum:pay-snt.thetoken.eth/transfer?address=gimme.ether&uint256=1&gas=100")))
|
||||
(is (= {:address "gimme.eth" :value "1e18" :chain-id 1} (eip681/parse-uri "ethereum:pay-gimme.eth?value=1e18")))
|
||||
(is (= {:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :value "1e18" :chain-id 1} (eip681/parse-uri "ethereum:pay-0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7?value=1e18")))
|
||||
(is (= {:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :chain-id 1} (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7")))
|
||||
(is (= {:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :value "1" :chain-id 1} (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7?value=1")))
|
||||
(is (= {:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7", :chain-id 1} (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7?unknown=1")))
|
||||
(is (= {:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7", :chain-id 1} (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7?address=0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7")))
|
||||
(is (= {:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :value "2.014e18" :chain-id 1} (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7?value=2.014e18")))
|
||||
(is (= {:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :value "-1e18" :chain-id 1} (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7?value=-1e18")))
|
||||
(is (= {:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :value "+1E18" :chain-id 1} (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7?value=+1E18")))
|
||||
(is (= {:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :value "1E18" :gas "100" :chain-id 1} (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7?value=1E18&gas=100")))
|
||||
(is (= {:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :value "NOT_NUMBER" :chain-id 1} (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7?value=NOT_NUMBER")))
|
||||
(is (= {:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :value "1ETH" :chain-id 1} (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7?value=1ETH")))
|
||||
(is (= {:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :value "1e18" :gas "5000" :chain-id 1} (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7@1?value=1e18&gas=5000")))
|
||||
(is (= {:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :value "1e18" :gas "5000" :chain-id 3} (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7@3?value=1e18&gas=5000")))
|
||||
(is (= {:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :chain-id 1 :function-name "transfer"} (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7/transfer")))
|
||||
(is (= {:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :chain-id 1 :function-name "transfer" :function-arguments {:address "0x8e23ee67d1332ad560396262c48ffbb01f93d052" :uint256 "1"}}
|
||||
(eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7/transfer?address=0x8e23ee67d1332ad560396262c48ffbb01f93d052&uint256=1")))
|
||||
(is (= {:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :chain-id 1 :function-name "transfer" :gas "100" :function-arguments {:address "0x8e23ee67d1332ad560396262c48ffbb01f93d052" :uint256 "1"}}
|
||||
(eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7/transfer?address=0x8e23ee67d1332ad560396262c48ffbb01f93d052&uint256=1&gas=100")))
|
||||
(is (= {:address "snt.thetoken.eth" :chain-id 1 :function-name "transfer" :gas "100" :function-arguments {:address "gimme.eth" :uint256 "1"}}
|
||||
(eip681/parse-uri "ethereum:pay-snt.thetoken.eth/transfer?address=gimme.eth&uint256=1&gas=100"))))
|
||||
|
||||
(is (= (eip681/parse-uri "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7")
|
||||
{:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7"}))
|
||||
|
||||
(is (= (eip681/parse-uri "ethereum:pay-gimme.eth?value=1e18")
|
||||
{:address "gimme.eth" :value "1e18" :chain-id 1}))
|
||||
|
||||
(is (= (eip681/parse-uri "ethereum:pay-0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7?value=1e18")
|
||||
{:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :value "1e18" :chain-id 1}))
|
||||
|
||||
(is (= (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7")
|
||||
{:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :chain-id 1}))
|
||||
|
||||
(is (= (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7?value=1")
|
||||
{:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :value "1" :chain-id 1}))
|
||||
|
||||
(is (= (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7?unknown=1")
|
||||
{:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7", :chain-id 1}))
|
||||
|
||||
(is (= (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7?address=0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7")
|
||||
{:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7", :chain-id 1}))
|
||||
|
||||
(is (= (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7?value=2.014e18")
|
||||
{:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :value "2.014e18" :chain-id 1}))
|
||||
|
||||
(is (= (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7?value=-1e18")
|
||||
{:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :value "-1e18" :chain-id 1}))
|
||||
|
||||
(is (= (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7?value=+1E18")
|
||||
{:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :value "+1E18" :chain-id 1}))
|
||||
|
||||
(is (= (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7?value=1E18&gas=100")
|
||||
{:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :value "1E18" :gas "100" :chain-id 1}))
|
||||
|
||||
(is (= (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7?value=NOT_NUMBER")
|
||||
{:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :value "NOT_NUMBER" :chain-id 1}))
|
||||
|
||||
(is (= (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7?value=1ETH")
|
||||
{:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :value "1ETH" :chain-id 1}))
|
||||
|
||||
(is (= (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7@1?value=1e18&gas=5000")
|
||||
{:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :value "1e18" :gas "5000" :chain-id 1}))
|
||||
|
||||
(is (= (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7@3?value=1e18&gas=5000")
|
||||
{:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :value "1e18" :gas "5000" :chain-id 3}))
|
||||
|
||||
(is (= (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7/transfer")
|
||||
{:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :chain-id 1 :function-name "transfer"}))
|
||||
|
||||
(is (= (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7/transfer?address=0x8e23ee67d1332ad560396262c48ffbb01f93d052&uint256=1")
|
||||
{:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :chain-id 1
|
||||
:function-name "transfer" :function-arguments {:address "0x8e23ee67d1332ad560396262c48ffbb01f93d052" :uint256 "1"}}))
|
||||
|
||||
(is (= (eip681/parse-uri "ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7/transfer?address=0x8e23ee67d1332ad560396262c48ffbb01f93d052&uint256=1&gas=100")
|
||||
{:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" :chain-id 1 :gas "100"
|
||||
:function-name "transfer" :function-arguments {:address "0x8e23ee67d1332ad560396262c48ffbb01f93d052" :uint256 "1"}}))
|
||||
|
||||
(is (= (eip681/parse-uri "ethereum:pay-snt.thetoken.eth/transfer?address=gimme.eth&uint256=1&gas=100")
|
||||
{:address "snt.thetoken.eth" :chain-id 1 :gas "100"
|
||||
:function-name "transfer" :function-arguments {:address "gimme.eth" :uint256 "1"}})))
|
||||
|
||||
(def all-tokens
|
||||
{:mainnet {"0x744d70fdbe2ba4cf95131626614a1763df805b9e" {:address "0x744d70fdbe2ba4cf95131626614a1763df805b9e"
|
||||
:name "Status Network Token"
|
||||
:symbol :SNT
|
||||
:decimals 18}}
|
||||
:testnet {"0xc55cF4B03948D7EBc8b9E8BAD92643703811d162" {:address "0xc55cF4B03948D7EBc8b9E8BAD92643703811d162"
|
||||
:testnet {"0xc55cf4b03948d7ebc8b9e8bad92643703811d162" {:address "0xc55cf4b03948d7ebc8b9e8bad92643703811d162"
|
||||
:name "Status Test Token"
|
||||
:symbol :STT
|
||||
:decimals 18}}})
|
||||
|
@ -51,13 +90,13 @@
|
|||
(deftest generate-erc20-uri
|
||||
(is (= nil (eip681/generate-erc20-uri nil nil all-tokens)))
|
||||
(is (= "ethereum:0x744d70fdbe2ba4cf95131626614a1763df805b9e/transfer?uint256=5&address=0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7"
|
||||
(eip681/generate-erc20-uri "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" {:symbol :SNT :value 5} all-tokens)))
|
||||
(eip681/generate-erc20-uri "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" {:symbol :SNT :value 5} (:mainnet all-tokens))))
|
||||
(is (= "ethereum:0x744d70fdbe2ba4cf95131626614a1763df805b9e/transfer?uint256=5&address=0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7&gas=10000&gasPrice=10000"
|
||||
(eip681/generate-erc20-uri "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" {:symbol :SNT :value 5 :gas 10000 :gasPrice 10000} all-tokens)))
|
||||
(eip681/generate-erc20-uri "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" {:symbol :SNT :value 5 :gas 10000 :gasPrice 10000} (:mainnet all-tokens))))
|
||||
(is (= "ethereum:0x744d70fdbe2ba4cf95131626614a1763df805b9e/transfer?uint256=5&address=0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7"
|
||||
(eip681/generate-erc20-uri "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" {:symbol :SNT :chain-id 1 :value 5} all-tokens)))
|
||||
(eip681/generate-erc20-uri "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" {:symbol :SNT :chain-id 1 :value 5} (:mainnet all-tokens))))
|
||||
(is (= "ethereum:0xc55cf4b03948d7ebc8b9e8bad92643703811d162@3/transfer?uint256=5&address=0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7"
|
||||
(eip681/generate-erc20-uri "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" {:symbol :STT :chain-id 3 :value 5} all-tokens))))
|
||||
(eip681/generate-erc20-uri "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" {:symbol :STT :chain-id 3 :value 5} (:testnet all-tokens)))))
|
||||
|
||||
(deftest generate-uri
|
||||
(is (= nil (eip681/generate-uri nil nil)))
|
||||
|
@ -96,13 +135,14 @@
|
|||
(is (.equals (money/ether->wei (money/bignumber 1)) value))
|
||||
(is (= :ETH symbol))
|
||||
(is (= "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" address)))
|
||||
(is (nil? (eip681/extract-request-details {:address "0x744d70fdbe2ba4cf95131626614a1763df805b9e" :chain-id 1 :function-name "unknown"} {})))
|
||||
(is (= (eip681/extract-request-details {:address "0x744d70fdbe2ba4cf95131626614a1763df805b9e" :chain-id 1 :function-name "unknown"}
|
||||
{:address "0x744d70fdbe2ba4cf95131626614a1763df805b9e" :chain-id 1 :function-name "unknown"})))
|
||||
(let [{:keys [value symbol address]} (eip681/extract-request-details {:address "0x744d70fdbe2ba4cf95131626614a1763df805b9e" :chain-id 1
|
||||
:function-name "transfer" :function-arguments {:uint256 1000 :address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7"}}
|
||||
{:mainnet {"0x744d70fdbe2ba4cf95131626614a1763df805b9e" {:address "0x744d70fdbe2ba4cf95131626614a1763df805b9e"
|
||||
:name "Status Network Token"
|
||||
:symbol :SNT
|
||||
:decimals 18}}})]
|
||||
{"0x744d70fdbe2ba4cf95131626614a1763df805b9e" {:address "0x744d70fdbe2ba4cf95131626614a1763df805b9e"
|
||||
:name "Status Network Token"
|
||||
:symbol :SNT
|
||||
:decimals 18}})]
|
||||
(is (.equals (money/bignumber 1000) value))
|
||||
(is (= :SNT symbol))
|
||||
(is (= "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" address))))
|
||||
|
|
Loading…
Reference in New Issue