Skip to content

Commit 11156eb

Browse files
feat: approve token transactions on swap
Signed-off-by: Brian Sztamfater <[email protected]>
1 parent e95962f commit 11156eb

File tree

9 files changed

+518
-319
lines changed

9 files changed

+518
-319
lines changed

src/status_im/constants.cljs

+7-1
Original file line numberDiff line numberDiff line change
@@ -593,11 +593,17 @@
593593
(def ^:const default-slippage 0.5)
594594
(def ^:const max-recommended-slippage 5)
595595
(def ^:const max-slippage-decimal-places 2)
596-
(def ^:const swap-default-provider
596+
(def ^:const swap-provider-paraswap
597597
{:name :paraswap
598598
:full-name "Paraswap"
599599
:color :blue
600600
:contract-address "0xdef171fe48cf0115b1d80b88dc8eab59176fee57"
601601
:terms-and-conditions-url "https://files.paraswap.io/tos_v4.pdf"})
602+
(def ^:const swap-providers
603+
{:paraswap swap-provider-paraswap})
602604

603605
(def ^:const token-for-fees-symbol "ETH")
606+
607+
(def ^:const transaction-status-success "Success")
608+
(def ^:const transaction-status-pending "Pending")
609+
(def ^:const transaction-status-failed "Failed")

src/status_im/contexts/wallet/common/utils.cljs

+120
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
(ns status-im.contexts.wallet.common.utils
22
(:require [clojure.string :as string]
3+
[native-module.core :as native-module]
34
[quo.foundations.resources :as resources]
45
[status-im.common.qr-codes.view :as qr-codes]
56
[status-im.constants :as constants]
7+
[utils.hex :as utils.hex]
68
[utils.money :as money]
79
[utils.number :as number]
810
[utils.string]))
@@ -360,3 +362,121 @@
360362
[tokens]
361363
(let [priority #(get constants/token-sort-priority (:symbol %) ##Inf)]
362364
(sort-by (juxt (comp - :balance) priority) tokens)))
365+
366+
(defn- transaction-data
367+
[{:keys [from-address to-address token-address route data eth-transfer?]}]
368+
(let [{:keys [amount-in gas-amount gas-fees]} route
369+
eip-1559-enabled? (:eip-1559-enabled gas-fees)
370+
{:keys [gas-price max-fee-per-gas-medium
371+
max-priority-fee-per-gas]} gas-fees]
372+
(cond-> {:From from-address
373+
:To (or token-address to-address)
374+
:Gas (money/to-hex gas-amount)
375+
:Value (when eth-transfer? amount-in)
376+
:Nonce nil
377+
:Input ""
378+
:Data (or data "0x")}
379+
eip-1559-enabled? (assoc
380+
:TxType "0x02"
381+
:MaxFeePerGas
382+
(money/to-hex
383+
(money/->wei
384+
:gwei
385+
max-fee-per-gas-medium))
386+
:MaxPriorityFeePerGas
387+
(money/to-hex
388+
(money/->wei
389+
:gwei
390+
max-priority-fee-per-gas)))
391+
(not eip-1559-enabled?) (assoc :TxType "0x00"
392+
:GasPrice
393+
(money/to-hex
394+
(money/->wei
395+
:gwei
396+
gas-price))))))
397+
398+
(defn approval-path
399+
[{:keys [route from-address to-address token-address]}]
400+
(let [{:keys [from]} route
401+
from-chain-id (:chain-id from)
402+
approval-amount-required (:approval-amount-required route)
403+
approval-amount-required-sanitized (-> approval-amount-required
404+
(utils.hex/normalize-hex)
405+
(native-module/hex-to-number))
406+
approval-contract-address (:approval-contract-address route)
407+
data (native-module/encode-function-call
408+
constants/contract-function-signature-erc20-approve
409+
[approval-contract-address
410+
approval-amount-required-sanitized])
411+
tx-data (transaction-data {:from-address from-address
412+
:to-address to-address
413+
:token-address token-address
414+
:route route
415+
:data data
416+
:eth-transfer? false})]
417+
{:BridgeName constants/bridge-name-transfer
418+
:ChainID from-chain-id
419+
:TransferTx tx-data}))
420+
421+
(defn transaction-path
422+
[{:keys [from-address to-address token-id token-address route data eth-transfer?]}]
423+
(let [{:keys [bridge-name amount-in bonder-fees from
424+
to]} route
425+
tx-data (transaction-data {:from-address from-address
426+
:to-address to-address
427+
:token-address token-address
428+
:route route
429+
:data data
430+
:eth-transfer? eth-transfer?})
431+
to-chain-id (:chain-id to)
432+
from-chain-id (:chain-id from)]
433+
(cond-> {:BridgeName bridge-name
434+
:ChainID from-chain-id}
435+
436+
(= bridge-name constants/bridge-name-erc-721-transfer)
437+
(assoc :ERC721TransferTx
438+
(assoc tx-data
439+
:Recipient to-address
440+
:TokenID token-id
441+
:ChainID to-chain-id))
442+
443+
(= bridge-name constants/bridge-name-erc-1155-transfer)
444+
(assoc :ERC1155TransferTx
445+
(assoc tx-data
446+
:Recipient to-address
447+
:TokenID token-id
448+
:ChainID to-chain-id
449+
:Amount amount-in))
450+
451+
(= bridge-name constants/bridge-name-transfer)
452+
(assoc :TransferTx tx-data)
453+
454+
(= bridge-name constants/bridge-name-hop)
455+
(assoc :HopTx
456+
(assoc tx-data
457+
:ChainID from-chain-id
458+
:ChainIDTo to-chain-id
459+
:Symbol token-id
460+
:Recipient to-address
461+
:Amount amount-in
462+
:BonderFee bonder-fees))
463+
464+
(not (or (= bridge-name constants/bridge-name-erc-721-transfer)
465+
(= bridge-name constants/bridge-name-transfer)
466+
(= bridge-name constants/bridge-name-hop)))
467+
(assoc :CbridgeTx
468+
(assoc tx-data
469+
:ChainID to-chain-id
470+
:Symbol token-id
471+
:Recipient to-address
472+
:Amount amount-in)))))
473+
474+
(defn multi-transaction-command
475+
[{:keys [from-address to-address from-asset to-asset amount-out multi-transaction-type]
476+
:or {multi-transaction-type constants/multi-transaction-type-unknown}}]
477+
{:fromAddress from-address
478+
:toAddress to-address
479+
:fromAsset from-asset
480+
:toAsset to-asset
481+
:fromAmount amount-out
482+
:type multi-transaction-type})

src/status_im/contexts/wallet/send/events.cljs

+6-125
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
[status-im.contexts.wallet.send.utils :as send-utils]
1111
[taoensso.timbre :as log]
1212
[utils.address :as address]
13-
[utils.hex :as utils.hex]
1413
[utils.money :as money]
1514
[utils.number]
1615
[utils.re-frame :as rf]))
@@ -582,124 +581,6 @@
582581
[{:ms 20
583582
:dispatch [:wallet/clean-up-transaction-flow]}]]]})))
584583

585-
(defn- transaction-data
586-
[{:keys [from-address to-address token-address route data eth-transfer?]}]
587-
(let [{:keys [amount-in gas-amount gas-fees]} route
588-
eip-1559-enabled? (:eip-1559-enabled gas-fees)
589-
{:keys [gas-price max-fee-per-gas-medium
590-
max-priority-fee-per-gas]} gas-fees]
591-
(cond-> {:From from-address
592-
:To (or token-address to-address)
593-
:Gas (money/to-hex gas-amount)
594-
:Value (when eth-transfer? amount-in)
595-
:Nonce nil
596-
:Input ""
597-
:Data (or data "0x")}
598-
eip-1559-enabled? (assoc
599-
:TxType "0x02"
600-
:MaxFeePerGas
601-
(money/to-hex
602-
(money/->wei
603-
:gwei
604-
max-fee-per-gas-medium))
605-
:MaxPriorityFeePerGas
606-
(money/to-hex
607-
(money/->wei
608-
:gwei
609-
max-priority-fee-per-gas)))
610-
(not eip-1559-enabled?) (assoc :TxType "0x00"
611-
:GasPrice
612-
(money/to-hex
613-
(money/->wei
614-
:gwei
615-
gas-price))))))
616-
617-
(defn- approval-path
618-
[{:keys [route from-address to-address token-address]}]
619-
(let [{:keys [from]} route
620-
from-chain-id (:chain-id from)
621-
approval-amount-required (:approval-amount-required route)
622-
approval-amount-required-sanitized (-> approval-amount-required
623-
(utils.hex/normalize-hex)
624-
(native-module/hex-to-number))
625-
approval-contract-address (:approval-contract-address route)
626-
data (native-module/encode-function-call
627-
constants/contract-function-signature-erc20-approve
628-
[approval-contract-address
629-
approval-amount-required-sanitized])
630-
tx-data (transaction-data {:from-address from-address
631-
:to-address to-address
632-
:token-address token-address
633-
:route route
634-
:data data
635-
:eth-transfer? false})]
636-
{:BridgeName constants/bridge-name-transfer
637-
:ChainID from-chain-id
638-
:TransferTx tx-data}))
639-
640-
(defn- transaction-path
641-
[{:keys [from-address to-address token-id token-address route data eth-transfer?]}]
642-
(let [{:keys [bridge-name amount-in bonder-fees from
643-
to]} route
644-
tx-data (transaction-data {:from-address from-address
645-
:to-address to-address
646-
:token-address token-address
647-
:route route
648-
:data data
649-
:eth-transfer? eth-transfer?})
650-
to-chain-id (:chain-id to)
651-
from-chain-id (:chain-id from)]
652-
(cond-> {:BridgeName bridge-name
653-
:ChainID from-chain-id}
654-
655-
(= bridge-name constants/bridge-name-erc-721-transfer)
656-
(assoc :ERC721TransferTx
657-
(assoc tx-data
658-
:Recipient to-address
659-
:TokenID token-id
660-
:ChainID to-chain-id))
661-
662-
(= bridge-name constants/bridge-name-erc-1155-transfer)
663-
(assoc :ERC1155TransferTx
664-
(assoc tx-data
665-
:Recipient to-address
666-
:TokenID token-id
667-
:ChainID to-chain-id
668-
:Amount amount-in))
669-
670-
(= bridge-name constants/bridge-name-transfer)
671-
(assoc :TransferTx tx-data)
672-
673-
(= bridge-name constants/bridge-name-hop)
674-
(assoc :HopTx
675-
(assoc tx-data
676-
:ChainID from-chain-id
677-
:ChainIDTo to-chain-id
678-
:Symbol token-id
679-
:Recipient to-address
680-
:Amount amount-in
681-
:BonderFee bonder-fees))
682-
683-
(not (or (= bridge-name constants/bridge-name-erc-721-transfer)
684-
(= bridge-name constants/bridge-name-transfer)
685-
(= bridge-name constants/bridge-name-hop)))
686-
(assoc :CbridgeTx
687-
(assoc tx-data
688-
:ChainID to-chain-id
689-
:Symbol token-id
690-
:Recipient to-address
691-
:Amount amount-in)))))
692-
693-
(defn- multi-transaction-command
694-
[{:keys [from-address to-address from-asset to-asset amount-out multi-transaction-type]
695-
:or {multi-transaction-type constants/multi-transaction-type-unknown}}]
696-
{:fromAddress from-address
697-
:toAddress to-address
698-
:fromAsset from-asset
699-
:toAsset to-asset
700-
:fromAmount amount-out
701-
:type multi-transaction-type})
702-
703584
(rf/reg-event-fx :wallet/send-transaction
704585
(fn [{:keys [db]} [sha3-pwd]]
705586
(let [routes (get-in db [:wallet :ui :send :route])
@@ -731,7 +612,7 @@
731612
(native-module/encode-transfer
732613
(address/normalized-hex to-address)
733614
(:amount-in route)))
734-
base-path (transaction-path
615+
base-path (utils/transaction-path
735616
{:to-address to-address
736617
:from-address from-address
737618
:route route
@@ -743,15 +624,15 @@
743624
:data data
744625
:eth-transfer? eth-transfer?})]
745626
(if approval-required?
746-
[(approval-path {:route route
747-
:token-address token-address
748-
:from-address from-address
749-
:to-address to-address})
627+
[(utils/approval-path {:route route
628+
:token-address token-address
629+
:from-address from-address
630+
:to-address to-address})
750631
base-path]
751632
[base-path]))))
752633
routes)
753634
request-params
754-
[(multi-transaction-command
635+
[(utils/multi-transaction-command
755636
{:from-address from-address
756637
:to-address to-address
757638
:from-asset token-id

src/status_im/contexts/wallet/signals.cljs

+16-3
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,29 @@
11
(ns status-im.contexts.wallet.signals
22
(:require
33
[oops.core :as oops]
4+
[status-im.constants :as constants]
45
[taoensso.timbre :as log]
56
[utils.re-frame :as rf]
67
[utils.transforms :as transforms]))
78

89
(rf/reg-event-fx
910
:wallet/pending-transaction-status-changed-received
1011
(fn [{:keys [db]} [{:keys [message]}]]
11-
(let [details (transforms/json->clj message)
12-
tx-hash (:hash details)]
13-
{:db (update-in db [:wallet :transactions tx-hash] assoc :status :confirmed :blocks 1)})))
12+
(let [details (transforms/json->clj message)
13+
tx-hash (:hash details)
14+
tx-status (:status details)
15+
status (cond
16+
(= tx-status constants/transaction-status-success)
17+
:confirmed
18+
(= tx-status constants/transaction-status-pending)
19+
:pending
20+
(= tx-status constants/transaction-status-failed)
21+
:failed)
22+
swap-approval-transaction-id (get-in db [:wallet :ui :swap :approval-transaction-id])
23+
swap-approval-transaction? (= swap-approval-transaction-id tx-hash)]
24+
(cond-> {:db (update-in db [:wallet :transactions tx-hash] assoc :status status)}
25+
swap-approval-transaction?
26+
(assoc :fx [[:dispatch [:wallet.swap/approve-transaction-update status]]])))))
1427

1528
(rf/reg-event-fx
1629
:wallet/signal-received

0 commit comments

Comments
 (0)