diff --git a/src/status_im/utils/erc20.cljs b/src/status_im/utils/erc20.cljs new file mode 100644 index 0000000000..1682fcf526 --- /dev/null +++ b/src/status_im/utils/erc20.cljs @@ -0,0 +1,51 @@ +(ns status-im.utils.erc20 + (:require [clojure.string :as string] + [status-im.js-dependencies :as dependencies])) + +;; Example +;; +;; Contract: https://ropsten.etherscan.io/address/0x29b5f6efad2ad701952dfde9f29c960b5d6199c5#readContract +;; Owner: https://ropsten.etherscan.io/token/0x29b5f6efad2ad701952dfde9f29c960b5d6199c5?a=0xa7cfd581060ec66414790691681732db249502bd +;; +;; With a running node on Ropsten: +;; (let [web3 (:web3 @re-frame.db/app-db) +;; contract "0x29b5f6efad2ad701952dfde9f29c960b5d6199c5" +;; address "0xa7cfd581060ec66414790691681732db249502bd"] +;; (erc20/balance-of web3 contract address println)) +;; +;; => 0x0000000000000000000000000000000000000000000000000000000001bd0c4a +;; (hex->int "0x0000000000000000000000000000000000000000000000000000000001bd0c4a") ;; => 29166666 (note token decimals) + +(defn sha3 [s] + (.sha3 dependencies/Web3.prototype (str s))) + +(defn hex->int [s] + (js/parseInt s 16)) + +(defn zero-pad-64 [s] + (str (apply str (drop (count s) (repeat 64 "0"))) s)) + +(defn format-param [param] + (if (number? param) + (zero-pad-64 (hex->int param)) + (zero-pad-64 (subs param 2)))) + +(defn format-call-params [method-id & params] + (let [params (string/join (map format-param params))] + (str method-id params))) + +(defn get-call-params [contract method-id & params] + (let [data (apply format-call-params method-id params)] + {:to contract :data data})) + +(defn sig->method-id [signature] + (apply str (take 10 (sha3 signature)))) + +(defn balance-of-params [token of] + (let [method-id (sig->method-id "balanceOf(address)")] + (get-call-params token method-id of))) + +(defn balance-of [web3 token of cb] + (.call (.-eth web3) + (clj->js (balance-of-params token of)) + cb)) diff --git a/test/cljs/status_im/test/runner.cljs b/test/cljs/status_im/test/runner.cljs index 1bb2593d2b..38dd620ff6 100644 --- a/test/cljs/status_im/test/runner.cljs +++ b/test/cljs/status_im/test/runner.cljs @@ -6,7 +6,8 @@ [status-im.test.handlers] [status-im.test.utils.utils] [status-im.test.utils.money] - [status-im.test.utils.clocks])) + [status-im.test.utils.clocks] + [status-im.test.utils.erc20])) (enable-console-print!) @@ -22,4 +23,5 @@ 'status-im.test.handlers 'status-im.test.utils.utils 'status-im.test.utils.money - 'status-im.test.utils.clocks) + 'status-im.test.utils.clocks + 'status-im.test.utils.erc20) diff --git a/test/cljs/status_im/test/utils/erc20.cljs b/test/cljs/status_im/test/utils/erc20.cljs new file mode 100644 index 0000000000..7259092c65 --- /dev/null +++ b/test/cljs/status_im/test/utils/erc20.cljs @@ -0,0 +1,11 @@ +(ns status-im.test.utils.erc20 + (:require [cljs.test :refer-macros [deftest is testing]] + [status-im.utils.erc20 :as erc20])) + +(deftest erc20 + (testing "ERC20 balance-of params" + (let [contract "0x29b5f6efad2ad701952dfde9f29c960b5d6199c5" + address "0xa7cfd581060ec66414790691681732db249502bd"] + (is (= (erc20/balance-of-params contract address) + {:to "0x29b5f6efad2ad701952dfde9f29c960b5d6199c5" + :data "0x70a08231000000000000000000000000a7cfd581060ec66414790691681732db249502bd"})))))