{meta {:name "Kyber UI" :description "Kyber exchange" :documentation ""} events/on-transaction-receipt (let [{value :value} properties] [store/put {:key "RECEIPT" :value value}]) events/on-trade-result (let [{value :value} properties] [ethereum/await-transaction-receipt {:interval 1000 :value value :on-success [on-transaction-receipt]}]) events/trade (let [{src-address :src-address dest-address :dest-address amount-in-wei :amount-in-wei address :address slippage :slippage} properties] [ethereum/send-transaction {:to "0x818E6FECD516Ecc3849DAf6845e3EC868087B755" :method "trade(address,uint256,address,address,uint256,uint256,address)" :gas "600000" :params [src-address amount-in-wei dest-address address "57896044618658097711785492504343953926634992332820282019728792003956564819968" slippage "0xD8a38Ae058fB6a6A6CB9517cF9Bc1730a6E15617"] :on-success [on-trade-result]}]) events/approve (let [{src-address :src-address dest-address :dest-address address :address amount-in-wei :amount-in-wei slippage :slippage} properties] ;; Approve Kyber contract for further transfer [ethereum/send-transaction {:to src-address :method "approve(address,uint256)" :params ["0x818E6FECD516Ecc3849DAf6845e3EC868087B755" amount-in-wei] :gas "100000" :on-success [trade {:address address :amount-in-wei amount-in-wei :slippage slippage :src-address src-address :dest-address dest-address}]}]) views/render-token (let [{name :name {source :source} :icon} properties] [view {:style {:height 64 :margin-horizontal 16 :flex-direction :row :align-items :center}} [image {:source source :style {:width 40 :height 40}}] [text {:style {:margin-left 16 :font-size 16 :color :black}} name]]) events/aputs (let [{key :key selection :selection source :source symbol :symbol rate :rate value :value} properties] [store/puts {:value [{:key key :value {:selection selection :source source :symbol symbol}} {:key "RATE" :value {:value rate}} {:key "AMOUNT-TO-RECEIVE" :value value}]}]) events/on-rate-result (let [{key :key amount :amount selection :selection source :source symbol :symbol [_ slippage :as result] :value} properties] [arithmetic {:operation :times :values [amount slippage] :on-result [aputs {:key key :amount amount :rate result :selection selection :source source :symbol symbol}]}]) ;; TODO Consider Kyber tokens list (require view lifecycle?) ;; TODO react on amount changes too ;; TODO hook completion screens (require case support?) ;; TODO proper error handling events/on-src-rate-params-change (let [{key :key amount :amount amount-in-wei :amount-in-wei dest-address :dest-address address :address selection :name {source :source} :icon symbol :symbol} properties] [ethereum/call {:to "0x818E6FECD516Ecc3849DAf6845e3EC868087B755" :method "getExpectedRate(address,address,uint256)" :params [address dest-address amount-in-wei] :outputs ["uint256" "uint256"] :on-success [on-rate-result {:key key :amount amount :selection selection :source source :symbol symbol}]}]) events/on-dest-rate-params-change (let [{key :key amount :amount amount-in-wei :amount-in-wei src-address :src-address address :address selection :name {source :source} :icon symbol :symbol} properties] [ethereum/call {:to "0x818E6FECD516Ecc3849DAf6845e3EC868087B755" :method "getExpectedRate(address,address,uint256)" :params [src-address address amount-in-wei] :outputs ["uint256" "uint256"] :on-success [on-rate-result {:key key :amount amount :selection selection :source source :symbol symbol}]}]) events/bputs (let [{amount :amount rate :rate value :value} properties] [store/puts {:value [{:key "RATE" :value {:value rate}} {:key "AMOUNT" :value amount} {:key "AMOUNT-TO-RECEIVE" :value value}]}]) events/on-amount-rate-result (let [{amount :amount [_ slippage :as result] :result} properties] [arithmetic {:operation :times :values [amount slippage] :on-result [bputs {:amount amount :rate result}]}]) events/on-amount-params-change (let [{amount :value src-address :src-address dest-address :dest-address} properties] [ethereum/call {:to "0x818E6FECD516Ecc3849DAf6845e3EC868087B755" :method "getExpectedRate(address,address,uint256)" :params [src-address dest-address amount-in-wei] :outputs ["uint256" "uint256"] :on-success [on-amount-rate-result {:amount amount}]}]) events/store-amount (let [{amount :value} properties] [store/put {:key "AMOUNT" :value amount}]) views/sign-to-confirm (let [{color :color} properties] [view {:style {:flex-direction :row :margin-vertical 14 :align-items :center}} [view {:style {:flex 1}}] [text {:style {:color color :font-size 15 :margin-right 5}} "Sign to confirm"] [icon {:key :icons/forward :color color}]]) views/transaction-failed-panel (let [{} properties] [view {:style {:flex 1 :background-color "#4360df"}} [view {:style {:flex 1 :justify-content :center :align-items :center}} [view {:style {:background-color :white :width 56 :height 56 :border-radius 28 :align-items :center :justify-content :center}} [icon {:key :icons/ok :color "#4360df"}]] [text {:style {:color :white :font-size 17 :margin-top 16}} "Transaction Failed"] [text {:style {:color "rgba(255,255,255,0.6)" :font-size 15 :margin-top 8}} "Sorry :("] [view {:style {:height 1 :background-color :white :opacity 0.2}}] [view {:style {:flex 1}}] [touchable-opacity {:on-press [store/put {:key "completed?" :value false}]} [text {:style {:color :white :font-size 15 :margin-top 16}} "Try again"]]]]) views/transaction-pending-panel (let [{} properties] [view {:style {:flex 1 :background-color "#4360df"}} [view {:style {:flex 1 :justify-content :center :align-items :center :margin-top 200}} [view {:style {:background-color :white :width 56 :height 56 :border-radius 28 :align-items :center :justify-content :center}} [icon {:key :icons/ok :color "#4360df"}]] [text {:style {:color :white :font-size 17 :margin-top 16}} "Transaction Pending"] [text {:style {:color "rgba(255,255,255,0.6)" :font-size 15 :margin-top 8 :margin-horizontal 40}} "Your transaction is pending confirmation on the blockchain. You can check its status in your transaction history."] [view {:style {:flex 1}}] [view {:style {:height 1 :background-color :white :opacity 0.2}}] [touchable-opacity {:on-press [store/put {:key "completed?" :value false}]} [text {:style {:color :white :font-size 15 :margin-bottom 14 :margin-top 18}} "Back to wallet"]]]]) views/transaction-completed-panel (let [{tokenname1 :tokenname1 tokenname2 :tokenname2 source1 :source1 source2 :source2 address :address} properties] [view {:style {:flex 1 :background-color "#4360df"}} [view {:style {:flex 1 :justify-content :center :align-items :center}} [view {:style {:background-color :white :width 56 :height 56 :border-radius 28 :align-items :center :justify-content :center}} [icon {:key :icons/ok :color "#4360df"}]] [text {:style {:color :white :font-size 17 :margin-top 16}} "Transaction Confirmed"] [view {:style {:height 1 :background-color :white :opacity 0.2}}] [touchable-opacity {:on-press [store/put {:key "completed?" :value false}]} [text {:style {:color :white :font-size 15 :margin-top 16}} "Back to exchange"]]] [view {:style {:flex 1 :background-color :white :padding-horizontal 16 :padding-top 23}} [text {:style {:font-size 15}} "You exchanged"] [view {:style {:border-color "#EEF2F5" :border-radius 8 :border-width 1 :flex-direction :row :margin-top 6 :padding 15 :align-items :center}} [image {:source source1 :style {:width 30 :height 30}}] [text {:style {:flex 1 :font-size 15 :margin-left 12}} tokenname1]] [view {:style {:flex 1}}] [text {:style {:font-size 15}} "You received"] [view {:style {:border-color "#EEF2F5" :border-radius 8 :border-width 1 :flex-direction :row :margin-top 6 :padding 15 :align-items :center}} [image {:source source2 :style {:width 30 :height 30}}] [text {:style {:flex 1 :font-size 15 :margin-left 12}} tokenname2]] [view {:style {:flex 1}}]]]) views/transaction-panel (let [m properties {status :status} [store/get {:key "RECEIPT"}]] (if status [transaction-completed-panel m] [transaction-pending-panel m])) views/kyber-panel {:component-will-mount [store/clear-all] :view (let [{address :address} properties visible-tokens [wallet/tokens {:visible true}] tokens [wallet/tokens] {tokenname1 :selection source1 :source src-symbol :symbol} [store/get {:key "SRC"}] {tokenname2 :selection source2 :source dest-symbol :symbol} [store/get {:key "DEST"}] completed? [store/get {:key "completed?"}] amount [store/get {:key "AMOUNT"}] amount-to-receive-in-wei [store/get {:key "AMOUNT-TO-RECEIVE"}] {[expected slippage-in-wei] :value} [store/get {:key "RATE"}] {slippage :amount} [wallet/token {:token "ETH" :amount-in-wei slippage-in-wei}] ;; Kyber returns slippage with 18 decimals {amount-to-receive :amount} [wallet/token {:token "ETH" :amount-in-wei amount-to-receive-in-wei}] {src-decimals :decimals src-address :address amount-in-wei :amount-in-wei} [wallet/token {:token src-symbol :amount amount}] {dest-decimals :decimals dest-address :address} [wallet/token {:token dest-symbol}] {balance :value} [wallet/balance {:token src-symbol}]] (if completed? [transaction-panel {:source1 source1 :source2 source2 :tokenname1 tokenname1 :tokenname2 tokenname2 :address completed?}] [view {:style {:flex 1 :background-color "#4360df" :padding-horizontal 16 :padding-top 20}} [scroll-view {:keyboard-should-persist-taps :always} [view {:style {:flex 1}} [text {:style {:color :white :font-size 15}} "I want to exchange"] [touchable-opacity {:on-press [selection-screen {:title "Choose asset" :items visible-tokens :on-select [on-src-rate-params-change {:key "SRC" :amount amount :dest-address dest-address :amount-in-wei amount-in-wei}] :render [render-token] :extractor-key :name}]} [view {:style {:flex-direction :row :margin-top 8 :border-radius 8 :height 52 :background-color "rgba(255,255,255,0.1)" :align-items :center :padding-horizontal 14}} [image {:source source1 :style {:width 30 :height 30}}] (if tokenname1 [view {:style {:flex 1 :flex-direction :column}} [view {:style {:flex-direction :row}} [text {:style {:margin-left 16 :color :white :font-size 15}} tokenname1] [text {:style {:margin-left 16 :color :white :font-size 15 :opacity 0.6}} src-symbol]] [text {:style {:margin-left 16 :color :white :font-size 15 :opacity 0.6}} "Available: ${balance}"]] [text {:style {:flex 1 :color :white :margin-left 12}} "Select token"]) [icon {:key :icons/forward :color :white}]]] [text {:style {:color :white :font-size 15 :margin-top 28}} "Amount"] [view {:style {:flex-direction :row :margin-top 8 :border-radius 8 :height 52 :background-color "rgba(255,255,255,0.1)" :align-items :center :padding-horizontal 14 :margin-bottom 32}} [input {:style {:color :white :flex 1} :placeholder "Specify amount..." :placeholder-text-color "rgba(255,255,255,0.6)" :selection-color :white :keyboard-type :decimal-pad :on-change [store-amount {:amount amount :src-address src-address :dest-address dest-address}]}]] [view {:style {:flex 1}}] [view {:style {:height 1 :background-color :white :opacity 0.2}}] [view {:style {:flex 1}}] [text {:style {:color :white :font-size 15 :margin-top 32}} "I want to recieve"] [touchable-opacity {:on-press [selection-screen {:title "Choose asset" :items tokens :on-select [on-dest-rate-params-change {:key "DEST" :amount amount :src-address src-address :amount-in-wei amount-in-wei}] :render [render-token] :extractor-key :name}]} [view {:style {:flex-direction :row :margin-top 8 :border-radius 8 :height 52 :background-color "rgba(255,255,255,0.1)" :align-items :center :padding-horizontal 14}} (when source2 [image {:source source2 :style {:width 30 :height 30}}]) (if tokenname2 [view {:style {:flex 1 :flex-direction :row}} [text {:style {:margin-left 16 :color :white :font-size 15}} tokenname2] [text {:style {:margin-left 16 :color :white :font-size 15 :opacity 0.6}} dest-symbol]] [text {:style {:flex 1 :color :white :margin-left 12}} "Select token"]) [icon {:key :icons/forward :color :white}]]] [text {:style {:color :white :opacity 0.6 :font-size 15 :margin-top 28}} "Amount to receive"] [view {:style {:flex-direction :row :margin-top 8 :border-radius 8 :height 52 :border-color "rgba(255,255,255,0.1)" :border-width 1 :align-items :center :padding-horizontal 14}} [text {:style {:color :white}} amount-to-receive]] (when slippage [text {:style {:margin-top 16 :color :white :opacity 0.6}} "1 ${src-symbol} = ${slippage} ${dest-symbol}"]) [view {:style {:flex 1}}] [text {:style {:color :white :opacity 0.6}} "Powered by Kyber Network"] [view {:style {:height 1 :background-color :white :opacity 0.2}}]]] (if slippage [touchable-opacity {:on-press [approve {:slippage slippage-in-wei :amount-in-wei amount-in-wei :src-address src-address :dest-address dest-address :address address}]} [sign-to-confirm {:color :white}]] [sign-to-confirm {:color "#FFFFFF66"}])]))} hooks/wallet.settings.kyber {:label "Exchange Assets" :view [kyber-panel]}}