fix(wallet): fix bridge transactions (#20902)

* fix(wallet): fix bridge transactions

Signed-off-by: Brian Sztamfater <brian@status.im>

* add support for approve transactions

Signed-off-by: Brian Sztamfater <brian@status.im>

---------

Signed-off-by: Brian Sztamfater <brian@status.im>
This commit is contained in:
Brian Sztamfater 2024-07-30 11:02:11 -03:00 committed by GitHub
parent 99ccbc3383
commit 59ceddbaad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 88 additions and 40 deletions

View File

@ -387,6 +387,11 @@
(log/debug "[native-module] encode-transfer") (log/debug "[native-module] encode-transfer")
(.encodeTransfer ^js (encryption) to-norm amount-hex)) (.encodeTransfer ^js (encryption) to-norm amount-hex))
(defn encode-function-call
[method params]
(log/debug "[native-module] encode-function-call")
(.encodeFunctionCall ^js (encryption) method (types/clj->json params)))
(defn decode-parameters (defn decode-parameters
[bytes-string types] [bytes-string types]
(log/debug "[native-module] decode-parameters") (log/debug "[native-module] decode-parameters")

View File

@ -554,6 +554,14 @@
(def ^:const send-type-erc-721-transfer 6) (def ^:const send-type-erc-721-transfer 6)
(def ^:const send-type-erc-1155-transfer 7) (def ^:const send-type-erc-1155-transfer 7)
(def ^:const multi-transaction-type-send 0)
(def ^:const multi-transaction-type-approve 1)
(def ^:const multi-transaction-type-bridge 2)
(def ^:const multi-transaction-type-swap 3)
(def ^:const multi-transaction-type-unknown 255)
(def ^:const contract-function-signature-erc20-approve "approve(address,uint256)")
(def ^:const bridge-name-transfer "Transfer") (def ^:const bridge-name-transfer "Transfer")
(def ^:const bridge-name-erc-721-transfer "ERC721Transfer") (def ^:const bridge-name-erc-721-transfer "ERC721Transfer")
(def ^:const bridge-name-erc-1155-transfer "ERC1155Transfer") (def ^:const bridge-name-erc-1155-transfer "ERC1155Transfer")

View File

@ -274,7 +274,7 @@
(rf/reg-event-fx :wallet/get-keypairs get-keypairs) (rf/reg-event-fx :wallet/get-keypairs get-keypairs)
(rf/reg-event-fx :wallet/bridge-select-token (rf/reg-event-fx :wallet/bridge-select-token
(fn [{:keys [db]} [{:keys [token token-symbol stack-id]}]] (fn [{:keys [db]} [{:keys [token token-symbol stack-id start-flow?]}]]
(let [missing-recipient? (-> db :wallet :ui :send :to-address nil?) (let [missing-recipient? (-> db :wallet :ui :send :to-address nil?)
to-address (-> db :wallet :current-viewing-account-address)] to-address (-> db :wallet :current-viewing-account-address)]
{:db (cond-> db {:db (cond-> db
@ -285,7 +285,7 @@
:fx [[:dispatch :fx [[:dispatch
[:wallet/wizard-navigate-forward [:wallet/wizard-navigate-forward
{:current-screen stack-id {:current-screen stack-id
:start-flow? true :start-flow? start-flow?
:flow-id :wallet-bridge-flow}]]]}))) :flow-id :wallet-bridge-flow}]]]})))
(rf/reg-event-fx :wallet/start-bridge (rf/reg-event-fx :wallet/start-bridge

View File

@ -10,6 +10,7 @@
[status-im.contexts.wallet.send.utils :as send-utils] [status-im.contexts.wallet.send.utils :as send-utils]
[taoensso.timbre :as log] [taoensso.timbre :as log]
[utils.address :as address] [utils.address :as address]
[utils.hex :as utils.hex]
[utils.money :as money] [utils.money :as money]
[utils.number] [utils.number]
[utils.re-frame :as rf])) [utils.re-frame :as rf]))
@ -402,11 +403,11 @@
receiver-networks))) receiver-networks)))
network-chain-ids)) network-chain-ids))
from-locked-amount (update-vals from-locked-amounts to-hex) from-locked-amount (update-vals from-locked-amounts to-hex)
transaction-type (case tx-type send-type (case tx-type
:tx/collectible-erc-721 constants/send-type-erc-721-transfer :tx/collectible-erc-721 constants/send-type-erc-721-transfer
:tx/collectible-erc-1155 constants/send-type-erc-1155-transfer :tx/collectible-erc-1155 constants/send-type-erc-1155-transfer
:tx/bridge constants/send-type-bridge :tx/bridge constants/send-type-bridge
constants/send-type-transfer) constants/send-type-transfer)
balances-per-chain (when token (:balances-per-chain token)) balances-per-chain (when token (:balances-per-chain token))
sender-token-available-networks-for-suggested-routes sender-token-available-networks-for-suggested-routes
(when token (when token
@ -447,7 +448,7 @@
:tx-type tx-type :tx-type tx-type
:receiver? true})) :receiver? true}))
params [{:uuid (str (random-uuid)) params [{:uuid (str (random-uuid))
:sendType transaction-type :sendType send-type
:addrFrom from-address :addrFrom from-address
:addrTo to-address :addrTo to-address
:amountIn amount-in :amountIn amount-in
@ -583,6 +584,29 @@
:gwei :gwei
gas-price)))))) 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 (defn- transaction-path
[{:keys [from-address to-address token-id token-address route data eth-transfer?]}] [{:keys [from-address to-address token-id token-address route data eth-transfer?]}]
(let [{:keys [bridge-name amount-in bonder-fees from (let [{:keys [bridge-name amount-in bonder-fees from
@ -619,7 +643,8 @@
(= bridge-name constants/bridge-name-hop) (= bridge-name constants/bridge-name-hop)
(assoc :HopTx (assoc :HopTx
(assoc tx-data (assoc tx-data
:ChainID to-chain-id :ChainID from-chain-id
:ChainIDTo to-chain-id
:Symbol token-id :Symbol token-id
:Recipient to-address :Recipient to-address
:Amount amount-in :Amount amount-in
@ -636,14 +661,14 @@
:Amount amount-in))))) :Amount amount-in)))))
(defn- multi-transaction-command (defn- multi-transaction-command
[{:keys [from-address to-address from-asset to-asset amount-out transfer-type] [{:keys [from-address to-address from-asset to-asset amount-out multi-transaction-type]
:or {transfer-type constants/send-type-transfer}}] :or {multi-transaction-type constants/multi-transaction-type-unknown}}]
{:fromAddress from-address {:fromAddress from-address
:toAddress to-address :toAddress to-address
:fromAsset from-asset :fromAsset from-asset
:toAsset to-asset :toAsset to-asset
:fromAmount amount-out :fromAmount amount-out
:type transfer-type}) :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]]
@ -651,11 +676,9 @@
first-route (first routes) first-route (first routes)
from-address (get-in db [:wallet :current-viewing-account-address]) from-address (get-in db [:wallet :current-viewing-account-address])
transaction-type (get-in db [:wallet :ui :send :tx-type]) transaction-type (get-in db [:wallet :ui :send :tx-type])
transaction-type-param (case transaction-type multi-transaction-type (if (= :tx/bridge transaction-type)
:tx/collectible-erc-721 constants/send-type-erc-721-transfer constants/multi-transaction-type-bridge
:tx/collectible-erc-1155 constants/send-type-erc-1155-transfer constants/multi-transaction-type-send)
:tx/bridge constants/send-type-bridge
constants/send-type-transfer)
token (get-in db [:wallet :ui :send :token]) token (get-in db [:wallet :ui :send :token])
collectible (get-in db [:wallet :ui :send :collectible]) collectible (get-in db [:wallet :ui :send :collectible])
first-route-from-chain-id (get-in first-route [:from :chain-id]) first-route-from-chain-id (get-in first-route [:from :chain-id])
@ -670,30 +693,41 @@
erc20-transfer? erc20-transfer?
(get-in token [:balances-per-chain first-route-from-chain-id :address])) (get-in token [:balances-per-chain first-route-from-chain-id :address]))
to-address (get-in db [:wallet :ui :send :to-address]) to-address (get-in db [:wallet :ui :send :to-address])
transaction-paths (mapv (fn [route] transaction-paths (into []
(let [data (when erc20-transfer? (mapcat
(native-module/encode-transfer (fn [route]
(address/normalized-hex to-address) (let [approval-required? (:approval-required route)
(:amount-in route)))] data (when erc20-transfer?
(transaction-path {:to-address to-address (native-module/encode-transfer
:from-address from-address (address/normalized-hex to-address)
:route route (:amount-in route)))
:token-address token-address base-path (transaction-path
:token-id (if collectible {:to-address to-address
(money/to-hex (js/parseInt :from-address from-address
token-id)) :route route
token-id) :token-address token-address
:data data :token-id (if collectible
:eth-transfer? eth-transfer?}))) (money/to-hex
(js/parseInt token-id))
token-id)
:data data
:eth-transfer? eth-transfer?})]
(if approval-required?
[(approval-path {:route route
:token-address token-address
:from-address from-address
:to-address to-address})
base-path]
[base-path]))))
routes) routes)
request-params request-params
[(multi-transaction-command [(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
:to-asset token-id :to-asset token-id
:amount-out (if eth-transfer? (:amount-out first-route) "0x0") :amount-out (if eth-transfer? (:amount-out first-route) "0x0")
:transfer-type transaction-type-param}) :multi-transaction-type multi-transaction-type})
transaction-paths transaction-paths
sha3-pwd]] sha3-pwd]]
(log/info "multi transaction called") (log/info "multi transaction called")

View File

@ -124,7 +124,7 @@
:customization-color (:color account)}]])])) :customization-color (:color account)}]])]))
(defn- user-summary (defn- user-summary
[{:keys [account-props theme label accessibility-label summary-type recipient account-to?]}] [{:keys [account-props theme label accessibility-label summary-type recipient bridge-tx? account-to?]}]
(let [network-values (rf/sub [:wallet/network-values account-to?]) (let [network-values (rf/sub [:wallet/network-values account-to?])
summary-info-type (case (:recipient-type recipient) summary-info-type (case (:recipient-type recipient)
:saved-address :saved-account :saved-address :saved-account
@ -144,7 +144,7 @@
:networks? true :networks? true
:values network-values :values network-values
:account-props (cond-> account-props :account-props (cond-> account-props
account-to? (and account-to? (not bridge-tx?))
(assoc (assoc
:size 32 :size 32
:name (:label recipient) :name (:label recipient)
@ -298,5 +298,6 @@
from-account-props from-account-props
user-props) user-props)
:recipient recipient :recipient recipient
:bridge-tx? (= transaction-type :tx/bridge)
:account-to? true :account-to? true
:theme theme}]]]])))) :theme theme}]]]]))))