feat: approve token transactions on swap (#21076)
Signed-off-by: Brian Sztamfater <brian@status.im>
This commit is contained in:
parent
c861d95d69
commit
d5238ac82f
|
@ -591,11 +591,17 @@
|
||||||
(def ^:const default-slippage 0.5)
|
(def ^:const default-slippage 0.5)
|
||||||
(def ^:const max-recommended-slippage 5)
|
(def ^:const max-recommended-slippage 5)
|
||||||
(def ^:const max-slippage-decimal-places 2)
|
(def ^:const max-slippage-decimal-places 2)
|
||||||
(def ^:const swap-default-provider
|
(def ^:const swap-provider-paraswap
|
||||||
{:name :paraswap
|
{:name :paraswap
|
||||||
:full-name "Paraswap"
|
:full-name "Paraswap"
|
||||||
:color :blue
|
:color :blue
|
||||||
:contract-address "0xdef171fe48cf0115b1d80b88dc8eab59176fee57"
|
:contract-address "0xdef171fe48cf0115b1d80b88dc8eab59176fee57"
|
||||||
:terms-and-conditions-url "https://files.paraswap.io/tos_v4.pdf"})
|
:terms-and-conditions-url "https://files.paraswap.io/tos_v4.pdf"})
|
||||||
|
(def ^:const swap-providers
|
||||||
|
{:paraswap swap-provider-paraswap})
|
||||||
|
|
||||||
(def ^:const token-for-fees-symbol "ETH")
|
(def ^:const token-for-fees-symbol "ETH")
|
||||||
|
|
||||||
|
(def ^:const transaction-status-success "Success")
|
||||||
|
(def ^:const transaction-status-pending "Pending")
|
||||||
|
(def ^:const transaction-status-failed "Failed")
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
(ns status-im.contexts.wallet.common.utils
|
(ns status-im.contexts.wallet.common.utils
|
||||||
(:require [clojure.string :as string]
|
(:require [clojure.string :as string]
|
||||||
|
[native-module.core :as native-module]
|
||||||
[quo.foundations.resources :as resources]
|
[quo.foundations.resources :as resources]
|
||||||
[status-im.common.qr-codes.view :as qr-codes]
|
[status-im.common.qr-codes.view :as qr-codes]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
|
[utils.hex :as utils.hex]
|
||||||
[utils.money :as money]
|
[utils.money :as money]
|
||||||
[utils.number :as number]
|
[utils.number :as number]
|
||||||
[utils.string]))
|
[utils.string]))
|
||||||
|
@ -348,3 +350,121 @@
|
||||||
[tokens]
|
[tokens]
|
||||||
(let [priority #(get constants/token-sort-priority (:symbol %) ##Inf)]
|
(let [priority #(get constants/token-sort-priority (:symbol %) ##Inf)]
|
||||||
(sort-by (juxt (comp - :balance) priority) tokens)))
|
(sort-by (juxt (comp - :balance) priority) tokens)))
|
||||||
|
|
||||||
|
(defn- transaction-data
|
||||||
|
[{:keys [from-address to-address token-address route data eth-transfer?]}]
|
||||||
|
(let [{:keys [amount-in gas-amount gas-fees]} route
|
||||||
|
eip-1559-enabled? (:eip-1559-enabled gas-fees)
|
||||||
|
{:keys [gas-price max-fee-per-gas-medium
|
||||||
|
max-priority-fee-per-gas]} gas-fees]
|
||||||
|
(cond-> {:From from-address
|
||||||
|
:To (or token-address to-address)
|
||||||
|
:Gas (money/to-hex gas-amount)
|
||||||
|
:Value (when eth-transfer? amount-in)
|
||||||
|
:Nonce nil
|
||||||
|
:Input ""
|
||||||
|
:Data (or data "0x")}
|
||||||
|
eip-1559-enabled? (assoc
|
||||||
|
:TxType "0x02"
|
||||||
|
:MaxFeePerGas
|
||||||
|
(money/to-hex
|
||||||
|
(money/->wei
|
||||||
|
:gwei
|
||||||
|
max-fee-per-gas-medium))
|
||||||
|
:MaxPriorityFeePerGas
|
||||||
|
(money/to-hex
|
||||||
|
(money/->wei
|
||||||
|
:gwei
|
||||||
|
max-priority-fee-per-gas)))
|
||||||
|
(not eip-1559-enabled?) (assoc :TxType "0x00"
|
||||||
|
:GasPrice
|
||||||
|
(money/to-hex
|
||||||
|
(money/->wei
|
||||||
|
:gwei
|
||||||
|
gas-price))))))
|
||||||
|
|
||||||
|
(defn approval-path
|
||||||
|
[{:keys [route from-address to-address token-address]}]
|
||||||
|
(let [{:keys [from]} route
|
||||||
|
from-chain-id (:chain-id from)
|
||||||
|
approval-amount-required (:approval-amount-required route)
|
||||||
|
approval-amount-required-sanitized (-> approval-amount-required
|
||||||
|
(utils.hex/normalize-hex)
|
||||||
|
(native-module/hex-to-number))
|
||||||
|
approval-contract-address (:approval-contract-address route)
|
||||||
|
data (native-module/encode-function-call
|
||||||
|
constants/contract-function-signature-erc20-approve
|
||||||
|
[approval-contract-address
|
||||||
|
approval-amount-required-sanitized])
|
||||||
|
tx-data (transaction-data {:from-address from-address
|
||||||
|
:to-address to-address
|
||||||
|
:token-address token-address
|
||||||
|
:route route
|
||||||
|
:data data
|
||||||
|
:eth-transfer? false})]
|
||||||
|
{:BridgeName constants/bridge-name-transfer
|
||||||
|
:ChainID from-chain-id
|
||||||
|
:TransferTx tx-data}))
|
||||||
|
|
||||||
|
(defn transaction-path
|
||||||
|
[{:keys [from-address to-address token-id token-address route data eth-transfer?]}]
|
||||||
|
(let [{:keys [bridge-name amount-in bonder-fees from
|
||||||
|
to]} route
|
||||||
|
tx-data (transaction-data {:from-address from-address
|
||||||
|
:to-address to-address
|
||||||
|
:token-address token-address
|
||||||
|
:route route
|
||||||
|
:data data
|
||||||
|
:eth-transfer? eth-transfer?})
|
||||||
|
to-chain-id (:chain-id to)
|
||||||
|
from-chain-id (:chain-id from)]
|
||||||
|
(cond-> {:BridgeName bridge-name
|
||||||
|
:ChainID from-chain-id}
|
||||||
|
|
||||||
|
(= bridge-name constants/bridge-name-erc-721-transfer)
|
||||||
|
(assoc :ERC721TransferTx
|
||||||
|
(assoc tx-data
|
||||||
|
:Recipient to-address
|
||||||
|
:TokenID token-id
|
||||||
|
:ChainID to-chain-id))
|
||||||
|
|
||||||
|
(= bridge-name constants/bridge-name-erc-1155-transfer)
|
||||||
|
(assoc :ERC1155TransferTx
|
||||||
|
(assoc tx-data
|
||||||
|
:Recipient to-address
|
||||||
|
:TokenID token-id
|
||||||
|
:ChainID to-chain-id
|
||||||
|
:Amount amount-in))
|
||||||
|
|
||||||
|
(= bridge-name constants/bridge-name-transfer)
|
||||||
|
(assoc :TransferTx tx-data)
|
||||||
|
|
||||||
|
(= bridge-name constants/bridge-name-hop)
|
||||||
|
(assoc :HopTx
|
||||||
|
(assoc tx-data
|
||||||
|
:ChainID from-chain-id
|
||||||
|
:ChainIDTo to-chain-id
|
||||||
|
:Symbol token-id
|
||||||
|
:Recipient to-address
|
||||||
|
:Amount amount-in
|
||||||
|
:BonderFee bonder-fees))
|
||||||
|
|
||||||
|
(not (or (= bridge-name constants/bridge-name-erc-721-transfer)
|
||||||
|
(= bridge-name constants/bridge-name-transfer)
|
||||||
|
(= bridge-name constants/bridge-name-hop)))
|
||||||
|
(assoc :CbridgeTx
|
||||||
|
(assoc tx-data
|
||||||
|
:ChainID to-chain-id
|
||||||
|
:Symbol token-id
|
||||||
|
:Recipient to-address
|
||||||
|
:Amount amount-in)))))
|
||||||
|
|
||||||
|
(defn multi-transaction-command
|
||||||
|
[{:keys [from-address to-address from-asset to-asset amount-out multi-transaction-type]
|
||||||
|
:or {multi-transaction-type constants/multi-transaction-type-unknown}}]
|
||||||
|
{:fromAddress from-address
|
||||||
|
:toAddress to-address
|
||||||
|
:fromAsset from-asset
|
||||||
|
:toAsset to-asset
|
||||||
|
:fromAmount amount-out
|
||||||
|
:type multi-transaction-type})
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
[utils.address :as address]
|
[utils.address :as address]
|
||||||
[utils.hex :as utils.hex]
|
[utils.hex :as utils.hex]
|
||||||
[utils.money :as money]
|
[utils.money :as utils.money]
|
||||||
[utils.number]
|
[utils.number]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
@ -582,124 +582,6 @@
|
||||||
[{:ms 20
|
[{:ms 20
|
||||||
:dispatch [:wallet/clean-up-transaction-flow]}]]]})))
|
:dispatch [:wallet/clean-up-transaction-flow]}]]]})))
|
||||||
|
|
||||||
(defn- transaction-data
|
|
||||||
[{:keys [from-address to-address token-address route data eth-transfer?]}]
|
|
||||||
(let [{:keys [amount-in gas-amount gas-fees]} route
|
|
||||||
eip-1559-enabled? (:eip-1559-enabled gas-fees)
|
|
||||||
{:keys [gas-price max-fee-per-gas-medium
|
|
||||||
max-priority-fee-per-gas]} gas-fees]
|
|
||||||
(cond-> {:From from-address
|
|
||||||
:To (or token-address to-address)
|
|
||||||
:Gas (money/to-hex gas-amount)
|
|
||||||
:Value (when eth-transfer? amount-in)
|
|
||||||
:Nonce nil
|
|
||||||
:Input ""
|
|
||||||
:Data (or data "0x")}
|
|
||||||
eip-1559-enabled? (assoc
|
|
||||||
:TxType "0x02"
|
|
||||||
:MaxFeePerGas
|
|
||||||
(money/to-hex
|
|
||||||
(money/->wei
|
|
||||||
:gwei
|
|
||||||
max-fee-per-gas-medium))
|
|
||||||
:MaxPriorityFeePerGas
|
|
||||||
(money/to-hex
|
|
||||||
(money/->wei
|
|
||||||
:gwei
|
|
||||||
max-priority-fee-per-gas)))
|
|
||||||
(not eip-1559-enabled?) (assoc :TxType "0x00"
|
|
||||||
:GasPrice
|
|
||||||
(money/to-hex
|
|
||||||
(money/->wei
|
|
||||||
:gwei
|
|
||||||
gas-price))))))
|
|
||||||
|
|
||||||
(defn- approval-path
|
|
||||||
[{:keys [route from-address to-address token-address]}]
|
|
||||||
(let [{:keys [from]} route
|
|
||||||
from-chain-id (:chain-id from)
|
|
||||||
approval-amount-required (:approval-amount-required route)
|
|
||||||
approval-amount-required-sanitized (-> approval-amount-required
|
|
||||||
(utils.hex/normalize-hex)
|
|
||||||
(native-module/hex-to-number))
|
|
||||||
approval-contract-address (:approval-contract-address route)
|
|
||||||
data (native-module/encode-function-call
|
|
||||||
constants/contract-function-signature-erc20-approve
|
|
||||||
[approval-contract-address
|
|
||||||
approval-amount-required-sanitized])
|
|
||||||
tx-data (transaction-data {:from-address from-address
|
|
||||||
:to-address to-address
|
|
||||||
:token-address token-address
|
|
||||||
:route route
|
|
||||||
:data data
|
|
||||||
:eth-transfer? false})]
|
|
||||||
{:BridgeName constants/bridge-name-transfer
|
|
||||||
:ChainID from-chain-id
|
|
||||||
:TransferTx tx-data}))
|
|
||||||
|
|
||||||
(defn- transaction-path
|
|
||||||
[{:keys [from-address to-address token-id token-address route data eth-transfer?]}]
|
|
||||||
(let [{:keys [bridge-name amount-in bonder-fees from
|
|
||||||
to]} route
|
|
||||||
tx-data (transaction-data {:from-address from-address
|
|
||||||
:to-address to-address
|
|
||||||
:token-address token-address
|
|
||||||
:route route
|
|
||||||
:data data
|
|
||||||
:eth-transfer? eth-transfer?})
|
|
||||||
to-chain-id (:chain-id to)
|
|
||||||
from-chain-id (:chain-id from)]
|
|
||||||
(cond-> {:BridgeName bridge-name
|
|
||||||
:ChainID from-chain-id}
|
|
||||||
|
|
||||||
(= bridge-name constants/bridge-name-erc-721-transfer)
|
|
||||||
(assoc :ERC721TransferTx
|
|
||||||
(assoc tx-data
|
|
||||||
:Recipient to-address
|
|
||||||
:TokenID token-id
|
|
||||||
:ChainID to-chain-id))
|
|
||||||
|
|
||||||
(= bridge-name constants/bridge-name-erc-1155-transfer)
|
|
||||||
(assoc :ERC1155TransferTx
|
|
||||||
(assoc tx-data
|
|
||||||
:Recipient to-address
|
|
||||||
:TokenID token-id
|
|
||||||
:ChainID to-chain-id
|
|
||||||
:Amount amount-in))
|
|
||||||
|
|
||||||
(= bridge-name constants/bridge-name-transfer)
|
|
||||||
(assoc :TransferTx tx-data)
|
|
||||||
|
|
||||||
(= bridge-name constants/bridge-name-hop)
|
|
||||||
(assoc :HopTx
|
|
||||||
(assoc tx-data
|
|
||||||
:ChainID from-chain-id
|
|
||||||
:ChainIDTo to-chain-id
|
|
||||||
:Symbol token-id
|
|
||||||
:Recipient to-address
|
|
||||||
:Amount amount-in
|
|
||||||
:BonderFee bonder-fees))
|
|
||||||
|
|
||||||
(not (or (= bridge-name constants/bridge-name-erc-721-transfer)
|
|
||||||
(= bridge-name constants/bridge-name-transfer)
|
|
||||||
(= bridge-name constants/bridge-name-hop)))
|
|
||||||
(assoc :CbridgeTx
|
|
||||||
(assoc tx-data
|
|
||||||
:ChainID to-chain-id
|
|
||||||
:Symbol token-id
|
|
||||||
:Recipient to-address
|
|
||||||
:Amount amount-in)))))
|
|
||||||
|
|
||||||
(defn- multi-transaction-command
|
|
||||||
[{:keys [from-address to-address from-asset to-asset amount-out multi-transaction-type]
|
|
||||||
:or {multi-transaction-type constants/multi-transaction-type-unknown}}]
|
|
||||||
{:fromAddress from-address
|
|
||||||
:toAddress to-address
|
|
||||||
:fromAsset from-asset
|
|
||||||
:toAsset to-asset
|
|
||||||
:fromAmount amount-out
|
|
||||||
:type multi-transaction-type})
|
|
||||||
|
|
||||||
(rf/reg-event-fx :wallet/send-transaction
|
(rf/reg-event-fx :wallet/send-transaction
|
||||||
(fn [{:keys [db]} [sha3-pwd]]
|
(fn [{:keys [db]} [sha3-pwd]]
|
||||||
(let [routes (get-in db [:wallet :ui :send :route])
|
(let [routes (get-in db [:wallet :ui :send :route])
|
||||||
|
@ -731,7 +613,7 @@
|
||||||
(native-module/encode-transfer
|
(native-module/encode-transfer
|
||||||
(address/normalized-hex to-address)
|
(address/normalized-hex to-address)
|
||||||
(:amount-in route)))
|
(:amount-in route)))
|
||||||
base-path (transaction-path
|
base-path (utils/transaction-path
|
||||||
{:to-address to-address
|
{:to-address to-address
|
||||||
:from-address from-address
|
:from-address from-address
|
||||||
:route route
|
:route route
|
||||||
|
@ -743,7 +625,7 @@
|
||||||
:data data
|
:data data
|
||||||
:eth-transfer? eth-transfer?})]
|
:eth-transfer? eth-transfer?})]
|
||||||
(if approval-required?
|
(if approval-required?
|
||||||
[(approval-path {:route route
|
[(utils/approval-path {:route route
|
||||||
:token-address token-address
|
:token-address token-address
|
||||||
:from-address from-address
|
:from-address from-address
|
||||||
:to-address to-address})
|
:to-address to-address})
|
||||||
|
@ -751,7 +633,7 @@
|
||||||
[base-path]))))
|
[base-path]))))
|
||||||
routes)
|
routes)
|
||||||
request-params
|
request-params
|
||||||
[(multi-transaction-command
|
[(utils/multi-transaction-command
|
||||||
{:from-address from-address
|
{:from-address from-address
|
||||||
:to-address to-address
|
:to-address to-address
|
||||||
:from-asset token-id
|
:from-asset token-id
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
(ns status-im.contexts.wallet.signals
|
(ns status-im.contexts.wallet.signals
|
||||||
(:require
|
(:require
|
||||||
[oops.core :as oops]
|
[oops.core :as oops]
|
||||||
|
[status-im.constants :as constants]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
[utils.re-frame :as rf]
|
[utils.re-frame :as rf]
|
||||||
[utils.transforms :as transforms]))
|
[utils.transforms :as transforms]))
|
||||||
|
@ -9,8 +10,20 @@
|
||||||
:wallet/pending-transaction-status-changed-received
|
:wallet/pending-transaction-status-changed-received
|
||||||
(fn [{:keys [db]} [{:keys [message]}]]
|
(fn [{:keys [db]} [{:keys [message]}]]
|
||||||
(let [details (transforms/json->clj message)
|
(let [details (transforms/json->clj message)
|
||||||
tx-hash (:hash details)]
|
tx-hash (:hash details)
|
||||||
{:db (update-in db [:wallet :transactions tx-hash] assoc :status :confirmed :blocks 1)})))
|
tx-status (:status details)
|
||||||
|
status (cond
|
||||||
|
(= tx-status constants/transaction-status-success)
|
||||||
|
:confirmed
|
||||||
|
(= tx-status constants/transaction-status-pending)
|
||||||
|
:pending
|
||||||
|
(= tx-status constants/transaction-status-failed)
|
||||||
|
:failed)
|
||||||
|
swap-approval-transaction-id (get-in db [:wallet :ui :swap :approval-transaction-id])
|
||||||
|
swap-approval-transaction? (= swap-approval-transaction-id tx-hash)]
|
||||||
|
(cond-> {:db (update-in db [:wallet :transactions tx-hash] assoc :status status)}
|
||||||
|
swap-approval-transaction?
|
||||||
|
(assoc :fx [[:dispatch [:wallet.swap/approve-transaction-update status]]])))))
|
||||||
|
|
||||||
(rf/reg-event-fx
|
(rf/reg-event-fx
|
||||||
:wallet/signal-received
|
:wallet/signal-received
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
(ns status-im.contexts.wallet.swap.events
|
(ns status-im.contexts.wallet.swap.events
|
||||||
(:require [re-frame.core :as rf]
|
(:require [native-module.core :as native-module]
|
||||||
|
[re-frame.core :as rf]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
|
[status-im.contexts.wallet.common.utils :as utils]
|
||||||
[status-im.contexts.wallet.send.utils :as send-utils]
|
[status-im.contexts.wallet.send.utils :as send-utils]
|
||||||
[status-im.contexts.wallet.sheets.network-selection.view :as network-selection]
|
[status-im.contexts.wallet.sheets.network-selection.view :as network-selection]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
|
[utils.address :as address]
|
||||||
|
[utils.i18n :as i18n]
|
||||||
[utils.number]))
|
[utils.number]))
|
||||||
|
|
||||||
(rf/reg-event-fx :wallet.swap/start
|
(rf/reg-event-fx :wallet.swap/start
|
||||||
|
@ -152,8 +156,123 @@
|
||||||
:last-request-uuid
|
:last-request-uuid
|
||||||
:swap-proposal
|
:swap-proposal
|
||||||
:error-response
|
:error-response
|
||||||
:loading-swap-proposal?)}))
|
:loading-swap-proposal?
|
||||||
|
:approval-transaction-id)}))
|
||||||
|
|
||||||
(rf/reg-event-fx :wallet/clean-swap
|
(rf/reg-event-fx :wallet/clean-swap
|
||||||
(fn [{:keys [db]}]
|
(fn [{:keys [db]}]
|
||||||
{:db (update-in db [:wallet :ui] dissoc :swap)}))
|
{:db (update-in db [:wallet :ui] dissoc :swap)}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :wallet/swap-transaction
|
||||||
|
(fn [{:keys [db]} [sha3-pwd]]
|
||||||
|
(let [wallet-address (get-in db [:wallet :current-viewing-account-address])
|
||||||
|
{:keys [asset-to-pay swap-proposal network
|
||||||
|
approval-transaction-id]} (get-in db [:wallet :ui :swap])
|
||||||
|
transactions (get-in db [:wallet :transactions])
|
||||||
|
approval-transaction (when approval-transaction-id
|
||||||
|
(get transactions approval-transaction-id))
|
||||||
|
already-approved? (and approval-transaction
|
||||||
|
(= (:status approval-transaction) :confirmed))
|
||||||
|
approval-required? (and (:approval-required swap-proposal)
|
||||||
|
(not already-approved?))
|
||||||
|
multi-transaction-type constants/multi-transaction-type-swap
|
||||||
|
swap-chain-id (:chain-id network)
|
||||||
|
token-id (:symbol asset-to-pay)
|
||||||
|
erc20-transfer? (and asset-to-pay (not= token-id "ETH"))
|
||||||
|
eth-transfer? (and asset-to-pay (not erc20-transfer?))
|
||||||
|
token-address (when erc20-transfer?
|
||||||
|
(get-in asset-to-pay
|
||||||
|
[:balances-per-chain swap-chain-id :address]))
|
||||||
|
data (when erc20-transfer?
|
||||||
|
(native-module/encode-transfer
|
||||||
|
(address/normalized-hex wallet-address)
|
||||||
|
(:amount-in swap-proposal)))
|
||||||
|
transaction-paths (if approval-required?
|
||||||
|
[(utils/approval-path {:route swap-proposal
|
||||||
|
:token-address token-address
|
||||||
|
:from-address wallet-address
|
||||||
|
:to-address wallet-address})]
|
||||||
|
[(utils/transaction-path
|
||||||
|
{:to-address wallet-address
|
||||||
|
:from-address wallet-address
|
||||||
|
:route swap-proposal
|
||||||
|
:token-address token-address
|
||||||
|
:token-id token-id
|
||||||
|
:data data
|
||||||
|
:eth-transfer? eth-transfer?})])
|
||||||
|
request-params [(utils/multi-transaction-command
|
||||||
|
{:from-address wallet-address
|
||||||
|
:to-address wallet-address
|
||||||
|
:from-asset token-id
|
||||||
|
:to-asset token-id
|
||||||
|
:amount-out (if eth-transfer?
|
||||||
|
(:amount-out swap-proposal)
|
||||||
|
"0x0")
|
||||||
|
:multi-transaction-type multi-transaction-type})
|
||||||
|
transaction-paths
|
||||||
|
sha3-pwd]]
|
||||||
|
(log/info "multi transaction called")
|
||||||
|
{:json-rpc/call [{:method "wallet_createMultiTransaction"
|
||||||
|
:params request-params
|
||||||
|
:on-success (fn [result]
|
||||||
|
(when result
|
||||||
|
(rf/dispatch [:wallet.swap/add-authorized-transaction
|
||||||
|
{:transaction result
|
||||||
|
:approval-transaction? approval-required?}])
|
||||||
|
(rf/dispatch [:dismiss-modal
|
||||||
|
:screen/wallet.swap-set-spending-cap])
|
||||||
|
(rf/dispatch [:hide-bottom-sheet])))
|
||||||
|
:on-error (fn [error]
|
||||||
|
(log/error "failed swap transaction"
|
||||||
|
{:event :wallet/swap-transaction
|
||||||
|
:error error
|
||||||
|
:params request-params})
|
||||||
|
(rf/dispatch [:toasts/upsert
|
||||||
|
{:id :swap-transaction-error
|
||||||
|
:type :negative
|
||||||
|
:text (:message error)}]))}]})))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :wallet.swap/add-authorized-transaction
|
||||||
|
(fn [{:keys [db]} [{:keys [transaction approval-transaction?]}]]
|
||||||
|
(let [transaction-batch-id (:id transaction)
|
||||||
|
transaction-hashes (:hashes transaction)
|
||||||
|
transaction-ids (flatten (vals transaction-hashes))
|
||||||
|
transaction-details (send-utils/map-multitransaction-by-ids transaction-batch-id
|
||||||
|
transaction-hashes)]
|
||||||
|
{:db (cond-> db
|
||||||
|
:always (assoc-in [:wallet :transactions] transaction-details)
|
||||||
|
:always (assoc-in [:wallet :ui :swap :transaction-ids] transaction-ids)
|
||||||
|
approval-transaction? (assoc-in [:wallet :ui :swap :approval-transaction-id]
|
||||||
|
(first transaction-ids)))})))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :wallet.swap/approve-transaction-update
|
||||||
|
(fn [{:keys [db]} [status]]
|
||||||
|
(let [{:keys [amount asset-to-pay swap-proposal]} (get-in db [:wallet :ui :swap])
|
||||||
|
provider-name (:bridge-name swap-proposal)
|
||||||
|
token-symbol (:symbol asset-to-pay)
|
||||||
|
current-viewing-account-address (get-in db
|
||||||
|
[:wallet :current-viewing-account-address])
|
||||||
|
account-name (get-in db
|
||||||
|
[:wallet :accounts
|
||||||
|
current-viewing-account-address :name])
|
||||||
|
transaction-confirmed-or-failed? (#{:confirmed :failed} status)
|
||||||
|
transaction-confirmed? (= status :confirmed)]
|
||||||
|
(when transaction-confirmed-or-failed?
|
||||||
|
(cond-> {:fx
|
||||||
|
[[:dispatch
|
||||||
|
[:toasts/upsert
|
||||||
|
{:id :approve-transaction-update
|
||||||
|
:type (if transaction-confirmed? :positive :negative)
|
||||||
|
:text (if transaction-confirmed?
|
||||||
|
(i18n/label :t/spending-cap-set
|
||||||
|
{:amount amount
|
||||||
|
:token-symbol token-symbol
|
||||||
|
:provider-name provider-name
|
||||||
|
:account-name account-name})
|
||||||
|
(i18n/label :t/spending-cap-failed
|
||||||
|
{:amount amount
|
||||||
|
:token-symbol token-symbol
|
||||||
|
:provider-name provider-name
|
||||||
|
:account-name account-name}))}]]]}
|
||||||
|
(not transaction-confirmed?)
|
||||||
|
(assoc :db (update-in db [:wallet :ui :swap] dissoc :approval-transaction-id)))))))
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
(ns status-im.contexts.wallet.swap.set-spending-cap.view
|
(ns status-im.contexts.wallet.swap.set-spending-cap.view
|
||||||
(:require
|
(:require
|
||||||
|
[native-module.core :as native-module]
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
[quo.foundations.resources :as resources]
|
[quo.foundations.resources :as resources]
|
||||||
[quo.theme :as quo.theme]
|
[quo.theme :as quo.theme]
|
||||||
|
@ -7,14 +8,30 @@
|
||||||
[status-im.common.events-helper :as events-helper]
|
[status-im.common.events-helper :as events-helper]
|
||||||
[status-im.common.floating-button-page.view :as floating-button-page]
|
[status-im.common.floating-button-page.view :as floating-button-page]
|
||||||
[status-im.common.standard-authentication.core :as standard-auth]
|
[status-im.common.standard-authentication.core :as standard-auth]
|
||||||
|
[status-im.constants :as constants]
|
||||||
[status-im.contexts.wallet.common.utils.external-links :as external-links]
|
[status-im.contexts.wallet.common.utils.external-links :as external-links]
|
||||||
[status-im.contexts.wallet.swap.set-spending-cap.style :as style]
|
[status-im.contexts.wallet.swap.set-spending-cap.style :as style]
|
||||||
[utils.address :as address-utils]
|
[utils.address :as address-utils]
|
||||||
|
[utils.hex :as hex]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.number :as number]
|
||||||
|
[utils.re-frame :as rf]
|
||||||
|
[utils.security.core :as security]))
|
||||||
|
|
||||||
(defn- swap-title
|
(defn- swap-title
|
||||||
[{:keys [pay-token-symbol pay-amount account provider]}]
|
[]
|
||||||
|
(let [asset-to-pay (rf/sub [:wallet/swap-asset-to-pay])
|
||||||
|
amount-in (rf/sub [:wallet/swap-proposal-amount-in])
|
||||||
|
account (rf/sub [:wallet/current-viewing-account])
|
||||||
|
provider (rf/sub [:wallet/swap-proposal-provider])
|
||||||
|
pay-token-symbol (:symbol asset-to-pay)
|
||||||
|
pay-token-decimals (:decimals asset-to-pay)
|
||||||
|
pay-amount (when amount-in
|
||||||
|
(number/convert-to-whole-number
|
||||||
|
(native-module/hex-to-number
|
||||||
|
(hex/normalize-hex
|
||||||
|
amount-in))
|
||||||
|
pay-token-decimals))]
|
||||||
[rn/view {:style style/content-container}
|
[rn/view {:style style/content-container}
|
||||||
[rn/view {:style {:flex-direction :row}}
|
[rn/view {:style {:flex-direction :row}}
|
||||||
[quo/text
|
[quo/text
|
||||||
|
@ -51,10 +68,21 @@
|
||||||
{:label (:name account)
|
{:label (:name account)
|
||||||
:type :account
|
:type :account
|
||||||
:emoji (:emoji account)
|
:emoji (:emoji account)
|
||||||
:customization-color (:color account)}]]])
|
:customization-color (:color account)}]]]))
|
||||||
|
|
||||||
(defn- spending-cap-section
|
(defn- spending-cap-section
|
||||||
[{:keys [theme amount token-symbol]}]
|
[]
|
||||||
|
(let [theme (quo.theme/use-theme)
|
||||||
|
asset-to-pay (rf/sub [:wallet/swap-asset-to-pay])
|
||||||
|
amount-in (rf/sub [:wallet/swap-proposal-amount-in])
|
||||||
|
pay-token-symbol (:symbol asset-to-pay)
|
||||||
|
pay-token-decimals (:decimals asset-to-pay)
|
||||||
|
pay-amount (when amount-in
|
||||||
|
(number/convert-to-whole-number
|
||||||
|
(native-module/hex-to-number
|
||||||
|
(hex/normalize-hex
|
||||||
|
amount-in))
|
||||||
|
pay-token-decimals))]
|
||||||
[rn/view {:style style/summary-section-container}
|
[rn/view {:style style/summary-section-container}
|
||||||
[quo/text
|
[quo/text
|
||||||
{:size :paragraph-2
|
{:size :paragraph-2
|
||||||
|
@ -65,11 +93,23 @@
|
||||||
[quo/approval-info
|
[quo/approval-info
|
||||||
{:type :spending-cap
|
{:type :spending-cap
|
||||||
:unlimited-icon? false
|
:unlimited-icon? false
|
||||||
:label (str amount " " token-symbol)
|
:label (str pay-amount " " pay-token-symbol)
|
||||||
:avatar-props {:token token-symbol}}]])
|
:avatar-props {:token pay-token-symbol}}]]))
|
||||||
|
|
||||||
(defn- account-section
|
(defn- account-section
|
||||||
[{:keys [theme account pay-token-symbol pay-token-amount]}]
|
[]
|
||||||
|
(let [theme (quo.theme/use-theme)
|
||||||
|
asset-to-pay (rf/sub [:wallet/swap-asset-to-pay])
|
||||||
|
amount-in (rf/sub [:wallet/swap-proposal-amount-in])
|
||||||
|
account (rf/sub [:wallet/current-viewing-account])
|
||||||
|
pay-token-symbol (:symbol asset-to-pay)
|
||||||
|
pay-token-decimals (:decimals asset-to-pay)
|
||||||
|
pay-amount (when amount-in
|
||||||
|
(number/convert-to-whole-number
|
||||||
|
(native-module/hex-to-number
|
||||||
|
(hex/normalize-hex
|
||||||
|
amount-in))
|
||||||
|
pay-token-decimals))]
|
||||||
[rn/view {:style style/summary-section-container}
|
[rn/view {:style style/summary-section-container}
|
||||||
[quo/text
|
[quo/text
|
||||||
{:size :paragraph-2
|
{:size :paragraph-2
|
||||||
|
@ -82,9 +122,9 @@
|
||||||
:unlimited-icon? false
|
:unlimited-icon? false
|
||||||
:label (:name account)
|
:label (:name account)
|
||||||
:description (address-utils/get-short-wallet-address (:address account))
|
:description (address-utils/get-short-wallet-address (:address account))
|
||||||
:tag-label (str pay-token-amount " " pay-token-symbol)
|
:tag-label (str pay-amount " " pay-token-symbol)
|
||||||
:avatar-props {:emoji (:emoji account)
|
:avatar-props {:emoji (:emoji account)
|
||||||
:customization-color (:color account)}}]])
|
:customization-color (:color account)}}]]))
|
||||||
|
|
||||||
(defn- on-option-press
|
(defn- on-option-press
|
||||||
[{:keys [chain-id contract-address]}]
|
[{:keys [chain-id contract-address]}]
|
||||||
|
@ -103,7 +143,13 @@
|
||||||
:right-icon :i/external}]]])}]))
|
:right-icon :i/external}]]])}]))
|
||||||
|
|
||||||
(defn- token-section
|
(defn- token-section
|
||||||
[{:keys [theme token-address token-symbol network-chain-id]}]
|
[]
|
||||||
|
(let [theme (quo.theme/use-theme)
|
||||||
|
asset-to-pay (rf/sub [:wallet/swap-asset-to-pay])
|
||||||
|
network (rf/sub [:wallet/swap-network])
|
||||||
|
pay-token-symbol (:symbol asset-to-pay)
|
||||||
|
network-chain-id (:chain-id network)
|
||||||
|
pay-token-address (get-in asset-to-pay [:balances-per-chain network-chain-id :address])]
|
||||||
[rn/view {:style style/summary-section-container}
|
[rn/view {:style style/summary-section-container}
|
||||||
[quo/text
|
[quo/text
|
||||||
{:size :paragraph-2
|
{:size :paragraph-2
|
||||||
|
@ -115,14 +161,18 @@
|
||||||
{:type :token-contract
|
{:type :token-contract
|
||||||
:option-icon :i/options
|
:option-icon :i/options
|
||||||
:on-option-press #(on-option-press {:chain-id network-chain-id
|
:on-option-press #(on-option-press {:chain-id network-chain-id
|
||||||
:contract-address token-address})
|
:contract-address pay-token-address})
|
||||||
:unlimited-icon? false
|
:unlimited-icon? false
|
||||||
:label token-symbol
|
:label pay-token-symbol
|
||||||
:description (address-utils/get-short-wallet-address token-address)
|
:description (address-utils/get-short-wallet-address pay-token-address)
|
||||||
:avatar-props {:token token-symbol}}]])
|
:avatar-props {:token pay-token-symbol}}]]))
|
||||||
|
|
||||||
(defn- spender-contract-section
|
(defn- spender-contract-section
|
||||||
[{:keys [theme provider network-chain-id]}]
|
[]
|
||||||
|
(let [theme (quo.theme/use-theme)
|
||||||
|
network (rf/sub [:wallet/swap-network])
|
||||||
|
provider (rf/sub [:wallet/swap-proposal-provider])
|
||||||
|
network-chain-id (:chain-id network)]
|
||||||
[rn/view {:style style/summary-section-container}
|
[rn/view {:style style/summary-section-container}
|
||||||
[quo/text
|
[quo/text
|
||||||
{:size :paragraph-2
|
{:size :paragraph-2
|
||||||
|
@ -138,7 +188,7 @@
|
||||||
:unlimited-icon? false
|
:unlimited-icon? false
|
||||||
:label (:full-name provider)
|
:label (:full-name provider)
|
||||||
:description (address-utils/get-short-wallet-address (:contract-address provider))
|
:description (address-utils/get-short-wallet-address (:contract-address provider))
|
||||||
:avatar-props {:image (resources/get-network (:name provider))}}]])
|
:avatar-props {:image (resources/get-network (:name provider))}}]]))
|
||||||
|
|
||||||
(defn- data-item
|
(defn- data-item
|
||||||
[{:keys [network-image title subtitle size loading?]}]
|
[{:keys [network-image title subtitle size loading?]}]
|
||||||
|
@ -154,7 +204,12 @@
|
||||||
:size size}])
|
:size size}])
|
||||||
|
|
||||||
(defn- transaction-details
|
(defn- transaction-details
|
||||||
[{:keys [estimated-time-min max-fees network loading-fees?]}]
|
[]
|
||||||
|
(let [network (rf/sub [:wallet/swap-network])
|
||||||
|
max-fees (rf/sub [:wallet/wallet-swap-proposal-fee-fiat-formatted
|
||||||
|
constants/token-for-fees-symbol])
|
||||||
|
loading-fees? (rf/sub [:wallet/swap-loading-fees?])
|
||||||
|
estimated-time (rf/sub [:wallet/swap-proposal-estimated-time])]
|
||||||
[rn/view {:style style/details-container}
|
[rn/view {:style style/details-container}
|
||||||
[:<>
|
[:<>
|
||||||
[data-item
|
[data-item
|
||||||
|
@ -163,47 +218,38 @@
|
||||||
:network-image (:source network)}]
|
:network-image (:source network)}]
|
||||||
[data-item
|
[data-item
|
||||||
{:title (i18n/label :t/est-time)
|
{:title (i18n/label :t/est-time)
|
||||||
:subtitle (i18n/label :t/time-in-mins {:minutes (str estimated-time-min)})}]
|
:subtitle (i18n/label :t/time-in-mins {:minutes (str estimated-time)})}]
|
||||||
[data-item
|
[data-item
|
||||||
{:title (i18n/label :t/max-fees)
|
{:title (i18n/label :t/max-fees)
|
||||||
:subtitle max-fees
|
:subtitle max-fees
|
||||||
:loading? loading-fees?
|
:loading? loading-fees?
|
||||||
:size :small}]]])
|
:size :small}]]]))
|
||||||
|
|
||||||
(defn footer
|
(defn- slide-button
|
||||||
[{:keys [estimated-time-min native-currency-symbol network theme account-color loading-fees?]}]
|
[]
|
||||||
(let [fee-formatted (rf/sub [:wallet/wallet-send-fee-fiat-formatted native-currency-symbol])
|
(let [loading-fees? (rf/sub [:wallet/swap-loading-fees?])
|
||||||
on-auth-success (rn/use-callback #(js/alert "Not implemented yet"))]
|
account (rf/sub [:wallet/current-viewing-account])
|
||||||
[rn/view {:style {:margin-bottom -10}}
|
on-auth-success (rn/use-callback #(rf/dispatch
|
||||||
[transaction-details
|
[:wallet/swap-transaction
|
||||||
{:estimated-time-min estimated-time-min
|
(security/safe-unmask-data %)]))]
|
||||||
:max-fees fee-formatted
|
|
||||||
:network network
|
|
||||||
:loading-fees? loading-fees?
|
|
||||||
:theme theme}]
|
|
||||||
[standard-auth/slide-button
|
[standard-auth/slide-button
|
||||||
{:size :size-48
|
{:size :size-48
|
||||||
:track-text (i18n/label :t/slide-to-swap)
|
:track-text (i18n/label :t/slide-to-swap)
|
||||||
:container-style {:z-index 2}
|
:container-style {:z-index 2}
|
||||||
:customization-color account-color
|
:customization-color (:color account)
|
||||||
:disabled? loading-fees?
|
:disabled? loading-fees?
|
||||||
:on-auth-success on-auth-success
|
:on-auth-success on-auth-success
|
||||||
:auth-button-label (i18n/label :t/confirm)}]]))
|
:auth-button-label (i18n/label :t/confirm)}]))
|
||||||
|
|
||||||
|
(defn- footer
|
||||||
|
[]
|
||||||
|
[rn/view {:style {:margin-bottom -10}}
|
||||||
|
[transaction-details]
|
||||||
|
[slide-button]])
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[]
|
[]
|
||||||
(let [theme (quo.theme/use-theme)
|
(let [account (rf/sub [:wallet/current-viewing-account])]
|
||||||
swap-transaction-data (rf/sub [:wallet/swap])
|
|
||||||
{:keys [asset-to-pay network pay-amount
|
|
||||||
providers swap-proposal
|
|
||||||
loading-fees?]} swap-transaction-data
|
|
||||||
estimated-time-min (:estimated-time swap-proposal)
|
|
||||||
pay-token-symbol (:symbol asset-to-pay)
|
|
||||||
pay-token-address (:address asset-to-pay)
|
|
||||||
native-currency-symbol (get-in swap-proposal [:from :native-currency-symbol])
|
|
||||||
account (rf/sub [:wallet/current-viewing-account])
|
|
||||||
account-color (:color account)
|
|
||||||
provider (first providers)]
|
|
||||||
[rn/view {:style style/container}
|
[rn/view {:style style/container}
|
||||||
[floating-button-page/view
|
[floating-button-page/view
|
||||||
{:footer-container-padding 0
|
{:footer-container-padding 0
|
||||||
|
@ -213,37 +259,12 @@
|
||||||
:margin-top 8
|
:margin-top 8
|
||||||
:background :blur
|
:background :blur
|
||||||
:accessibility-label :top-bar}]
|
:accessibility-label :top-bar}]
|
||||||
:footer [footer
|
:footer [footer]
|
||||||
{:estimated-time-min estimated-time-min
|
|
||||||
:native-currency-symbol native-currency-symbol
|
|
||||||
:network network
|
|
||||||
:account-color account-color
|
|
||||||
:provider provider
|
|
||||||
:loading-fees? loading-fees?
|
|
||||||
:theme theme}]
|
|
||||||
:gradient-cover? true
|
:gradient-cover? true
|
||||||
:customization-color account-color}
|
:customization-color (:color account)}
|
||||||
[:<>
|
[:<>
|
||||||
[swap-title
|
[swap-title]
|
||||||
{:pay-token-symbol pay-token-symbol
|
[spending-cap-section]
|
||||||
:pay-amount pay-amount
|
[account-section]
|
||||||
:account account
|
[token-section]
|
||||||
:provider provider}]
|
[spender-contract-section]]]]))
|
||||||
[spending-cap-section
|
|
||||||
{:token-symbol pay-token-symbol
|
|
||||||
:amount pay-amount
|
|
||||||
:theme theme}]
|
|
||||||
[account-section
|
|
||||||
{:account account
|
|
||||||
:pay-token-symbol pay-token-symbol
|
|
||||||
:pay-token-amount pay-amount
|
|
||||||
:theme theme}]
|
|
||||||
[token-section
|
|
||||||
{:token-symbol pay-token-symbol
|
|
||||||
:token-address pay-token-address
|
|
||||||
:network-chain-id (:chain-id network)
|
|
||||||
:theme theme}]
|
|
||||||
[spender-contract-section
|
|
||||||
{:provider provider
|
|
||||||
:network-chain-id (:chain-id network)
|
|
||||||
:theme theme}]]]]))
|
|
||||||
|
|
|
@ -76,6 +76,7 @@
|
||||||
approval-required (rf/sub [:wallet/swap-proposal-approval-required])
|
approval-required (rf/sub [:wallet/swap-proposal-approval-required])
|
||||||
approval-amount-required (rf/sub [:wallet/swap-proposal-approval-amount-required])
|
approval-amount-required (rf/sub [:wallet/swap-proposal-approval-amount-required])
|
||||||
currency-symbol (rf/sub [:profile/currency-symbol])
|
currency-symbol (rf/sub [:profile/currency-symbol])
|
||||||
|
approval-transaction-status (rf/sub [:wallet/swap-approval-transaction-status])
|
||||||
pay-input-num-value (controlled-input/numeric-value input-state)
|
pay-input-num-value (controlled-input/numeric-value input-state)
|
||||||
pay-input-amount (controlled-input/input-value input-state)
|
pay-input-amount (controlled-input/input-value input-state)
|
||||||
pay-token-symbol (:symbol asset-to-pay)
|
pay-token-symbol (:symbol asset-to-pay)
|
||||||
|
@ -141,7 +142,11 @@
|
||||||
{:number available-crypto-limit
|
{:number available-crypto-limit
|
||||||
:token-symbol pay-token-symbol})
|
:token-symbol pay-token-symbol})
|
||||||
:networks [{:source (:source network)}]}
|
:networks [{:source (:source network)}]}
|
||||||
:approval-label-props {:status :approve
|
:approval-label-props {:status (case approval-transaction-status
|
||||||
|
:pending :approving
|
||||||
|
:confirmed :approved
|
||||||
|
:finalised :approved
|
||||||
|
:approve)
|
||||||
:token-value approval-amount-required-num
|
:token-value approval-amount-required-num
|
||||||
:button-props {:on-press on-approve-press}
|
:button-props {:on-press on-approve-press}
|
||||||
:customization-color account-color
|
:customization-color account-color
|
||||||
|
@ -203,12 +208,14 @@
|
||||||
swap-proposal (rf/sub [:wallet/swap-proposal])
|
swap-proposal (rf/sub [:wallet/swap-proposal])
|
||||||
loading-fees? (rf/sub [:wallet/swap-loading-fees?])
|
loading-fees? (rf/sub [:wallet/swap-loading-fees?])
|
||||||
loading-swap-proposal? (rf/sub [:wallet/swap-loading-swap-proposal?])
|
loading-swap-proposal? (rf/sub [:wallet/swap-loading-swap-proposal?])
|
||||||
approval-required? (rf/sub [:wallet/swap-proposal-approval-required])]
|
approval-required? (rf/sub [:wallet/swap-proposal-approval-required])
|
||||||
|
approval-transaction-status (rf/sub [:wallet/swap-approval-transaction-status])]
|
||||||
[quo/bottom-actions
|
[quo/bottom-actions
|
||||||
{:actions :one-action
|
{:actions :one-action
|
||||||
:button-one-label (i18n/label :t/review-swap)
|
:button-one-label (i18n/label :t/review-swap)
|
||||||
:button-one-props {:disabled? (or (not swap-proposal)
|
:button-one-props {:disabled? (or (not swap-proposal)
|
||||||
approval-required?
|
(and approval-required?
|
||||||
|
(not= approval-transaction-status :confirmed))
|
||||||
loading-swap-proposal?
|
loading-swap-proposal?
|
||||||
loading-fees?)
|
loading-fees?)
|
||||||
:customization-color account-color
|
:customization-color account-color
|
||||||
|
@ -262,7 +269,7 @@
|
||||||
:on-max-press #(set-pay-input-state pay-token-balance-selected-chain)
|
:on-max-press #(set-pay-input-state pay-token-balance-selected-chain)
|
||||||
:input-focused? pay-input-focused?
|
:input-focused? pay-input-focused?
|
||||||
:on-token-press #(js/alert "Token Pressed")
|
:on-token-press #(js/alert "Token Pressed")
|
||||||
:on-approve-press #(js/alert "Approve Pressed")
|
:on-approve-press #(rf/dispatch [:open-modal :screen/wallet.swap-set-spending-cap])
|
||||||
:on-input-focus #(set-pay-input-focused? true)}]
|
:on-input-focus #(set-pay-input-focused? true)}]
|
||||||
[swap-order-button {:on-press #(js/alert "Swap Order Pressed")}]
|
[swap-order-button {:on-press #(js/alert "Swap Order Pressed")}]
|
||||||
[receive-token-input
|
[receive-token-input
|
||||||
|
|
|
@ -80,6 +80,18 @@
|
||||||
:<- [:wallet/swap]
|
:<- [:wallet/swap]
|
||||||
:-> :loading-fees?)
|
:-> :loading-fees?)
|
||||||
|
|
||||||
|
(rf/reg-sub
|
||||||
|
:wallet/swap-approval-transaction-id
|
||||||
|
:<- [:wallet/swap]
|
||||||
|
:-> :approval-transaction-id)
|
||||||
|
|
||||||
|
(rf/reg-sub
|
||||||
|
:wallet/swap-approval-transaction-status
|
||||||
|
:<- [:wallet/transactions]
|
||||||
|
:<- [:wallet/swap-approval-transaction-id]
|
||||||
|
(fn [[transactions approval-transaction-id]]
|
||||||
|
(get-in transactions [approval-transaction-id :status])))
|
||||||
|
|
||||||
(rf/reg-sub
|
(rf/reg-sub
|
||||||
:wallet/swap-proposal
|
:wallet/swap-proposal
|
||||||
:<- [:wallet/swap]
|
:<- [:wallet/swap]
|
||||||
|
@ -95,6 +107,19 @@
|
||||||
:<- [:wallet/swap-proposal]
|
:<- [:wallet/swap-proposal]
|
||||||
:-> :amount-out)
|
:-> :amount-out)
|
||||||
|
|
||||||
|
(rf/reg-sub
|
||||||
|
:wallet/swap-proposal-amount-in
|
||||||
|
:<- [:wallet/swap-proposal]
|
||||||
|
:-> :amount-in)
|
||||||
|
|
||||||
|
(rf/reg-sub
|
||||||
|
:wallet/swap-proposal-provider
|
||||||
|
:<- [:wallet/swap-proposal]
|
||||||
|
(fn [swap-proposal]
|
||||||
|
(let [bridge-name (:bridge-name swap-proposal)
|
||||||
|
provider-key (keyword (string/lower-case bridge-name))]
|
||||||
|
(get constants/swap-providers provider-key))))
|
||||||
|
|
||||||
(rf/reg-sub
|
(rf/reg-sub
|
||||||
:wallet/swap-proposal-approval-required
|
:wallet/swap-proposal-approval-required
|
||||||
:<- [:wallet/swap-proposal]
|
:<- [:wallet/swap-proposal]
|
||||||
|
@ -105,6 +130,11 @@
|
||||||
:<- [:wallet/swap-proposal]
|
:<- [:wallet/swap-proposal]
|
||||||
:-> :approval-amount-required)
|
:-> :approval-amount-required)
|
||||||
|
|
||||||
|
(rf/reg-sub
|
||||||
|
:wallet/swap-proposal-estimated-time
|
||||||
|
:<- [:wallet/swap-proposal]
|
||||||
|
:-> :estimated-time)
|
||||||
|
|
||||||
(rf/reg-sub
|
(rf/reg-sub
|
||||||
:wallet/wallet-swap-proposal-fee-fiat-formatted
|
:wallet/wallet-swap-proposal-fee-fiat-formatted
|
||||||
:<- [:wallet/current-viewing-account]
|
:<- [:wallet/current-viewing-account]
|
||||||
|
|
|
@ -2313,6 +2313,8 @@
|
||||||
"specify-symbol": "Specify a symbol",
|
"specify-symbol": "Specify a symbol",
|
||||||
"spender-contract": "Spender contract",
|
"spender-contract": "Spender contract",
|
||||||
"spending-cap": "Spending cap",
|
"spending-cap": "Spending cap",
|
||||||
|
"spending-cap-failed": "Spending cap failed: {{amount}} {{token-symbol}} for {{provider-name}} in {{account-name}}",
|
||||||
|
"spending-cap-set": "Spending cap set: {{amount}} {{token-symbol}} for {{provider-name}} in {{account-name}}",
|
||||||
"start-chat": "Start chat",
|
"start-chat": "Start chat",
|
||||||
"start-conversation": "Start conversation",
|
"start-conversation": "Start conversation",
|
||||||
"start-group-chat": "Start group chat",
|
"start-group-chat": "Start group chat",
|
||||||
|
|
Loading…
Reference in New Issue