├── scripts ├── dexp2p_spam.sh ├── chainstart │ ├── requirements.txt │ ├── run.sh │ ├── chainconfig.json │ ├── README.md │ └── chainstart.py ├── dexp2p │ ├── multi-server │ │ ├── dexp2p_clean.sh │ │ ├── start_stream.sh │ │ ├── watch_stream.sh │ │ ├── dexp2p_start_spam_ms.sh │ │ ├── get_stats.py │ │ ├── dexp2p_spam_ms.sh │ │ ├── prepare_dexp2p_node_ms.sh │ │ ├── README.md │ │ ├── dexp2p_save_orderbooks_ms.py │ │ ├── dexp2p_orderbooks_parser_ms.py │ │ ├── dexp2p_auto_deploy.py │ │ └── clients_spawn_multi_server.py │ ├── dexp2p_start_spam.sh │ ├── dexp2p_test_start.sh │ ├── prepare_dexp2p_node.sh │ ├── dexp2p_spam.sh │ ├── dexp2p_orderbooks_parser.py │ └── clients_spawn.py ├── start_spam.sh ├── start_libnspv_spam.sh ├── nspv_node_prepare.sh ├── send_labs_to_staking_node ├── keystrokes_combine.py ├── warrios_hex_extract.py ├── seeds_extracter.py ├── libnspv_calls.sh ├── nspv_calls.sh ├── libnspv_clients_spam.py ├── nspv_clients_spawn.py ├── find_uuid_by_txid.py ├── find_uuids_by_addr.py ├── kmd_1of1gw_creation.py ├── crosschain_migrations.py └── crosschain_migrations_v2.py ├── dash.ini ├── undo-redo.css ├── static └── undo-redo.css ├── tokens_list ├── .gitignore ├── requirements.txt ├── lib ├── getaddycli.py ├── mm2lib.py ├── marmara_lib.py ├── logo.txt ├── atomicdex_stats_lib.py ├── rpclib.py └── visualization_lib.py ├── LICENSE ├── PEGSTUI_pegsinfo.json ├── rekt_inspector.py ├── pegs_creation_tui.py ├── README.md ├── assets_cc_tui.py ├── prices_visualization_server.py ├── generate_addresses.py ├── gateways_creation_tui.py ├── marmara_tui.py ├── oracles_cc_tui.py ├── payments_cc_tui.py ├── tetris_tui.py ├── pegs_usage_tui.py ├── gateways_usage_tui.py ├── rogue_tui.py ├── docs └── pegs_module.md ├── antara_tui.py └── prices_app_v2.py /scripts/dexp2p_spam.sh: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dash.ini: -------------------------------------------------------------------------------- 1 | [auth] 2 | user=custom 3 | pass=consensus 4 | -------------------------------------------------------------------------------- /undo-redo.css: -------------------------------------------------------------------------------- 1 | ._dash-undo-redo { 2 | display: none; 3 | } -------------------------------------------------------------------------------- /static/undo-redo.css: -------------------------------------------------------------------------------- 1 | ._dash-undo-redo { 2 | display: none; 3 | } -------------------------------------------------------------------------------- /tokens_list: -------------------------------------------------------------------------------- 1 | 4770abe0b3b50647a1f84e7195e2ccfdbd608f8338c9cc54f3a1f8b081eaf276 2 | -------------------------------------------------------------------------------- /scripts/chainstart/requirements.txt: -------------------------------------------------------------------------------- 1 | ujson>=1.35 2 | wget>=3.2 3 | pycurl>=7.43.0.5 4 | slick-bitcoinrpc>=0.1.4 5 | -------------------------------------------------------------------------------- /scripts/dexp2p/multi-server/dexp2p_clean.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | rm -rf node_* 4 | rm spam_p2p/packages/* 5 | rm spam_p2p/orderbooks/* -------------------------------------------------------------------------------- /scripts/start_spam.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | i=7000 4 | 5 | while [ $i -le 7250 ] 6 | do 7 | ./nspv_calls.sh $i & 8 | ((i++)) 9 | done 10 | -------------------------------------------------------------------------------- /scripts/start_libnspv_spam.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | i=7000 4 | 5 | while [ $i -le 7100 ] 6 | do 7 | ./libnspv_calls.sh $i & 8 | ((i++)) 9 | done 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | oraclefeed 2 | connection.json 3 | kmd_connection.json 4 | oracles_list 5 | tokens_list 6 | deposits_list 7 | __pycache__/ 8 | *_7776 9 | *.log 10 | 11 | -------------------------------------------------------------------------------- /scripts/dexp2p/dexp2p_start_spam.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | i=7000 4 | j=$(($i+$NODESAMOUNT-1)) 5 | 6 | while [ $i -le $j ] 7 | do 8 | ./dexp2p_spam.sh $i & 9 | ((i++)) 10 | done -------------------------------------------------------------------------------- /scripts/dexp2p/multi-server/start_stream.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | while true; do 4 | ./komodo-cli -ac_name=DEXTEST -conf=/root/node_0/DEXTEST.conf -datadir=/root/node_0 DEX_stream pony_8x01.mkv 0 5 | done 6 | -------------------------------------------------------------------------------- /scripts/dexp2p/multi-server/watch_stream.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | while true; do 4 | ./komodo-cli -ac_name=DEXSTATS -conf=/root/node_0/DEXTEST.conf -rpcport=7000 -datadir=/root/node_0 DEX_streamsub pony_8x01.mkv 0 $1 5 | done 6 | -------------------------------------------------------------------------------- /scripts/dexp2p/multi-server/dexp2p_start_spam_ms.sh: -------------------------------------------------------------------------------- 1 | # server IP as argument 2 | 3 | #!/bin/bash 4 | 5 | i=7000 6 | j=$(($i+$NODESAMOUNT-1)) 7 | 8 | while [ $i -le $j ] 9 | do 10 | ./dexp2p_spam_ms.sh $i $1 $2 & 11 | ((i++)) 12 | done -------------------------------------------------------------------------------- /scripts/dexp2p/dexp2p_test_start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export NODESAMOUNT=$1 4 | 5 | python3 dexp2p_clients_spawn.py 6 | ./dexp2p_start_spam.sh 7 | python3 dexp2p_orderbooks_parser.py 8 | 9 | rm -rf node_* 10 | rm -rf spam_p2p/orderbooks/* 11 | rm -rf spam_p2p/packages/* 12 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | configobj==5.0.6 2 | pip==19.2 3 | pycurl==7.43.0.2 4 | setuptools==39.0.1 5 | six==1.12.0 6 | slick-bitcoinrpc==0.1.4 7 | ujson==1.35 8 | wheel==0.32.3 9 | dash==0.43.0 10 | dash-auth==1.2.0 11 | dash-core-components==0.48.0 12 | dash-daq==0.1.5 13 | dash-html-components==0.16.0 14 | dash-renderer==0.24.0 15 | dash-table==3.7.0 16 | qrcode==6.1 17 | -------------------------------------------------------------------------------- /scripts/dexp2p/multi-server/get_stats.py: -------------------------------------------------------------------------------- 1 | from slickrpc import Proxy, exc 2 | import json 3 | import os 4 | 5 | proxies_to_create = int(os.getenv('NODESAMOUNT')) 6 | 7 | for i in range(proxies_to_create): 8 | rpcport = 7000 + i 9 | globals()['proxy_%s' % i] = Proxy("http://%s:%s@127.0.0.1:%d" % ("test", "test", int(rpcport))) 10 | dex_stats = globals()['proxy_%s' % i].DEX_stats() 11 | print(dex_stats["perfstats"]) 12 | -------------------------------------------------------------------------------- /scripts/dexp2p/multi-server/dexp2p_spam_ms.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | 4 | end=$((SECONDS+$3)) 5 | 6 | while [ $SECONDS -lt $end ]; do 7 | TEST="$2"_$(( ( RANDOM % 1000000 ) + 1 )) 8 | curl --user test:test --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "DEX_broadcast", "params": ["'"$TEST"'", "0", "'"$1"'", "", "", "0.1", "100"] }' -H 'content-type: text/plain;' http://127.0.0.1:$1/ >> spam_p2p/packages/$2_$1_packages.txt 9 | done 10 | -------------------------------------------------------------------------------- /scripts/nspv_node_prepare.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | sudo apt-get update 3 | sudo apt-get upgrade -y 4 | sudo apt-get install zip wget libgomp1 -y 5 | wget http://159.69.45.70/nspv_daemon.zip 6 | unzip nspv_daemon.zip 7 | wget https://raw.githubusercontent.com/tonymorony/komodo-cctools-python/master/scripts/nspv_clients_spawn.py 8 | wget http://159.69.45.70/fetch-params.sh 9 | chmod u+x fetch-params.sh 10 | ./fetch-params.sh 11 | python3 nspv_clients_spawn.py 12 | -------------------------------------------------------------------------------- /scripts/chainstart/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # chains start script params 4 | export CLIENTS=2 5 | export CHAIN="TICKER" 6 | export TEST_ADDY0="example_address1" 7 | export TEST_WIF0="example_wif1" 8 | export TEST_PUBKEY0="example_pub1" 9 | export TEST_ADDY1="example_address2" 10 | export TEST_WIF1="example_wif2" 11 | export TEST_PUBKEY1="example_pub2" 12 | export CHAIN_MODE="REGULAR" 13 | export IS_BOOTSTRAP_NEEDED="True" 14 | export BOOTSTRAP_URL="" 15 | export BINARYPATH=$HOME/komodo/src/komodod 16 | 17 | # starting the chains 18 | python3 chainstart.py 19 | -------------------------------------------------------------------------------- /scripts/send_labs_to_staking_node: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from time import gmtime, strftime 3 | from lib import tuilib 4 | 5 | rpc_connection = tuilib.def_credentials("LABS") 6 | address = "RAC25VsXmwjgyvkw3yaPYrgfsSXKxD51WE" 7 | time = strftime("%Y-%m-%d %H:%M:%S", gmtime()) 8 | balance = rpc_connection.getbalance() 9 | 10 | if int(balance) > 10: 11 | txid = rpc_connection.sendtoaddress(address, "10") 12 | print("Sent 10 LABS. txid:" + txid + " Current time:" + time) 13 | else: 14 | print("Current balance: " + str(balance) + " Time: " + time) 15 | -------------------------------------------------------------------------------- /scripts/keystrokes_combine.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | seed = "2139495316301712247" 4 | levels = "7" 5 | 6 | levels_counter = int(levels) 7 | iterator = 1 8 | filenames = [] 9 | 10 | while iterator <= levels_counter: 11 | filenames.append("rogue." + seed + "." + str(iterator)) 12 | iterator = iterator + 1 13 | 14 | with open(seed + "_combined.txt", 'w') as outfile: 15 | for fname in filenames: 16 | with open(fname) as infile: 17 | outfile.write(infile.read()) 18 | 19 | 20 | print("Succesfully combined to: " + seed + "_combined.txt file") -------------------------------------------------------------------------------- /lib/getaddycli.py: -------------------------------------------------------------------------------- 1 | import mm2lib 2 | 3 | while True: 4 | time_lock = int(input("Input maker_payment_lock from Started e.g. 1588875030 : ")) 5 | secret_hash = input("Input secret_hash e.g. bc88c6534d5b82866807cde2da0ce5735c335a2a : ") 6 | pub_0 = input("Input my_persistent_pub pubkey e.g. 03683c77e807a47dcd559fa60a6510087e5c5aa0016c094cf5eb4d7e002db18e9f : ") 7 | pub_1 = input("Input taker_pubkey from Negotiated event e.g. 032eadab416e372d21d8cbf798019325088dc796fd6762b6304c0298f279d58038 : ") 8 | print("Address: " + mm2lib.get_payment_address(time_lock, bytes.fromhex(secret_hash), bytes.fromhex(pub_0), bytes.fromhex(pub_1))) 9 | -------------------------------------------------------------------------------- /scripts/warrios_hex_extract.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from lib import tuilib 4 | 5 | rpc_connection = tuilib.def_credentials("ROGUE") 6 | 7 | players_list = rpc_connection.cclib("players", "17")["playerdata"] 8 | 9 | players_tokenids_list = [] 10 | 11 | for player_txid in players_list: 12 | players_tokenids_list.append(tuilib.rogue_player_info(rpc_connection, player_txid)["player"]["tokenid"]) 13 | 14 | for token_txid in players_tokenids_list: 15 | player_vouts = rpc_connection.getrawtransaction(token_txid, 1)["vout"] 16 | for vout in player_vouts: 17 | if vout["value"] == 0: 18 | print(vout["scriptPubKey"]["hex"]) 19 | -------------------------------------------------------------------------------- /scripts/dexp2p/prepare_dexp2p_node.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sudo apt-get update 4 | sudo apt-get install python3.6 python3-pip libgnutls28-dev libcurl4-openssl-dev libssl-dev unzip python3-dev build-essential 5 | pip3 install setuptools 6 | pip3 install wheel slick-bitcoinrpc 7 | git clone https://github.com/tonymorony/komodo-cctools-python 8 | wget http://159.69.45.70/komodo_dexp2p.zip 9 | unzip komodo_dexp2p.zip 10 | wget https://raw.githubusercontent.com/KomodoPlatform/komodo/master/zcutil/fetch-params.sh 11 | chmod u+x fetch-params.sh 12 | ./fetch-params.sh 13 | cp komodo-cctools-python/scripts/dexp2p/* . 14 | mkdir spam_p2p 15 | mkdir spam_p2p/orderbooks 16 | mkdir spam_p2p/packages 17 | -------------------------------------------------------------------------------- /scripts/dexp2p/multi-server/prepare_dexp2p_node_ms.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sudo apt-get -y update 4 | sudo apt-get -y install python3.6 python3-pip libgnutls28-dev libcurl4-openssl-dev libssl-dev unzip python3-dev build-essential jq 5 | pip3 install setuptools 6 | pip3 install wheel slick-bitcoinrpc 7 | git clone https://github.com/tonymorony/komodo-cctools-python 8 | wget http://159.69.45.70/komodo_dexp2p.zip 9 | unzip komodo_dexp2p.zip 10 | wget https://raw.githubusercontent.com/KomodoPlatform/komodo/master/zcutil/fetch-params.sh 11 | chmod u+x fetch-params.sh 12 | ./fetch-params.sh 13 | cp komodo-cctools-python/scripts/dexp2p/multi-server/* . 14 | mkdir spam_p2p 15 | mkdir spam_p2p/orderbooks 16 | mkdir spam_p2p/packages 17 | -------------------------------------------------------------------------------- /scripts/dexp2p/dexp2p_spam.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | end=$((SECONDS+180)) 4 | 5 | while [ $SECONDS -lt $end ]; do 6 | TEST=$(( ( RANDOM % 1000000 ) + 1 )) 7 | curl --user test:test --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "DEX_broadcast", "params": ["'"$TEST"'", "0", "'"$1"'", "", "", "0.1", "100"] }' -H 'content-type: text/plain;' http://127.0.0.1:$1/ >> spam_p2p/packages/node$1_packages.txt 8 | done 9 | 10 | # getting orderbooks 11 | i=0 12 | j=$(($NODESAMOUNT-1)) 13 | while [ $i -le $j ] 14 | do 15 | TAG=$(( 7000 + $i )) 16 | curl --user test:test --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "DEX_list", "params": [ "0", "0", "'"$TAG"'"] }' -H 'content-type: text/plain;' http://127.0.0.1:$1/ >> spam_p2p/orderbooks/node$1_tag_$TAG.txt 17 | ((i++)) 18 | done 19 | -------------------------------------------------------------------------------- /scripts/seeds_extracter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from lib import tuilib 4 | 5 | 6 | rpc_connection_ac = tuilib.def_credentials("ROGUE") 7 | 8 | games_list = rpc_connection_ac.cclib("games", "17") 9 | 10 | pastgames_list = games_list["pastgames"] 11 | 12 | activegames_list = games_list["games"] 13 | 14 | 15 | print(tuilib.colorize("\n*** Pastgames *** \n", "blue")) 16 | print("TXID SEED") 17 | for game in pastgames_list: 18 | pastgame_info = tuilib.rogue_game_info(rpc_connection_ac, game) 19 | print(game + " " + str(pastgame_info["seed"])) 20 | 21 | 22 | 23 | print(tuilib.colorize("\n*** Active games *** \n", "blue")) 24 | print("TXID SEED") 25 | for game in activegames_list: 26 | activegame_info = tuilib.rogue_game_info(rpc_connection_ac, game) 27 | print(game + " " + str(activegame_info["seed"])) 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Anton Lysakov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PEGSTUI_pegsinfo.json: -------------------------------------------------------------------------------- 1 | { 2 | "Pegs_Launch_Parameters":"-ac_supply=5000 -ac_reward=800000000 -ac_sapling=1 -addnode=localhost -ac_snapshot=1440 -ac_cc=2 -ac_import=PEGSCC -debug=gatewayscc-2 -ac_end=1 -ac_perc=0 -ac_cbopret=7 -ac_name=PEGSTUI -earlytxid=a0b6fa8f5e437df126a7ee668b7b82ba6331a0df5d566dd9070e77c69cc1dda5", 3 | "Oraclefeed_Launch_Parameters":"/home/smk762/Mixa84/komodo/src/oraclefeed PEGSTUI efbf27614519dba1ffb407d00a14f80f3b99ff3d092105555225f00f76e60bd5 0218cfbaf0a69449bd8b81d731c6ae0b1c81a4968f8f4fdae25dda3dfd9468526a Ihh 03d715bbcc8cd96b2f85ef57478da3855e149933ff13b7436ca351189bacc790 /home/smk762/Mixa84/komodo/src/komodo-cli", 4 | "Pegs_Creation_TXID":"a0b6fa8f5e437df126a7ee668b7b82ba6331a0df5d566dd9070e77c69cc1dda5", 5 | "Gateways_Bind_TXID":"03d715bbcc8cd96b2f85ef57478da3855e149933ff13b7436ca351189bacc790", 6 | "Oracle_TXID":"efbf27614519dba1ffb407d00a14f80f3b99ff3d092105555225f00f76e60bd5", 7 | "Token_TXID":"26ad8fecec3cd900ea24b292a6df78354cd6f325074518e6a82ebefd93c9e4a0", 8 | "Coin":"KMD", 9 | "Pubkeys":"['0218cfbaf0a69449bd8b81d731c6ae0b1c81a4968f8f4fdae25dda3dfd9468526a']", 10 | "Gateways_Deposit_Address":"RW629fdF8Sq9W3JcuSAz6BE2cHd4vvpNnR" 11 | } -------------------------------------------------------------------------------- /scripts/libnspv_calls.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | while : 4 | do 5 | curl -s --user test:test --data-binary '{"jsonrpc": "2.0", "id":"curltest", "method": "getinfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:$1/ &> curl-output.txt 6 | curl -s --user test:test --data-binary '{"jsonrpc": "2.0", "id":"curltest", "method": "listunspent", "params": ["RQ1mvCUcziWzRwE8Ugtex29VjoFjRzxQJT"] }' -H 'content-type: text/plain;' http://127.0.0.1:$1 &> curl-output.txt 7 | curl -s --user test:test --data-binary '{"jsonrpc": "2.0", "id":"curltest", "method": "notarizations", "params": ["2000"] }' -H 'content-type: text/plain;' http://127.0.0.1:$1 &> curl-output.txt 8 | curl -s --user test:test --data-binary '{"jsonrpc": "2.0", "id":"curltest", "method": "spentinfo", "params": ["67ffe0eaecd6081de04675c492a59090b573ee78955c4e8a85b8ac0be0e8e418", "1"] }' -H 'content-type: text/plain;' http://127.0.0.1:$1 &> curl-output.txt 9 | curl -s --user test:test --data-binary '{"jsonrpc": "2.0", "id":"curltest", "method": "txproof", "params": ["67ffe0eaecd6081de04675c492a59090b573ee78955c4e8a85b8ac0be0e8e418", "2673"] }' -H 'content-type: text/plain;' http://127.0.0.1:$1 &> curl-output.txt 10 | done 11 | -------------------------------------------------------------------------------- /scripts/nspv_calls.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | while : 4 | do 5 | curl -s --user test:test --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "nspv_getinfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:$1/ > curl-output.txt 6 | curl -s --user test:test --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "nspv_listunspent", "params": ["RQ1mvCUcziWzRwE8Ugtex29VjoFjRzxQJT"] }' -H 'content-type: text/plain;' http://127.0.0.1:$1 > curl-output.txt 7 | curl -s --user test:test --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "nspv_notarizations", "params": ["2000"] }' -H 'content-type: text/plain;' http://127.0.0.1:$1 > curl-output.txt 8 | curl -s --user test:test --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "nspv_spentinfo", "params": ["67ffe0eaecd6081de04675c492a59090b573ee78955c4e8a85b8ac0be0e8e418", "1"] }' -H 'content-type: text/plain;' http://127.0.0.1:$1 > curl-output.txt 9 | curl -s --user test:test --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "nspv_txproof", "params": ["67ffe0eaecd6081de04675c492a59090b573ee78955c4e8a85b8ac0be0e8e418", "2673"] }' -H 'content-type: text/plain;' http://127.0.0.1:$1 > curl-output.txt 10 | done 11 | -------------------------------------------------------------------------------- /scripts/dexp2p/multi-server/README.md: -------------------------------------------------------------------------------- 1 | ## 0 - Server preapration 2 | 3 | Run `prepare_dexp2p_node_ms.sh` 4 | 5 | ## A - start nodes on multiply servers 6 | 7 | 1) Set NODESAMOUNT env variable 8 | 2) Set `is_first_server` in nodes spawn script for a frist server (TODO: why it's not env?) 9 | 2.1) for each next server add new ip of previous server in ips array of spawn script 10 | 11 | ## B - spamming (after all nodes started) 12 | 13 | 1) Start spam on each node by `./dexp2p_start_spam_ms.sh ` 14 | 15 | ## C - orderbooks collecting 16 | 17 | 0) Set self IP and nodes IP in `server_ips` list of `python3 dexp2p_save_orderbooks_ms.py` 18 | 19 | 1) Run `python3 dexp2p_save_orderbooks_ms.py` 20 | 21 | packages of server's nodes will be in `packages` directory 22 | orderbooks for each nodeip_port will be in `orderbooks` directory 23 | 24 | 25 | ## D - orderbooks parsing 26 | 27 | 1) run `python3 dexp2p_orderbooks_parser_ms.py` - it should parse files from step B into something human readable 28 | 29 | ## E - re-run tests 30 | 31 | 1) Kill all daemons (something like a `ps aux | grep DEX` and then `kill -9 {firstPID..lastPID}` or `pkill komodod` if you don't have another komodod daemons 32 | 2) ./dexp2p_clean.sh 33 | 3) return to A 34 | -------------------------------------------------------------------------------- /scripts/dexp2p/multi-server/dexp2p_save_orderbooks_ms.py: -------------------------------------------------------------------------------- 1 | from slickrpc import Proxy, exc 2 | import json 3 | import os 4 | 5 | proxies_to_create = int(os.getenv('NODESAMOUNT')) 6 | 7 | server_ips = ["159.69.45.70", "95.217.44.58"] 8 | 9 | # creating rpc proxies for NODESAMOUNT 10 | for i in range(proxies_to_create): 11 | rpcport = 7000 + i 12 | globals()['proxy_%s' % i] = Proxy("http://%s:%s@127.0.0.1:%d" % ("test", "test", int(rpcport))) 13 | # getting DEX_list from each node for each port tag 14 | iter_port = 7000 15 | while iter_port < (7000 + proxies_to_create): 16 | dex_list = globals()['proxy_%s' % i].DEX_list("0", "0", str(iter_port)) 17 | # separating by server IP 18 | for server_ip in server_ips: 19 | matches_for_ip = [] 20 | for match in dex_list["matches"]: 21 | if server_ip in match["payload"]: 22 | matches_for_ip.append(match) 23 | file_name = str(rpcport) + '_' + server_ip + "_" + str(iter_port) + ".json" 24 | matches_json = json.dumps(matches_for_ip) 25 | with open('spam_p2p/orderbooks/' + file_name, "w+") as json_file: 26 | json.dump(matches_json, json_file) 27 | iter_port = iter_port + 1 -------------------------------------------------------------------------------- /scripts/libnspv_clients_spam.py: -------------------------------------------------------------------------------- 1 | import time 2 | import subprocess 3 | import requests 4 | 5 | """ 6 | Libnspv has no analog to komodod's -connect= parameter 7 | You are supposed to run this script after modifying coins file 8 | and add a 0 && to the if statement on line 389 in netspv.c. 9 | Obviously, recompile nspv executable with this changes. 10 | """ 11 | 12 | # init params 13 | nspv_clients_to_start = 100 14 | ac_name = 'ILN' 15 | userpass = 'uerpass' 16 | 17 | 18 | # getinfo method execution 19 | def nspv_getpeerinfo(node_ip, user_pass): 20 | params = {'userpass': user_pass, 21 | 'method': 'getpeerinfo'} 22 | r = requests.post(node_ip, json=params) 23 | return r.content 24 | 25 | 26 | def main(): 27 | # start numnodes libnspv daemons, changing port 28 | for i in range(nspv_clients_to_start): 29 | command = ['./nspv', ac_name, '-p', str(7000 + i)] 30 | # subprocess.call(['./nspv', ac_name, '-p', str(7000 + i)]) 31 | subprocess.Popen(command, shell=False, stderr=subprocess.PIPE, stdout=subprocess.PIPE) 32 | 33 | time.sleep(2) 34 | 35 | while True: 36 | for i in range(nspv_clients_to_start): 37 | nodeip = 'http://127.0.0.1' + ":" + str(7000 + i) 38 | try: 39 | nspv_getinfo_output = nspv_getpeerinfo(nodeip, userpass) 40 | print(nspv_getinfo_output) 41 | except Exception as e: 42 | print(e) 43 | 44 | 45 | if __name__ == '__main__': 46 | main() 47 | -------------------------------------------------------------------------------- /rekt_inspector.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from lib import tuilib 4 | 5 | AC_NAME = "BETSTEST" 6 | 7 | rpc_connection = tuilib.def_credentials(AC_NAME) 8 | 9 | while True: 10 | # scanning list 11 | prices_list = rpc_connection.priceslist("open") 12 | print(tuilib.colorize("Looking for rekts... Current height is: " + str(rpc_connection.getinfo()["blocks"]), "blue")) 13 | for position in prices_list: 14 | position_info = rpc_connection.pricesinfo(position) 15 | if position_info["rekt"] == 1: 16 | try: 17 | rekt_raw = rpc_connection.pricesrekt(position, position_info["LastHeight"])["hex"] 18 | rekt_txid = rpc_connection.sendrawtransaction(rekt_raw) 19 | print(tuilib.colorize("MUAHAHA REEEEKTED! TXID: " + rekt_txid, "green")) 20 | print(tuilib.colorize("Position size: " + str(position_info["TotalPositionSize"]), "magenta")) 21 | except Exception as e: 22 | print(e) 23 | # waiting for next block to perform scan again 24 | prev_scan_height = int(rpc_connection.getinfo()["blocks"]) 25 | while True: 26 | current_height = int(rpc_connection.getinfo()["blocks"]) 27 | height_difference = current_height - prev_scan_height 28 | if height_difference == 0: 29 | # print(current_height) 30 | # print(prev_scan_height) 31 | # print(colorize("Waiting for next block before scan for rekts", "blue")) 32 | pass 33 | else: 34 | break 35 | -------------------------------------------------------------------------------- /scripts/nspv_clients_spawn.py: -------------------------------------------------------------------------------- 1 | import os 2 | import time 3 | import sys 4 | import subprocess 5 | from slickrpc import Proxy 6 | 7 | # init params 8 | nspv_clients_to_start = 500 9 | ac_name = 'ILN' 10 | node = '192.168.0.106' 11 | 12 | # pre-creating separate folders 13 | for i in range(nspv_clients_to_start): 14 | os.mkdir("node_" + str(i)) 15 | open("node_" + str(i) + "/" + ac_name + ".conf", 'a').close() 16 | with open("node_" + str(i) + "/" + ac_name + ".conf", 'a') as conf: 17 | conf.write("rpcuser=test" + '\n') 18 | conf.write("rpcpassword=test" + '\n') 19 | conf.write("rpcport=" + str(7000 + i) + '\n') 20 | 21 | # start numnodes daemons, changing folder name and port 22 | for i in range(nspv_clients_to_start): 23 | subprocess.call(['./komodod', '-ac_name=' + ac_name, 24 | '-conf=' + sys.path[0] + '/node_' + str(i) + "/" + ac_name + ".conf", 25 | '-rpcport=' + str(7000 + i), '-datadir=' + sys.path[0] + '/node_' + str(i), 26 | '-ac_supply=10000000000', '-ac_cc=2', '-nSPV=1', '-connect=' + node, '-listen=0', '-daemon']) 27 | 28 | time.sleep(2) 29 | 30 | # creating rpc proxies for all nodes 31 | for i in range(nspv_clients_to_start): 32 | rpcport = 7000 + i 33 | globals()['proxy_%s' % i] = Proxy("http://%s:%s@127.0.0.1:%d" % ("test", "test", int(rpcport))) 34 | 35 | while True: 36 | for i in range(nspv_clients_to_start): 37 | try: 38 | nspv_getinfo_output = globals()['proxy_%s' % i].nspv_getinfo() 39 | print(nspv_getinfo_output) 40 | except Exception as e: 41 | print(e) 42 | -------------------------------------------------------------------------------- /scripts/chainstart/chainconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "TONYCI": { 3 | "rpc_user": "test", 4 | "rpcpassword": "test", 5 | "rpcallowip": "0.0.0.0/0", 6 | "rpcport": 7000, 7 | "port": 6000, 8 | "rpcbind": "0.0.0.0", 9 | "ac_name": "TONYCI", 10 | "ac_reward": "100000000000", 11 | "ac_supply": "10000000000", 12 | "ac_cc": "2" 13 | }, 14 | "HUSH3": { 15 | "rpc_user": "test", 16 | "rpcpassword": "test", 17 | "rpcallowip": "0.0.0.0/0", 18 | "rpcport": 7000, 19 | "rpcbind": "0.0.0.0", 20 | "ac_name": "HUSH3", 21 | "ac_sapling": "1", 22 | "ac_reward": "0,1125000000,562500000", 23 | "ac_halving": "129,340000,840000", 24 | "ac_end": "128,340000,5422111", 25 | "ac_eras": "3", 26 | "ac_blocktime": "150", 27 | "ac_cc": "2", 28 | "ac_ccenable": "228,234,235,236,241", 29 | "ac_founders": "1", 30 | "ac_supply": "6178674", 31 | "ac_perc": "11111111", 32 | "clientname": "GoldenSandtrout", 33 | "addnode": "188.165.212.101", 34 | "ac_cclib": "hush3", 35 | "ac_script": "76a9145eb10cf64f2bab1b457f1f25e658526155928fac88ac" 36 | }, 37 | "KMD": { 38 | "rpc_user": "test", 39 | "rpcpassword": "test", 40 | "rpcallowip": "0.0.0.0/0", 41 | "rpcport": 7000, 42 | "rpcbind": "0.0.0.0" 43 | }, 44 | "PIRATE": { 45 | "rpc_user": "test", 46 | "rpcpassword": "test", 47 | "rpcallowip": "0.0.0.0/0", 48 | "rpcport": 7000, 49 | "rpcbind": "0.0.0.0", 50 | "ac_name": "PIRATE", 51 | "ac_supply": "0", 52 | "ac_reward": "25600000000", 53 | "ac_halving": "77777", 54 | "ac_private": "1", 55 | "addnode": "178.63.77.56" 56 | } 57 | } -------------------------------------------------------------------------------- /lib/mm2lib.py: -------------------------------------------------------------------------------- 1 | from bitcoin.core.script import * 2 | from bitcoin.core import Hash160 3 | import bitcoin.base58 4 | import struct 5 | import unittest 6 | from hashlib import sha256 7 | 8 | 9 | def payment_script(time_lock, secret_hash, pub_0, pub_1): 10 | """ 11 | this function making payment script for mm2 atomic swap 12 | ported from mm2 rust code 13 | """ 14 | return CScript([OP_IF, struct.pack('> ") 35 | try: 36 | if int(choice) < 0: 37 | raise ValueError 38 | # Call the matching function 39 | if list(menuItems[int(choice)].keys())[0] == "Pegs Module Readme": 40 | list(menuItems[int(choice)].values())[0]('docs/pegs_module.md') 41 | else: 42 | list(menuItems[int(choice)].values())[0]() 43 | except (ValueError, IndexError): 44 | pass 45 | 46 | 47 | if __name__ == "__main__": 48 | while True: 49 | with (open("lib/logo.txt", "r")) as logo: 50 | for line in logo: 51 | print(line, end='') 52 | time.sleep(0.04) 53 | print("\n") 54 | break 55 | main() 56 | -------------------------------------------------------------------------------- /scripts/dexp2p/multi-server/dexp2p_orderbooks_parser_ms.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | 4 | # loading nodes packages nodeport[n] : ["id"]["hash"] 5 | package_files_list = os.listdir('spam_p2p/packages') 6 | 7 | nodes_packages = {} 8 | last_port = 7000 + int(os.getenv('NODESAMOUNT')) 9 | 10 | self_ip = "159.69.45.70" 11 | 12 | for node_port in range(7000, last_port): 13 | nodes_packages[node_port] = {} 14 | for file in package_files_list: 15 | if int(file.split("_")[1]) == node_port: 16 | with open('spam_p2p/packages/' + file) as json_file: 17 | packages_counter = 0 18 | list_of_pacakges = json_file.readlines() 19 | for package in list_of_pacakges: 20 | package_json = json.loads(package) 21 | packages_counter = packages_counter + 1 22 | nodes_packages[node_port][packages_counter] = {} 23 | nodes_packages[node_port][packages_counter]["id"] = package_json["result"]["id"] 24 | nodes_packages[node_port][packages_counter]["hash"] = package_json["result"]["hash"] 25 | nodes_packages[node_port]["total"] = packages_counter 26 | 27 | 28 | # loading nodes orderbooks nodeport[n] : [tag][orderbook] 29 | orderbook_files_list = os.listdir('spam_p2p/orderbooks') 30 | 31 | # comparing broadcasted packages vs received orderbooks 32 | for nodeport in nodes_packages: 33 | packages_amount_sent = nodes_packages[nodeport]["total"] 34 | print("Packages sent by node " + self_ip + ":" + str(nodeport) + " : " + str(packages_amount_sent)) 35 | for file in orderbook_files_list: 36 | with open('spam_p2p/orderbooks/' + file) as json_file: 37 | file_content = json.load(json_file) 38 | packages_amount = len(json.loads(file_content)) 39 | node_address = file.split("_")[1] + ":" + file.split("_")[2][:-5] 40 | print("Packages received from node " + node_address + " " + str(packages_amount) + " by node " + self_ip + ":" + file.split("_")[0]) -------------------------------------------------------------------------------- /scripts/find_uuid_by_txid.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Usage: $./find_uuid_by_txid.py txid path_to_jsons 3 | # Where txid - transaction included in desired swap 4 | # path_to_jsons - path to swaps json directory 5 | import os 6 | import json 7 | import sys 8 | 9 | 10 | def get_files_in_directory(dirpath): 11 | files = [f for f in os.listdir(dirpath) if os.path.isfile(f)] 12 | return files 13 | 14 | 15 | def json_files_loader(jsons_list): # jsons_list - list of files to read 16 | dicts_list = [] 17 | for json_file in jsons_list: 18 | if ".json" in json_file: 19 | with open(json_file, 'r') as f: 20 | fstring = (f.read()).encode('utf-8').strip() 21 | jsf = json.loads(fstring) 22 | dicts_list.append(jsf) 23 | return dicts_list 24 | 25 | 26 | def find_uuid_by_txhash(dirpath, txhash): 27 | jflist = get_files_in_directory(dirpath) 28 | dicts = json_files_loader(jflist) 29 | for d in dicts: 30 | swap_uuid = d.get('uuid') 31 | print('.. checking ' + swap_uuid) 32 | events = d.get('events') 33 | for event in events: 34 | try: 35 | tx = event.get('event').get('data').get('tx_hash') 36 | if tx == txhash: 37 | return swap_uuid 38 | else: 39 | pass 40 | except Exception as e: 41 | pass 42 | 43 | 44 | def main(): 45 | """Prints first swap uuid found by txhash, if any""" 46 | try: 47 | txhash = sys.argv[1] 48 | try: 49 | path = sys.argv[2] 50 | uuid = find_uuid_by_txhash(path, txhash) 51 | if uuid: 52 | print("\ntx found in swap : " + str(uuid)) 53 | else: 54 | print("\n" + txhash + " not found") 55 | except Exception as e: 56 | print("Error: " + str(e)) 57 | except Exception as e: 58 | print(e) 59 | print("Usage: ./find_uuid_by_txid.py txid path_to_jsons") 60 | 61 | 62 | if __name__ == '__main__': 63 | main() 64 | -------------------------------------------------------------------------------- /scripts/dexp2p/dexp2p_orderbooks_parser.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | 4 | # loading nodes packages nodeport[n] : ["id"]["hash"] 5 | package_files_list = os.listdir('spam_p2p/packages') 6 | 7 | nodes_packages = {} 8 | last_port = 7000 + int(os.getenv('NODESAMOUNT')) 9 | 10 | for node_port in range(7000, last_port): 11 | nodes_packages[node_port] = {} 12 | for file in package_files_list: 13 | if int(file[4:-13]) == node_port: 14 | with open('spam_p2p/packages/' + file) as json_file: 15 | packages_counter = 0 16 | list_of_pacakges = json_file.readlines() 17 | for package in list_of_pacakges: 18 | package_json = json.loads(package) 19 | packages_counter = packages_counter + 1 20 | nodes_packages[node_port][packages_counter] = {} 21 | nodes_packages[node_port][packages_counter]["id"] = package_json["result"]["id"] 22 | nodes_packages[node_port][packages_counter]["hash"] = package_json["result"]["hash"] 23 | nodes_packages[node_port]["total"] = packages_counter 24 | 25 | 26 | # loading nodes orderbooks nodeport[n] : [tag][orderbook] 27 | orderbook_files_list = os.listdir('spam_p2p/orderbooks') 28 | 29 | nodes_orderbooks = {} 30 | 31 | for node_port in range(7000, last_port): 32 | nodes_orderbooks[node_port] = {} 33 | for file in orderbook_files_list: 34 | if int(file[4:-13]) == node_port: 35 | with open('spam_p2p/orderbooks/' + file) as json_file: 36 | nodes_orderbooks[node_port][file[13:-4]] = json.loads(json_file.read()) 37 | 38 | # comparing broadcasted packages vs received orderbooks 39 | for nodeport in nodes_packages: 40 | packages_amount_sent = nodes_packages[nodeport]["total"] 41 | print("Packages sent by node " + str(nodeport) + " : " + str(packages_amount_sent)) 42 | for nodeport_orderbook in nodes_orderbooks: 43 | packages_amount_received = nodes_orderbooks[nodeport_orderbook][str(nodeport)]["result"]["n"] 44 | print("Received by node " + str(nodeport_orderbook) + " " + str(packages_amount_received)) 45 | print("\n") 46 | print("\n") -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python tools and libs for Komodo CC modules usage demonstration 2 | 3 | These tools creating for demonstration and partial automation of Komodo cryptoconditions modules testing. (RogueCC game, AssetsCC, OraclesCC, GatewaysCC, MarmaraCC, ...) 4 | 5 | 6 | Developer installation (on Ubuntu 18.04) : 7 | 8 | Python3 required for execution: 9 | 10 | * `sudo apt-get install python3.6 python3-pip libgnutls28-dev` 11 | 12 | pip packages needed: 13 | 14 | * `pip3 install setuptools wheel slick-bitcoinrpc` 15 | * or `pip3 install -r requirements.txt` 16 | 17 | For prices visualisation you'll also need additonal Dash framework deps: 18 | 19 | * `pip3 install dash dash-daq flask pandas dash-auth==1.2.0 qrcode` 20 | 21 | Starting: 22 | 23 | # Web-app interface for PricesCC 24 | 25 | To start web-app just sync REKT0 daemon first and then run: 26 | 27 | `python3 prices_app_v2.py` 28 | 29 | By default app will be availiable on port 777 (can be changed in prices_app_v2.py, as well as assetchain name) 30 | 31 | ![alt text](https://i.imgur.com/hnpYaYG.png) 32 | 33 | # TUI for RogueCC 34 | 35 | If you're looking for player 3 in 1 (daemon + game + TUI) multiOS bundle - please check `releases` of this repo. 36 | 37 | `python3 rogue_tui.py` 38 | 39 | ![alt text](https://i.imgur.com/gkcxMGt.png) 40 | 41 | # TUI for OraclesCC 42 | 43 | Have files uploader/downloader functionality - also there is a AWS branch for AWS certificates uploading demonstration 44 | 45 | `python3 oracles_cc_tui.py` 46 | 47 | ![alt text](https://i.imgur.com/tfHwRqc.png) 48 | 49 | # TUI for GatewaysCC 50 | 51 | ![alt text](https://i.imgur.com/c8DPfpp.png) 52 | 53 | `python3 gateways_creation_tui.py` 54 | 55 | `python3 gateways_usage_tui.py` 56 | 57 | At the moment raw version of manual gateway how-to guide can be found here: https://docs.komodoplatform.com/basic-docs/antara/antara-tutorials/gateways-module-tutorial.html#tutorial I advice to read it before you start use this tool to understand the flow. 58 | 59 | # TUI for MarmaraCC 60 | 61 | `python3 marmara_tui.py` 62 | 63 | ![alt text](https://i.imgur.com/uonMWHl.png) 64 | 65 | # TUI for AssetsCC (not much finished) 66 | 67 | `python3 assets_cc_tui.py` 68 | 69 | Before execution be sure than daemon for needed AC up. 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /scripts/find_uuids_by_addr.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Usage: $./find_uuids_by_addr.py address path_to_jsons 3 | import os 4 | import json 5 | import sys 6 | 7 | 8 | def get_files_in_directory(dirpath): 9 | files = [f for f in os.listdir(dirpath) if os.path.isfile(f)] 10 | return files 11 | 12 | 13 | def json_files_loader(jsons_list): # jsons_list - list of files to read 14 | dicts_list = [] 15 | for json_file in jsons_list: 16 | if ".json" in json_file: 17 | with open(json_file, 'r') as f: 18 | fstring = (f.read()).encode('utf-8').strip() 19 | jsf = json.loads(fstring) 20 | dicts_list.append(jsf) 21 | return dicts_list 22 | 23 | 24 | def find_uuids_by_addr(dirpath, address): 25 | """Returns list with all swaps(uuids) made to/from address""" 26 | jflist = get_files_in_directory(dirpath) 27 | dicts = json_files_loader(jflist) 28 | swaps_list = [] 29 | for d in dicts: 30 | swap_uuid = d.get('uuid') 31 | print('.. checking ' + swap_uuid) 32 | events = d.get('events') 33 | for event in events: 34 | try: 35 | from_field = event.get('event').get('data').get('from') 36 | if address in from_field: 37 | swaps_list.append(swap_uuid) 38 | break 39 | to_field = event.get('event').get('data').get('to') 40 | if address in to_field: 41 | swaps_list.append(swap_uuid) 42 | break 43 | except Exception as e: 44 | pass 45 | return swaps_list 46 | 47 | 48 | def main(): 49 | """Prints all swaps(uuids) made to/from address if any""" 50 | try: 51 | address = sys.argv[1] 52 | try: 53 | path = sys.argv[2] 54 | swaps = find_uuids_by_addr(path, address) 55 | if swaps: 56 | print("\nfound in swaps : " + str(swaps)) 57 | else: 58 | print("\n" + address + " not found") 59 | except Exception as e: 60 | print("Error: " + str(e)) 61 | except Exception as e: 62 | print(e) 63 | print("Usage: ./find_uuids_by_addr.py address path_to_jsons") 64 | 65 | 66 | if __name__ == '__main__': 67 | main() 68 | -------------------------------------------------------------------------------- /assets_cc_tui.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from lib import rpclib, tuilib 4 | import os 5 | import time 6 | 7 | 8 | header = "\ 9 | ___ _ _____ \n\ 10 | / _ \ | | / __ \\\n\ 11 | / /_\ \ ___ ___ ___ | |_ ___ | / \/\n\ 12 | | _ |/ __|/ __| / _ \| __|/ __|| | \n\ 13 | | | | |\__ \\\__ \| __/| |_ \__ \| \__/\\\n\ 14 | \_| |_/|___/|___/ \___| \__||___/ \____/\n" 15 | 16 | 17 | menuItems = [ 18 | {"Check current connection": tuilib.getinfo_tui}, 19 | {"Check mempool": tuilib.print_mempool}, 20 | {"Print tokens list": tuilib.print_tokens_list}, 21 | {"Check my tokens balances" : tuilib.print_tokens_balances}, 22 | # transfer tokens (pre-print tokens balances) 23 | {"Create token": tuilib.token_create_tui}, 24 | # trading zone - pre-print token orders - possible to open order or fill existing one 25 | {"Exit": exit} 26 | ] 27 | 28 | 29 | def main(): 30 | while True: 31 | os.system('clear') 32 | print(tuilib.colorize(header, 'pink')) 33 | print(tuilib.colorize('CLI version 0.2 by Anton Lysakov\n', 'green')) 34 | for item in menuItems: 35 | print(tuilib.colorize("[" + str(menuItems.index(item)) + "] ", 'blue') + list(item.keys())[0]) 36 | choice = input(">> ") 37 | try: 38 | if int(choice) < 0: 39 | raise ValueError 40 | # Call the matching function 41 | if list(menuItems[int(choice)].keys())[0] == "Exit": 42 | list(menuItems[int(choice)].values())[0]() 43 | else: 44 | list(menuItems[int(choice)].values())[0](rpc_connection) 45 | except (ValueError, IndexError): 46 | pass 47 | 48 | 49 | if __name__ == "__main__": 50 | while True: 51 | try: 52 | print(tuilib.colorize("Welcome to the GatewaysCC TUI!\n" 53 | "Please provide asset chain RPC connection details for initialization", "blue")) 54 | rpc_connection = tuilib.rpc_connection_tui() 55 | rpclib.getinfo(rpc_connection) 56 | except Exception: 57 | print(tuilib.colorize("Cant connect to RPC! Please re-check credentials.", "pink")) 58 | else: 59 | print(tuilib.colorize("Succesfully connected!\n", "green")) 60 | with (open("lib/logo.txt", "r")) as logo: 61 | for line in logo: 62 | print(line, end='') 63 | time.sleep(0.04) 64 | print("\n") 65 | break 66 | main() 67 | 68 | -------------------------------------------------------------------------------- /prices_visualization_server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import dash 4 | from dash.dependencies import Input, Output 5 | import dash_core_components as dcc 6 | import dash_html_components as html 7 | 8 | import flask 9 | import pandas as pd 10 | import time 11 | import os 12 | 13 | from lib import tuilib, visualization_lib 14 | 15 | rpc_connection = tuilib.def_credentials("REKT0") 16 | server = flask.Flask('app') 17 | server.secret_key = os.environ.get('secret_key', 'secret') 18 | 19 | visualization_lib.make_csv_for_stack(rpc_connection, ["BTC_USD", "KMD_BTC", "*", 1], "BTC_USD*KMD_BTC", "435") 20 | 21 | df = pd.read_csv('BTC_USD*KMD_BTC.csv') 22 | 23 | 24 | app = dash.Dash('app', server=server) 25 | 26 | app.scripts.config.serve_locally = False 27 | 28 | pair_names = ["BTC_USD*KMD_BTC"] 29 | 30 | options_arg = [] 31 | for pair in pair_names: 32 | pair_arg = {} 33 | pair_arg['label'] = pair 34 | pair_arg['value'] = pair 35 | options_arg.append(pair_arg) 36 | 37 | app.layout = html.Div([ 38 | html.H1('Prices provided by Komodo PricesCC trustless oracle'), 39 | dcc.Dropdown( 40 | id='my-dropdown', 41 | options=options_arg, 42 | value='BTC_USD*KMD_BTC' 43 | ), 44 | dcc.Graph(id='my-graph') 45 | ], className="container") 46 | 47 | @app.callback(Output('my-graph', 'figure'), 48 | [Input('my-dropdown', 'value')]) 49 | 50 | def update_graph(selected_dropdown_value): 51 | 52 | visualization_lib.make_csv_for_stack(rpc_connection, ["BTC_USD", "KMD_BTC", "*", 1], "BTC_USD*KMD_BTC", "435") 53 | df = pd.read_csv('BTC_USD*KMD_BTC.csv') 54 | 55 | dff = df[df['pair'] == selected_dropdown_value] 56 | return { 57 | 'data': [ 58 | 59 | { 60 | 'x': dff.date, 61 | 'y': dff.price1, 62 | 'line': { 63 | 'width': 3, 64 | 'shape': 'spline' 65 | } 66 | }, 67 | 68 | { 69 | 'x': dff.date, 70 | 'y': dff.price2, 71 | 'line': { 72 | 'width': 3, 73 | 'shape': 'spline' 74 | } 75 | }, 76 | 77 | { 78 | 'x': dff.date, 79 | 'y': dff.price3, 80 | 'line': { 81 | 'width': 3, 82 | 'shape': 'spline' 83 | } 84 | }, 85 | ], 86 | 'layout': { 87 | 'margin': { 88 | 'l': 30, 89 | 'r': 20, 90 | 'b': 30, 91 | 't': 20 92 | } 93 | } 94 | } 95 | 96 | 97 | if __name__ == '__main__': 98 | app.run_server(host = '0.0.0.0') 99 | -------------------------------------------------------------------------------- /generate_addresses.py: -------------------------------------------------------------------------------- 1 | # test purposes script, generates needed amount of pre-funded addresses 2 | from slickrpc import Proxy 3 | from lib import rpclib 4 | import json 5 | import time 6 | 7 | # settings 8 | amount_of_addresses = 2 9 | amount_of_funding = 1 10 | 11 | # generate addresses to fund 12 | kmd_rpc_proxy_auth = rpclib.get_rpc_details("KMD") 13 | 14 | rpc_user = kmd_rpc_proxy_auth[0] 15 | rpc_password = kmd_rpc_proxy_auth[1] 16 | rpc_port = int(kmd_rpc_proxy_auth[2]) 17 | 18 | rpc_proxy_kmd = Proxy("http://%s:%s@127.0.0.1:%d"%(rpc_user, rpc_password, rpc_port)) 19 | 20 | addresses_to_fund = {} 21 | 22 | while amount_of_addresses > 0: 23 | new_address = rpc_proxy_kmd.getnewaddress() 24 | new_privkey = rpc_proxy_kmd.dumpprivkey(new_address) 25 | addresses_to_fund[new_address] = { "private_key" : new_privkey, 26 | "is_funded_rick": False, "is_funded_morty": False } 27 | amount_of_addresses -= 1 28 | 29 | 30 | # fund RICK 31 | rick_rpc_proxy_auth = rpclib.get_rpc_details("RICK") 32 | rick_txs_count = 0 33 | rpc_proxy_rick = Proxy("http://%s:%s@127.0.0.1:%d"%(rick_rpc_proxy_auth[0], rick_rpc_proxy_auth[1], int(rick_rpc_proxy_auth[2]))) 34 | for address in addresses_to_fund: 35 | if not addresses_to_fund[address]["is_funded_rick"]: 36 | rick_funding_txid = rpc_proxy_rick.sendtoaddress(address, amount_of_funding) 37 | print(rick_funding_txid) 38 | # TODO: confirm that its really mined 39 | addresses_to_fund[address]["is_funded_rick"] = True 40 | rick_txs_count += 1 41 | # to not fill the blocks completely 42 | if rick_txs_count % 1000 == 0: 43 | time.sleep(60) 44 | 45 | 46 | # TODO: funding processes can be parallel since its different blockchains 47 | 48 | # fund MORTY 49 | morty_rpc_proxy_auth = rpclib.get_rpc_details("MORTY") 50 | morty_txs_count = 0 51 | rpc_proxy_morty = Proxy("http://%s:%s@127.0.0.1:%d"%(morty_rpc_proxy_auth[0], morty_rpc_proxy_auth[1], int(morty_rpc_proxy_auth[2]))) 52 | for address in addresses_to_fund: 53 | if not addresses_to_fund[address]["is_funded_morty"]: 54 | morty_funding_txid = rpc_proxy_morty.sendtoaddress(address, amount_of_funding) 55 | print(morty_funding_txid) 56 | # TODO: confirm that its really mined 57 | addresses_to_fund[address]["is_funded_morty"] = True 58 | morty_txs_count += 1 59 | # to not fill the blocks completely 60 | if morty_txs_count % 1000 == 0: 61 | time.sleep(60) 62 | 63 | 64 | addys_json = json.dumps(addresses_to_fund, indent=4) 65 | with open("funded_addresses.json", "w+") as file: 66 | file.write(addys_json) 67 | 68 | -------------------------------------------------------------------------------- /scripts/chainstart/README.md: -------------------------------------------------------------------------------- 1 | Script starts X komodo nodes locally, usage is simple: 2 | `./run.sh` 3 | 4 | Depends on: 5 | ``` 6 | python 3.6+ 7 | 8 | pip install wheel \ 9 | setuptools \ 10 | pycurl \ 11 | ujson \ 12 | slick-bitcoinrpc \ 13 | wget 14 | 15 | Or: 16 | 17 | pip install -r requirements.txt 18 | ``` 19 | 20 | Nodes configuration with ENV vars: 21 | 22 | note: ENV vars are exported in run.sh script, you can set variables separately and start nodes after with `python3 chainstart.py` 23 | 24 | `CLIENTS` - amount of nodes to start, for each node following vars should be set: 25 | 26 | `TEST_ADDYN` - nodes address 27 | `TEST_WIFN` - wif to be imported on startup 28 | `TEST_PUBKEYN` - pubkey, will be used as start parameter `-pubkey=` 29 | Here `N` is node number, starting from 0 30 | 31 | `CHAIN_MODE` - set mode, available: 32 | REGULAR - normal chain start 33 | DEX1 - appends -dexp2p=1 to start args 34 | DEX2 - appends -dexp2p=2 35 | REGETST - appends -regtest 36 | 37 | `IS_BOOTSTRAP_NEEDED` - Ture or False 38 | If bootstrap param set to True script will look for bootstrap.tar.gz file in local directory, or bootstrap url set in following variable: 39 | `BOOTSTRAP_URL` - url to download bootstrap from if IS_BOOTSTRAP_NEEDED is True 40 | 41 | `BINARYPATH` - path to `komodod[.exe]` binary, defaults to ../../src/komodod if not set 42 | 43 | `CHAIN` - chain to start 44 | CHAIN should be set in `chainconfig.json`, similair to komodo's assetchains.json 45 | Example: 46 | ```json 47 | { 48 | "RICK": { 49 | "ac_supply": "90000000000", 50 | "ac_reward": "100000000", 51 | "ac_cc": "3", 52 | "ac_staked": "10", 53 | "ac_name": "RICK", 54 | "addnode": "138.201.136.145", 55 | "rpc_user": "ricktest", 56 | "rpcpassword": "ricktest", 57 | "rpcallowip": "0.0.0.0/0", 58 | "rpcport": 7000, 59 | "rpcbind": "0.0.0.0" 60 | }, 61 | "MORTY": { 62 | "ac_supply": "90000000000", 63 | "ac_reward": "100000000", 64 | "ac_name": "MORTY", 65 | "ac_cc": "3", 66 | "ac_staked": "10", 67 | "rpc_user": "mortytest", 68 | "addnode": "95.217.44.58", 69 | "rpcpassword": "mortytest", 70 | "rpcallowip": "0.0.0.0/0", 71 | "rpcport": 7000, 72 | "rpcbind": "0.0.0.0" 73 | } 74 | } 75 | ``` 76 | 77 | Values `"rpc_user", "rpcpassword", "rpcallowip", "rpcport", "rpcbind"` will be set in CHAIN.conf 78 | 79 | Configuration files, blocks, .dats, etc are located in ./node_N directory. 80 | Easy way to use komodo-cli with started nodes is to pass -conf= with rpc call, example: 81 | `/komodo-clii -conf=$HOME/scripts/node_0/RICK.conf getinfo` 82 | -------------------------------------------------------------------------------- /gateways_creation_tui.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from lib import rpclib, tuilib 4 | import os 5 | import time 6 | 7 | header = "\ 8 | _____ _ _____ _____ \n\ 9 | | __ \ | | / __ \/ __ \\\n\ 10 | | | \/ __ _| |_ _____ ____ _ _ _ ___| / \/| / \/\n\ 11 | | | __ / _` | __/ _ \ \ /\ / / _` | | | / __| | | | \n\ 12 | | |_\ \ (_| | || __/\ V V / (_| | |_| \__ \ \__/\| \__/\\\n\ 13 | \____/\__,_|\__\___| \_/\_/ \__,_|\__, |___/\____/ \____/\n\ 14 | __/ | \n\ 15 | |___/ \n" 16 | 17 | 18 | menuItems = [ 19 | {"Check current connection": tuilib.getinfo_tui}, 20 | {"Check mempool": tuilib.print_mempool}, 21 | {"Create token": tuilib.token_create_tui}, 22 | {"Create oracle": tuilib.oracle_create_tui}, 23 | {"Register as publisher for oracle": tuilib.oracle_register_tui}, 24 | {"Subscribe on oracle (+UTXO generator)": tuilib.oracle_subscription_utxogen}, 25 | {"Bind Gateway": tuilib.gateways_bind_tui}, 26 | {"Exit": exit} 27 | ] 28 | 29 | 30 | def main(): 31 | while True: 32 | os.system('clear') 33 | print(tuilib.colorize(header, 'pink')) 34 | print(tuilib.colorize('CLI version 0.2\n', 'green')) 35 | for item in menuItems: 36 | print(tuilib.colorize("[" + str(menuItems.index(item)) + "] ", 'blue') + list(item.keys())[0]) 37 | choice = input(">> ") 38 | try: 39 | if int(choice) < 0: 40 | raise ValueError 41 | # Call the matching function 42 | if list(menuItems[int(choice)].keys())[0] == "Exit": 43 | list(menuItems[int(choice)].values())[0]() 44 | else: 45 | list(menuItems[int(choice)].values())[0](rpc_connection) 46 | except (ValueError, IndexError): 47 | pass 48 | 49 | 50 | if __name__ == "__main__": 51 | while True: 52 | try: 53 | print(tuilib.colorize("Welcome to the GatewaysCC TUI!\n" 54 | "Please provide asset chain RPC connection details for initialization", "blue")) 55 | rpc_connection = tuilib.rpc_connection_tui() 56 | rpclib.getinfo(rpc_connection) 57 | except Exception: 58 | print(tuilib.colorize("Cant connect to RPC! Please re-check credentials.", "pink")) 59 | else: 60 | print(tuilib.colorize("Succesfully connected!\n", "green")) 61 | with (open("lib/logo.txt", "r")) as logo: 62 | for line in logo: 63 | print(line, end='') 64 | time.sleep(0.04) 65 | print("\n") 66 | break 67 | main() 68 | -------------------------------------------------------------------------------- /scripts/dexp2p/multi-server/dexp2p_auto_deploy.py: -------------------------------------------------------------------------------- 1 | from pssh.clients import ParallelSSHClient 2 | from pssh.clients import SSHClient 3 | import time 4 | 5 | # init params, write down servers IPs below 6 | hosts = [] 7 | amount_of_nodes_per_host = 10 8 | spam_duration_seconds = 5 9 | 10 | # 1 - Preparing nodes 11 | command = "rm -rf * && wget https://raw.githubusercontent.com/tonymorony/komodo-cctools-python/master/scripts/dexp2p/multi-server/prepare_dexp2p_node_ms.sh " \ 12 | "&& chmod u+x prepare_dexp2p_node_ms.sh && ./prepare_dexp2p_node_ms.sh" 13 | 14 | client = ParallelSSHClient(hosts, user="root") 15 | output = client.run_command(command, sudo=True) 16 | 17 | for node in output: 18 | for line in output[node]['stdout']: 19 | print(line) 20 | 21 | # 2 - Preparing "started nodes" file on each server 22 | i = 0 23 | for host in hosts: 24 | print("Preparing file on node " + str(i+1)) 25 | non_parallel_client = SSHClient(host, user="root") 26 | if i == 0: 27 | non_parallel_client.run_command("touch ip_list") 28 | else: 29 | line_with_hosts = "" 30 | for host in hosts[:i]: 31 | line_with_hosts += host + "\n" 32 | non_parallel_client.run_command("echo -e " + line_with_hosts + " >> ip_list") 33 | i = i + 1 34 | print("Test nodes software prepared. Starting network.") 35 | 36 | # 3 - Starting network (need to do one by one) 37 | i = 0 38 | for host in hosts: 39 | print("Starting network on node " + str(i+1)) 40 | non_parallel_client = SSHClient(host, user="root") 41 | if i == 0: 42 | is_first_env = "export IS_FIRST=True" 43 | else: 44 | is_first_env = "export IS_FIRST=False" 45 | ip_env = "NODE_IP=" + host 46 | network_start_command = "export NODESAMOUNT=" + str(amount_of_nodes_per_host) + " && " + is_first_env \ 47 | + " && " + ip_env + " && " + "python3 clients_spawn_multi_server.py" 48 | output = non_parallel_client.run_command(network_start_command, sudo=True) 49 | time.sleep(3 * amount_of_nodes_per_host + 3) 50 | i = i + 1 51 | print("Network setup completed. Starting to spam.") 52 | 53 | # 3 - Starting spam 54 | for host in hosts: 55 | non_parallel_client = SSHClient(host, user="root") 56 | output = non_parallel_client.run_command("export NODESAMOUNT=" + str(amount_of_nodes_per_host) + " && ./dexp2p_start_spam_ms.sh " + host + " " + str(spam_duration_seconds), sudo=True) 57 | time.sleep(spam_duration_seconds) 58 | 59 | # 4 - Collecting results 60 | print("Spam is finished. Collecting results") 61 | client = ParallelSSHClient(hosts, user="root") 62 | output = client.run_command("export NODESAMOUNT=" + str(amount_of_nodes_per_host) + " && python3 get_stats.py", sudo=True) 63 | for node in output: 64 | for line in output[node]['stdout']: 65 | print(line) 66 | -------------------------------------------------------------------------------- /marmara_tui.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from lib import rpclib, tuilib 4 | import os 5 | import time 6 | 7 | 8 | header = "\ 9 | ___ ___ _____ _ _ _____ \n\ 10 | | \/ | |_ _| | | |_ _|\n\ 11 | | . . | __ _ _ __ _ __ ___ __ _ _ __ __ _ | | | | | | | |\n\ 12 | | |\/| |/ _` | '__| '_ ` _ \ / _` | '__/ _` | | | | | | | | |\n\ 13 | | | | | (_| | | | | | | | | (_| | | | (_| | | | | |_| |_| |_\n\ 14 | \_| |_/\__,_|_| |_| |_| |_|\__,_|_| \__,_| \_/ \___/ \___/\n" 15 | 16 | 17 | menuItems = [ 18 | {"Check current connection": tuilib.getinfo_tui}, 19 | {"Check mempool": tuilib.print_mempool}, 20 | {"Check MARMARA info": tuilib.marmara_info_tui}, 21 | {"Lock funds for MARMARA": tuilib.marmara_lock_tui}, 22 | {"Request MARMARA cheque": tuilib.marmara_receive_tui}, 23 | {"Issue MARMARA cheque": tuilib.marmara_issue_tui}, 24 | {"Check credit loop status": tuilib.marmara_creditloop_tui}, 25 | {"Settle MARMARA loop": tuilib.marmara_settlement_tui}, 26 | {"Exit": exit} 27 | ] 28 | 29 | 30 | def main(): 31 | while True: 32 | os.system('clear') 33 | print(tuilib.colorize(header, 'pink')) 34 | print(tuilib.colorize('CLI version 0.1\n', 'green')) 35 | for item in menuItems: 36 | print(tuilib.colorize("[" + str(menuItems.index(item)) + "] ", 'blue') + list(item.keys())[0]) 37 | choice = input(">> ") 38 | try: 39 | if int(choice) < 0: 40 | raise ValueError 41 | # Call the matching function 42 | if list(menuItems[int(choice)].keys())[0] == "Exit": 43 | list(menuItems[int(choice)].values())[0]() 44 | else: 45 | list(menuItems[int(choice)].values())[0](rpc_connection) 46 | except (ValueError, IndexError): 47 | pass 48 | 49 | 50 | if __name__ == "__main__": 51 | while True: 52 | chain = input("Input assetchain name (-ac_name= value) you want to work with: ") 53 | try: 54 | print(tuilib.colorize("Welcome to the MarmaraCC TUI!\n" 55 | "Please provide asset chain RPC connection details for initialization", "blue")) 56 | rpc_connection = rpclib.def_credentials(chain) 57 | rpc_connection.getinfo() 58 | except Exception as e: 59 | print(e) 60 | print(tuilib.colorize("Cant connect to RPC! Please re-check credentials.", "pink")) 61 | else: 62 | print(tuilib.colorize("Succesfully connected!\n", "green")) 63 | with (open("lib/logo.txt", "r")) as logo: 64 | for line in logo: 65 | print(line, end='') 66 | time.sleep(0.04) 67 | print("\n") 68 | break 69 | main() 70 | -------------------------------------------------------------------------------- /oracles_cc_tui.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from lib import rpclib, tuilib 4 | import os 5 | import time 6 | 7 | header = "\ 8 | _____ _ _____ _____ \n\ 9 | | _ | | | / __ \/ __ \\\n\ 10 | | | | | _ __ __ _ ___ | | ___ ___ | / \/| / \/\n\ 11 | | | | || '__| / _` | / __|| | / _ \/ __|| | | |\n\ 12 | \ \_/ /| | | (_| || (__ | || __/\__ \| \__/\| \__/\\\n\ 13 | \___/ |_| \__,_| \___||_| \___||___/ \____/ \____/\n" 14 | 15 | menuItems = [ 16 | # TODO: Have to implement here native oracle file uploader / reader, should be dope 17 | # TODO: data publisher / converter for different types 18 | {"Check current connection": tuilib.getinfo_tui}, 19 | {"Check mempool": tuilib.print_mempool}, 20 | {"Create oracle": tuilib.oracle_create_tui}, 21 | {"Register as publisher for oracle": tuilib.oracle_register_tui}, 22 | {"Subscribe on oracle (+UTXO generator)": tuilib.oracle_subscription_utxogen}, 23 | {"Upload file to oracle": tuilib.convert_file_oracle_D}, 24 | {"Display list of files uploaded to this AC": tuilib.display_files_list}, 25 | {"Download files from oracle": tuilib.files_downloader}, 26 | {"Exit": exit} 27 | ] 28 | 29 | 30 | def main(): 31 | while True: 32 | os.system('clear') 33 | print(tuilib.colorize(header, 'pink')) 34 | print(tuilib.colorize('CLI version 0.2 by Anton Lysakov\n', 'green')) 35 | for item in menuItems: 36 | print(tuilib.colorize("[" + str(menuItems.index(item)) + "] ", 'blue') + list(item.keys())[0]) 37 | choice = input(">> ") 38 | try: 39 | if int(choice) < 0: 40 | raise ValueError 41 | # Call the matching function 42 | if list(menuItems[int(choice)].keys())[0] == "Exit": 43 | list(menuItems[int(choice)].values())[0]() 44 | else: 45 | list(menuItems[int(choice)].values())[0](rpc_connection) 46 | except (ValueError, IndexError): 47 | pass 48 | 49 | 50 | if __name__ == "__main__": 51 | while True: 52 | try: 53 | print(tuilib.colorize("Welcome to the OraclesCC TUI!\n" 54 | "Please provide asset chain RPC connection details for initialization", "blue")) 55 | rpc_connection = tuilib.rpc_connection_tui() 56 | rpclib.getinfo(rpc_connection) 57 | except Exception: 58 | print(tuilib.colorize("Cant connect to RPC! Please re-check credentials.", "pink")) 59 | else: 60 | print(tuilib.colorize("Succesfully connected!\n", "green")) 61 | with (open("lib/logo.txt", "r")) as logo: 62 | for line in logo: 63 | print(line, end='') 64 | time.sleep(0.04) 65 | print("\n") 66 | break 67 | main() 68 | -------------------------------------------------------------------------------- /payments_cc_tui.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from lib import rpclib, tuilib 4 | import os 5 | import time 6 | 7 | header = "\ 8 | _____ _ _____ _____ \n\ 9 | | _ | | | / __ \/ __ \\\n\ 10 | | | | | _ __ __ _ ___ | | ___ ___ | / \/| / \/\n\ 11 | | | | || '__| / _` | / __|| | / _ \/ __|| | | |\n\ 12 | \ \_/ /| | | (_| || (__ | || __/\__ \| \__/\| \__/\\\n\ 13 | \___/ |_| \__,_| \___||_| \___||___/ \____/ \____/\n" 14 | 15 | menuItems = [ 16 | # TODO: Have to implement here native oracle file uploader / reader, should be dope 17 | # TODO: data publisher / converter for different types 18 | {"Check current connection": tuilib.getinfo_tui}, 19 | {"Check mempool": tuilib.print_mempool}, 20 | {"Create oracle": tuilib.oracle_create_tui}, 21 | {"Register as publisher for oracle": tuilib.oracle_register_tui}, 22 | {"Subscribe on oracle (+UTXO generator)": tuilib.oracle_subscription_utxogen}, 23 | {"Upload file to oracle": tuilib.convert_file_oracle_D}, 24 | {"Display list of files uploaded to this AC": tuilib.display_files_list}, 25 | {"Download files from oracle": tuilib.files_downloader}, 26 | {"Exit": exit} 27 | ] 28 | 29 | 30 | def main(): 31 | while True: 32 | os.system('clear') 33 | print(tuilib.colorize(header, 'pink')) 34 | print(tuilib.colorize('CLI version 0.2 by Anton Lysakov\n', 'green')) 35 | for item in menuItems: 36 | print(tuilib.colorize("[" + str(menuItems.index(item)) + "] ", 'blue') + list(item.keys())[0]) 37 | choice = input(">> ") 38 | try: 39 | if int(choice) < 0: 40 | raise ValueError 41 | # Call the matching function 42 | if list(menuItems[int(choice)].keys())[0] == "Exit": 43 | list(menuItems[int(choice)].values())[0]() 44 | else: 45 | list(menuItems[int(choice)].values())[0](rpc_connection) 46 | except (ValueError, IndexError): 47 | pass 48 | 49 | 50 | if __name__ == "__main__": 51 | while True: 52 | try: 53 | print(tuilib.colorize("Welcome to the OraclesCC TUI!\n" 54 | "Please provide asset chain RPC connection details for initialization", "blue")) 55 | rpc_connection = tuilib.rpc_connection_tui() 56 | rpclib.getinfo(rpc_connection) 57 | except Exception: 58 | print(tuilib.colorize("Cant connect to RPC! Please re-check credentials.", "pink")) 59 | else: 60 | print(tuilib.colorize("Succesfully connected!\n", "green")) 61 | with (open("lib/logo.txt", "r")) as logo: 62 | for line in logo: 63 | print(line, end='') 64 | time.sleep(0.04) 65 | print("\n") 66 | break 67 | main() 68 | -------------------------------------------------------------------------------- /lib/marmara_lib.py: -------------------------------------------------------------------------------- 1 | import platform 2 | import os 3 | import re 4 | import slickrpc 5 | import shutil 6 | import time 7 | import threading 8 | import math 9 | import requests 10 | 11 | 12 | """ 13 | slickrpc.Proxy -> List 14 | returns list with marmaraactivated addresses for provided MCL daemon proxy 15 | """ 16 | 17 | 18 | def marmara_list_addresses(marmara_proxy): 19 | marmara_list_activated_addresses = marmara_proxy.marmaralistactivatedaddresses()["WalletActivatedAddresses"] 20 | marmara_addresses_list = [] 21 | for entry in marmara_list_activated_addresses: 22 | marmara_addresses_list.append(entry["activatedaddress"]) 23 | return marmara_addresses_list 24 | 25 | 26 | """ 27 | slickrpc.Proxy -> Dict 28 | Desired RPC proxy providing as first arg. finding pubkeys for provided rpc proxy wallet and return dict 29 | where keys marmaraactivated addresses and values pubkeys 30 | """ 31 | 32 | 33 | def marmara_find_pubkeys(marmara_proxy): 34 | listaddressgroupings = marmara_proxy.listaddressgroupings() 35 | pubkeys_list = [] 36 | for group in listaddressgroupings[0]: 37 | usual_address = group[0] 38 | pubkey = marmara_proxy.validateaddress(usual_address)["pubkey"] 39 | pubkeys_list.append(pubkey) 40 | marmara_addy_pub = {} 41 | for pubkey in pubkeys_list: 42 | pubkey_marmara_info = marmara_proxy.marmarainfo("0", "0", "0", "0", pubkey) 43 | marmara_addy_pub[pubkey_marmara_info["myCCActivatedAddress"]] = pubkey 44 | return marmara_addy_pub 45 | 46 | 47 | 48 | """ 49 | String -> slickrpc.Proxy 50 | creating proxy object for provided ac_name by searching for rpc credentials locally 51 | """ 52 | 53 | 54 | def def_credentials(chain, mode="usual"): 55 | rpcport = '' 56 | ac_dir = '' 57 | operating_system = platform.system() 58 | if operating_system == 'Darwin': 59 | ac_dir = os.environ['HOME'] + '/Library/Application Support/Komodo' 60 | elif operating_system == 'Linux': 61 | ac_dir = os.environ['HOME'] + '/.komodo' 62 | elif operating_system == 'Win64' or operating_system == 'Windows': 63 | ac_dir = '%s/komodo/' % os.environ['APPDATA'] 64 | if chain == 'KMD': 65 | coin_config_file = str(ac_dir + '/komodo.conf') 66 | else: 67 | coin_config_file = str(ac_dir + '/' + chain + '/' + chain + '.conf') 68 | with open(coin_config_file, 'r') as f: 69 | for line in f: 70 | l = line.rstrip() 71 | if re.search('rpcuser', l): 72 | rpcuser = l.replace('rpcuser=', '') 73 | elif re.search('rpcpassword', l): 74 | rpcpassword = l.replace('rpcpassword=', '') 75 | elif re.search('rpcport', l): 76 | rpcport = l.replace('rpcport=', '') 77 | if len(rpcport) == 0: 78 | if chain == 'KMD': 79 | rpcport = 7771 80 | else: 81 | print("rpcport not in conf file, exiting") 82 | print("check "+coin_config_file) 83 | exit(1) 84 | return slickrpc.Proxy("http://%s:%s@127.0.0.1:%d" % (rpcuser, rpcpassword, int(rpcport))) 85 | -------------------------------------------------------------------------------- /lib/logo.txt: -------------------------------------------------------------------------------- 1 | ............................... ´~»*&o££±£Xo&*»;^´ .............................. 2 | ......................... ~*±ëëëëëëëëëëëë±±££Xoo%&&Ií ........................... 3 | ..................... /£ëëëëëëëëëëëëëëëëë±±££Xo%%&IIIí .......................... 4 | ................. ,&ëëëëëëëëëëëëëëëëëëëëë±±££Xo%%&II*~ .......................... 5 | ............... =ëëëëëëëëëëëëëëëëëëë±X%&IIII%oo%%&I*' ............ ´´ ............. 6 | ............ ,XëëëëëëëëëëëëëëX», ............................. í*******?´ ......... 7 | .......... ,£ëëëëëëëëëëëë%^ ................................ ´***********~ ........ 8 | ......... %ëëëëëëëëëëë&, ................................... /************ ........ 9 | ....... íëëëëëëëëëë±í ...................................... ?***********= ........ 10 | ...... &ëëëëëëëëë±~ ....................................... ^************, ........ 11 | ..... Xëëëëëëëëë» ........................................'**********=~ .......... 12 | ... ´£ëëëëëëëë£, ........................................ »****/' ................. 13 | ... Xëëëëëëëë% ....................................... ^=***/ ..................... 14 | .. Iëëëëëëëë& ..................... ~*o%%%%%&&&&I==*I*****?´ ...................... 15 | . íëëëëëëëëo ................... íoXXoooo%%%%%&&&&IIIII**» ................ '*IIII;. 16 | . Xëëëëëëëë, ................. ;££XXXXXoooo%%%%%&&&&IIIII´ ............... íII&&&&&= 17 | ~ëëëëëëëë= ................. &±££££XXXXXoooo%%%%%&&&&II= ................ /%%%%%%%% 18 | *ëëëëëëëë, ................ &±±±±££££XXXXXoooo%%%%%&&&&* ................ ,oooooooX 19 | oëëëëëëëX ................ /ëë±±±±±££££XXXXXoooo%%%%%&&&~ ................ %£££££££ 20 | ±ëëëëëëëI ................ %ëëëë±±±±±££££XXXXXoooo%%%%%&? ................ I±±±±±±± 21 | ±ëëëëëëëI ................ X@ëëëëë±±±±±££££XXXXXoooo%%%%= ................ Iëëëëëëë 22 | £ëëëëëëë% ................ I@@@@ëëëë±±±±±££££XXXXXoooo%%/ ................ %ëëëëëëë 23 | &ëëëëëëë± ................ '@@@@@@ëëëë±±±±±££££XXXXXooo%´ ................ ëëëëëëëë 24 | »ëëëëëëëëí ................ ;@@@@@@@ëëëë±±±±±££££XXXXXo^ ................ ;ëëëëëëëë 25 | ´ëëëëëëëëo ................. ^ë@@@@@@ëëëëë±±±±±££££XXo, ................. Xëëëëëëëë 26 | . *ëëëëëëëë» .................. »@@@@@@@@ëëëë±±±±±£££; .................. »ëëëëëëëë= 27 | . ´±ëëëëëëëë~ ................... ^o@@@@@@@ëëëë±±±&' ................... ~ëëëëëëëë± . 28 | .. ~ëëëëëëëëë^ ...................... ,/*%oo&=;, ...................... ^ëëëëëëëëë^ . 29 | ... /ëëëëëëëëë; .................................................... ;ëëëëëëëëë/ .. 30 | .... »ëëëëëëëëë& .................................................. &ëëëëëëëëë/ ... 31 | ..... íëëëëëëëëëëí .............................................. íëëëëëëëëëëí .... 32 | ...... ,±ëëëëëëëëë±~ .......................................... ~±ëëëëëëëëë£, ..... 33 | ........ =ëëëëëëëëëëë» ...................................... ?ëëëëëëëëëëë= ....... 34 | ......... ´Xëëëëëëëëëëë£; ................................ ;±ëëëëëëëëëëëo´ ........ 35 | ........... '£ëëëëëëëëëëëëë&~ ........................ ~&ëëëëëëëëëëëëëX, .......... 36 | ............. ´%ëëëëëëëëëëëëëëëëo=í' .......... ';=oëëëëëëëëëëëëëëëë&´ ............ 37 | ................ í±ëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëë£í ............... 38 | ................... íXëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëXí .................. 39 | ...................... ´/XëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëX/´ ..................... 40 | ........................... ´í=Xëëëëëëëëëëëëëëëëëëo=~ ........................... 41 | ............................... ´~»*&o££±£Xo&*»;^´ .............................. -------------------------------------------------------------------------------- /scripts/kmd_1of1gw_creation.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from lib import tuilib 4 | import time 5 | import subprocess 6 | 7 | ac_name = "GWTEST5" 8 | start_time = time.time() 9 | 10 | # proxies for ac_name assetchain and KMD daemon (both should be up)\ 11 | rpc_connection_ac = tuilib.def_credentials(ac_name) 12 | rpc_connection_kmd = tuilib.def_credentials("KMD") 13 | 14 | print(tuilib.colorize("\nSetting up 1of1 test GW for KMD. Please be patient - it can take some time.\n", "green")) 15 | 16 | # creating token 17 | token_hex = rpc_connection_ac.tokencreate("KMD", "1", "Test")["hex"] 18 | token_txid = rpc_connection_ac.sendrawtransaction(token_hex) 19 | 20 | # create oracle 21 | oracle_hex = rpc_connection_ac.oraclescreate("KMD", "Test", "Ihh")["hex"] 22 | oracle_txid = rpc_connection_ac.sendrawtransaction(oracle_hex) 23 | 24 | # register as publisher with 10000 sat datafee 25 | register_hex = rpc_connection_ac.oraclesregister(oracle_txid, "10000")["hex"] 26 | register_txid = rpc_connection_ac.sendrawtransaction(register_hex) 27 | 28 | # waiting until registration transaction is mined 29 | tuilib.check_if_tx_in_mempool(rpc_connection_ac, register_txid) 30 | 31 | # subscribing on this publisher utxo_num times 32 | utxo_num = 10 33 | while utxo_num > 0: 34 | publisher_id = rpc_connection_ac.getinfo()["pubkey"] 35 | while True: 36 | oracle_subscription_hex = rpc_connection_ac.oraclessubscribe(oracle_txid, publisher_id, "0.1")["hex"] 37 | oracle_subscription_txid = rpc_connection_ac.sendrawtransaction(oracle_subscription_hex) 38 | mempool = rpc_connection_ac.getrawmempool() 39 | if oracle_subscription_txid in mempool: 40 | break 41 | else: 42 | pass 43 | print(tuilib.colorize("Oracle subscription transaction broadcasted: " + oracle_subscription_txid, "green")) 44 | utxo_num = utxo_num - 1 45 | 46 | # bind gateway 47 | pubkey = rpc_connection_ac.getinfo()["pubkey"] 48 | gateways_bind_hex = rpc_connection_ac.gatewaysbind(token_txid, oracle_txid, "KMD", "100000000", "1", "1", pubkey, "60", "85", "188")["hex"] 49 | gateways_bind_txid = rpc_connection_ac.sendrawtransaction(gateways_bind_hex) 50 | 51 | tuilib.check_if_tx_in_mempool(rpc_connection_ac, gateways_bind_txid) 52 | 53 | # export privkey for gateways deposit address from AC to KMD daemon 54 | deposit_address = rpc_connection_ac.gatewaysinfo(gateways_bind_txid)["deposit"] 55 | deposit_address_privkey = rpc_connection_ac.dumpprivkey(deposit_address) 56 | 57 | # ERROR HANDLING LOOP FOR KMD IF LOADING/REWINDING BLOCKS 58 | output ='' 59 | while len(output) != 30: 60 | try: 61 | output = rpc_connection_kmd.getinfo() 62 | except Exception as e: 63 | print(e) 64 | print('waiting for KMD RPC') 65 | pass 66 | time.sleep(15) 67 | 68 | rpc_connection_kmd.importprivkey(deposit_address_privkey) 69 | 70 | # save all params to file 71 | timestamp = str(int(time.time())) 72 | file_name = "gateway_binded_at_" + timestamp + ".txt" 73 | with open(file_name, "w+") as file: 74 | file.writelines("Bind txid: " + gateways_bind_txid) 75 | file.writelines("Token txid: " + token_txid) 76 | file.writelines("Oracle txid: " + oracle_txid) 77 | 78 | print(tuilib.colorize("Gateway succesfully binded! Information saved to file: " + file_name, "green")) 79 | print("--- %s seconds ---" % (time.time() - start_time)) 80 | 81 | # start oraclefeed for this gateway 82 | subprocess.call(["./oraclefeed", ac_name, oracle_txid, pubkey, "Ihh", gateways_bind_txid]) 83 | -------------------------------------------------------------------------------- /scripts/dexp2p/clients_spawn.py: -------------------------------------------------------------------------------- 1 | import os 2 | import time 3 | import sys 4 | import subprocess 5 | from slickrpc import Proxy, exc 6 | import random 7 | 8 | # init params, nodes amount can't be < than 5 9 | dexp2p_clients_to_start = int(os.getenv('NODESAMOUNT')) 10 | ac_name = 'DEXTEST' 11 | node_ip = '127.0.0.1' 12 | 13 | # pre-creating separate folders 14 | for i in range(dexp2p_clients_to_start): 15 | os.mkdir("node_" + str(i)) 16 | open("node_" + str(i) + "/" + ac_name + ".conf", 'a').close() 17 | with open("node_" + str(i) + "/" + ac_name + ".conf", 'a') as conf: 18 | conf.write("rpcuser=test" + '\n') 19 | conf.write("rpcpassword=test" + '\n') 20 | conf.write("rpcport=" + str(7000 + i) + '\n') 21 | conf.write("port=" + str(6000 + i) + '\n') 22 | 23 | # start numnodes daemons, changing folder name and port 24 | for i in range(dexp2p_clients_to_start): 25 | # first node doesn't connect to any node 26 | if i == 0: 27 | subprocess.call(['./komodod', '-ac_name=' + ac_name, 28 | '-conf=' + sys.path[0] + '/node_' + str(i) + "/" + ac_name + ".conf", 29 | '-rpcport=' + str(7000 + i), '-datadir=' + sys.path[0] + '/node_' + str(i), 30 | '-ac_supply=10000000000', '-dexp2p=2', '-whitelist=127.0.0.1', '-daemon']) 31 | time.sleep(5) 32 | # let's connect first few nodes to the seed node to surely have a network 33 | elif i < 4: 34 | subprocess.call(['./komodod', '-ac_name=' + ac_name, 35 | '-conf=' + sys.path[0] + '/node_' + str(i) + "/" + ac_name + ".conf", 36 | '-rpcport=' + str(7000 + i), '-datadir=' + sys.path[0] + '/node_' + str(i), 37 | '-ac_supply=10000000000', '-dexp2p=2', '-addnode=127.0.0.1:6000', '-whitelist=127.0.0.1', '-daemon']) 38 | time.sleep(5) 39 | else: 40 | # choosing 4 random pre-determined already started nodes ports to connect 41 | nodes_ports_to_connect = [] 42 | for j in range(4): 43 | node_port = random.randint(6000, 6000 + i - 1) 44 | while True: 45 | # to not connect to the same node twice 46 | if node_port in nodes_ports_to_connect: 47 | node_port = random.randint(6000, 6001 + dexp2p_clients_to_start - 1) 48 | else: 49 | nodes_ports_to_connect.append(node_port) 50 | break 51 | daemon_args = ['./komodod', '-ac_name=' + ac_name, 52 | '-conf=' + sys.path[0] + '/node_' + str(i) + "/" + ac_name + ".conf", 53 | '-rpcport=' + str(7000 + i), '-datadir=' + sys.path[0] + '/node_' + str(i), 54 | '-ac_supply=10000000000', '-dexp2p=2', '-whitelist=127.0.0.1', '-daemon'] 55 | for node_port in nodes_ports_to_connect: 56 | daemon_args.append("-addnode=" + node_ip + ":" + str(node_port)) 57 | subprocess.call(daemon_args) 58 | time.sleep(5) 59 | 60 | # creating rpc proxies for all nodes 61 | for i in range(dexp2p_clients_to_start): 62 | rpcport = 7000 + i 63 | globals()['proxy_%s' % i] = Proxy("http://%s:%s@127.0.0.1:%d" % ("test", "test", int(rpcport))) 64 | try: 65 | dex_stats_output = globals()['proxy_%s' % i].DEX_stats() 66 | print(dex_stats_output) 67 | except Exception as e: 68 | print(e) 69 | 70 | # since connection ports were chosen randomly let's try to interconnect orphan nodes 71 | for i in range(dexp2p_clients_to_start): 72 | connections_amount = globals()['proxy_%s' % i].getinfo()["connections"] 73 | print(connections_amount) 74 | 75 | print("All nodes started (hopefully) - you can proceed to loading test") 76 | -------------------------------------------------------------------------------- /tetris_tui.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from lib import rpclib, tuilib 4 | import os 5 | import time 6 | import sys 7 | import platform 8 | 9 | header = "\ 10 | _____ _ _ ______\n\ 11 | |_ _| | | (_) | _ \n\ 12 | | | ___| |_ _ __ _ ___| | | |__ _ _ __ _ __\n\ 13 | | |/ _ \ __| '__| / __| | | / _` | '_ \| '_ \\\n\ 14 | | | __/ |_| | | \__ \ |/ / (_| | |_) | |_) |\n\ 15 | \_/\___|\__|_| |_|___/___/ \__,_| .__/| .__/\n\ 16 | | | | |\n\ 17 | |_| |_|" 18 | 19 | 20 | menuItems = [ 21 | {"Check current connection": tuilib.getinfo_tui}, 22 | {"Check mempool": tuilib.print_mempool}, 23 | {"Start singleplayer tetris game (creating, registering and starting game)": tuilib.rogue_newgame_singleplayer}, 24 | {"Exit": tuilib.exit} 25 | ] 26 | 27 | 28 | def main(): 29 | while True: 30 | operating_system = platform.system() 31 | if operating_system != 'Win64' and operating_system != 'Windows': 32 | os.system('clear') 33 | else: 34 | os.system('cls') 35 | print(tuilib.colorize(header, 'pink')) 36 | print(tuilib.colorize('TUI v0.0.3\n', 'green')) 37 | menu_items_counter = 0 38 | for item in menuItems: 39 | print(tuilib.colorize("[" + str(menuItems.index(item)) + "] ", 'blue') + list(item.keys())[0]) 40 | choice = input(">> ") 41 | try: 42 | if int(choice) < 0: 43 | raise ValueError 44 | # Call the matching function 45 | if list(menuItems[int(choice)].keys())[0] == "Exit": 46 | list(menuItems[int(choice)].values())[0]() 47 | elif list(menuItems[int(choice)].keys())[0] == "Start singleplayer tetris game (creating, registering and starting game)": 48 | list(menuItems[int(choice)].values())[0](rpc_connection, False) 49 | else: 50 | list(menuItems[int(choice)].values())[0](rpc_connection) 51 | except (ValueError, IndexError): 52 | pass 53 | 54 | 55 | if __name__ == "__main__": 56 | while True: 57 | chain = "GTEST" 58 | try: 59 | print(tuilib.colorize("Welcome to the Tetris TUI!\n" 60 | "Please provide asset chain RPC connection details for initialization", "blue")) 61 | rpc_connection = tuilib.def_credentials(chain) 62 | rpclib.getinfo(rpc_connection) 63 | # waiting until chain is in sync 64 | while True: 65 | have_blocks = rpclib.getinfo(rpc_connection)["blocks"] 66 | longest_chain = rpclib.getinfo(rpc_connection)["longestchain"] 67 | if have_blocks != longest_chain: 68 | print(tuilib.colorize("GTEST not synced yet.", "red")) 69 | print("Have " + str(have_blocks) + " from " + str(longest_chain) + " blocks") 70 | time.sleep(5) 71 | else: 72 | print(tuilib.colorize("Chain is synced!", "green")) 73 | break 74 | # checking if pubkey is set and set valid if not 75 | info = rpclib.getinfo(rpc_connection) 76 | if "pubkey" in info.keys(): 77 | print("Pubkey is already set") 78 | else: 79 | valid_address = rpc_connection.getaccountaddress("") 80 | valid_pubkey = rpc_connection.validateaddress(valid_address)["pubkey"] 81 | rpc_connection.setpubkey(valid_pubkey) 82 | print(tuilib.colorize("Pubkey is succesfully set!", "green")) 83 | # copy ROGUE config to current daemon directory if it's not here 84 | tuilib.check_if_config_is_here(rpc_connection, "GTEST") 85 | except Exception: 86 | print(tuilib.colorize("Cant connect to GTEST daemon RPC! Please check if daemon is up.", "pink")) 87 | tuilib.exit() 88 | else: 89 | print(tuilib.colorize("Succesfully connected!\n", "green")) 90 | with (open("lib/logo.txt", "r")) as logo: 91 | for line in logo: 92 | print(line, end='') 93 | time.sleep(0.04) 94 | print("\n") 95 | break 96 | main() 97 | -------------------------------------------------------------------------------- /lib/atomicdex_stats_lib.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | 4 | error_events = [ 5 | "StartFailed", 6 | "NegotiateFailed", 7 | "TakerFeeValidateFailed", 8 | "MakerPaymentTransactionFailed", 9 | "MakerPaymentDataSendFailed", 10 | "TakerPaymentValidateFailed", 11 | "TakerPaymentSpendFailed", 12 | "MakerPaymentRefunded", 13 | "MakerPaymentRefundFailed" 14 | ] 15 | 16 | # assuming start from DB/%NODE_PUBKEY%/SWAPS/STATS/ directory 17 | 18 | files_list_tmp = os.listdir("MAKER") 19 | files_list = [] 20 | for file in files_list_tmp: 21 | if file[-5:] == '.json': 22 | files_list.append(file) 23 | 24 | files_content = {} 25 | 26 | # loading files content into files_content dict 27 | for file in files_list: 28 | try: 29 | with open('MAKER/'+file) as json_file: 30 | swap_uuid = file[:-5] 31 | data = json.load(json_file) 32 | files_content[swap_uuid] = data 33 | except Exception as e: 34 | print(e) 35 | print("Broken: " + file) 36 | 37 | # filter swaps data for speciifc pair 38 | def pair_filter(data_to_filter, maker_coin, taker_coin): 39 | swaps_of_pair = {} 40 | for swap_data in data_to_filter.values(): 41 | try: 42 | if swap_data["events"][0]["event"]["data"]["taker_coin"] == taker_coin and swap_data["events"][0]["event"]["data"]["maker_coin"] == maker_coin: 43 | swaps_of_pair[swap_data["events"][0]["event"]["data"]["uuid"]] = swap_data 44 | except Exception: 45 | pass 46 | return swaps_of_pair 47 | 48 | # filter for time period 49 | def time_filter(data_to_filter, start_time_stamp, end_time_stamp): 50 | swaps_for_dates = {} 51 | for swap_data in data_to_filter.values(): 52 | try: 53 | if swap_data["events"][0]["timestamp"] >= start_time_stamp and swap_data["events"][0]["timestamp"] <= end_time_stamp: 54 | swaps_for_dates[swap_data["events"][0]["event"]["data"]["uuid"]] = swap_data 55 | except Exception as e: 56 | pass 57 | return swaps_for_dates 58 | 59 | 60 | # checking if swap succesfull 61 | def count_successful_swaps(swaps_data): 62 | successful_swaps_counter = 0 63 | failed_swaps_counter = 0 64 | for swap_data in swaps_data.values(): 65 | for event in swap_data["events"]: 66 | if event["event"]["type"] in error_events: 67 | failed_swaps_counter += 1 68 | else: 69 | successful_swaps_counter += 1 70 | return (failed_swaps_counter, successful_swaps_counter) 71 | 72 | # calculate volumes 73 | # TODO: ETH/ERC volumes seems not possible to calculate this way 74 | def calculate_trades_volumes(swaps_data): 75 | maker_coin_volume = 0 76 | taker_coin_volume = 0 77 | for swap_data in swaps_data.values(): 78 | for event in swap_data["events"]: 79 | if event["event"]["type"] == "MakerPaymentSent": 80 | maker_coin_volume += abs(event["event"]["data"]["my_balance_change"]) 81 | elif event["event"]["type"] == "TakerPaymentSpent": 82 | taker_coin_volume += abs(event["event"]["data"]["my_balance_change"]) 83 | return (maker_coin_volume, taker_coin_volume) 84 | 85 | # TODO: just examples of methods usage, have to make simple interface or take params from cli and generate report 86 | 87 | count_for_aug = count_successful_swaps(time_filter(files_content, 1564617600000, 1566583283000)) 88 | count_for_jul = count_successful_swaps(time_filter(files_content, 1561939200000, 1564531200000)) 89 | 90 | count_for_rick_morty = count_successful_swaps(pair_filter(files_content, "RICK", "MORTY")) 91 | 92 | print("Total successful swaps in Aug: " + str(count_for_aug[1])) 93 | print("Total failed swaps in Aug: " + str(count_for_aug[0])) 94 | print("Fails ratio (%): " + (str(count_for_aug[0]*100/count_for_aug[1]))) 95 | 96 | print("Total successful swaps in Jul: " + str(count_for_jul[1])) 97 | print("Total failed swaps in Jul: " + str(count_for_jul[0])) 98 | print("Fails ratio (%): " + (str(count_for_jul[0]*100/count_for_jul[1]))) 99 | 100 | print("Total successful RICK/MORTY swaps: " + str(count_for_rick_morty[1])) 101 | print("Total failed RICK/MORTY swaps: " + str(count_for_rick_morty[0])) 102 | -------------------------------------------------------------------------------- /pegs_usage_tui.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from lib import rpclib, tuilib 4 | import os, time 5 | 6 | header = "\ 7 | ______ _____ _____ \n\ 8 | | ___ \ / __ \/ __ \\\n\ 9 | | |_/ /___ _____ ___| / \/| / \/\n\ 10 | | __// _ \| _ |/ __| | | | \n\ 11 | | | | __/| |_| |\__ \ \__/\| \__/\\\n\ 12 | \_| \___|\___ |/___/\____/ \____/\n\ 13 | __/ | \n\ 14 | |___/ \n" 15 | 16 | 17 | 18 | 19 | menuItems = [ 20 | {"Pegs Module Readme": tuilib.readme_tui}, 21 | {"Check connection to assetchain": tuilib.getinfo_tui}, 22 | {"Check assetchain mempool": tuilib.print_mempool}, 23 | {"Check connection to KMD": tuilib.getinfo_tui}, 24 | {"Connect to KMD daemon": tuilib.rpc_kmd_connection_tui}, 25 | {"View assetchain Gateway Info": tuilib.gateway_info_tui}, 26 | {"Deposit KMD in Gateway and claim Tokens": tuilib.gateways_deposit_claim_tokens}, 27 | {"Execute Pegs funding": tuilib.pegs_fund_tui}, 28 | {"Execute Pegs get": tuilib.pegs_get_tui}, 29 | {"Check Pegs info": tuilib.pegsinfo_tui}, 30 | {"Check Pegs account history": tuilib.pegs_accounthistory_tui}, 31 | {"Check Pegs account info": tuilib.pegs_accountinfo_tui}, 32 | {"Check Pegs addresses": tuilib.pegs_addresses_tui}, 33 | {"Check Pegs worst accounts": tuilib.pegs_worstaccounts_tui}, 34 | {"Exit": exit} 35 | ] 36 | 37 | def main(): 38 | while True: 39 | os.system('clear') 40 | print(tuilib.colorize(header, 'pink')) 41 | print(tuilib.colorize('CLI version 0.1 by Thor Mennet\n', 'green')) 42 | for item in menuItems: 43 | print(tuilib.colorize("[" + str(menuItems.index(item)) + "] ", 'blue') + list(item.keys())[0]) 44 | choice = input(">> ") 45 | try: 46 | if int(choice) < 0: 47 | raise ValueError 48 | # Call the matching function 49 | if list(menuItems[int(choice)].keys())[0] == "Exit": 50 | list(menuItems[int(choice)].values())[0]() 51 | elif list(menuItems[int(choice)].keys())[0] == "Pegs Module Readme": 52 | list(menuItems[int(choice)].values())[0]('docs/pegs_module.md') 53 | # We have to call KMD specific functions with connection to KMD daemon 54 | elif list(menuItems[int(choice)].keys())[0] == "Connect to KMD daemon": 55 | rpc_connection_kmd = list(menuItems[int(choice)].values())[0]() 56 | elif list(menuItems[int(choice)].keys())[0] == "Check connection to KMD": 57 | while True: 58 | try: 59 | list(menuItems[int(choice)].values())[0](rpc_connection_kmd) 60 | break 61 | except Exception as e: 62 | print("Please connect to KMD daemon first!") 63 | input("Press [Enter] to continue...") 64 | break 65 | elif list(menuItems[int(choice)].keys())[0] == "Deposit KMD in Gateway and claim Tokens": 66 | while True: 67 | try: 68 | list(menuItems[int(choice)].values())[0](rpc_connection, rpc_connection_kmd) 69 | break 70 | except Exception as e: 71 | print(e) 72 | print("Please connect to KMD daemon first!") 73 | input("Press [Enter] to continue...") 74 | break 75 | else: 76 | list(menuItems[int(choice)].values())[0](rpc_connection) 77 | except (ValueError, IndexError): 78 | pass 79 | 80 | 81 | if __name__ == "__main__": 82 | while True: 83 | try: 84 | print(tuilib.colorize("Welcome to the GatewaysCC TUI!\nPlease provide RPC connection details for initialization", "blue")) 85 | rpc_connection = tuilib.rpc_connection_tui() 86 | rpclib.getinfo(rpc_connection) 87 | except Exception: 88 | print(tuilib.colorize("Cant connect to RPC! Please re-check credentials.", "pink")) 89 | else: 90 | print(tuilib.colorize("Succesfully connected!\n", "green")) 91 | with (open("lib/logo.txt", "r")) as logo: 92 | for line in logo: 93 | print(line, end='') 94 | time.sleep(0.04) 95 | print("\n") 96 | break 97 | main() 98 | -------------------------------------------------------------------------------- /gateways_usage_tui.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from lib import rpclib, tuilib 4 | import os, time 5 | 6 | header = "\ 7 | _____ _ _____ _____ \n\ 8 | | __ \ | | / __ \/ __ \\\n\ 9 | | | \/ __ _| |_ _____ ____ _ _ _ ___| / \/| / \/\n\ 10 | | | __ / _` | __/ _ \ \ /\ / / _` | | | / __| | | | \n\ 11 | | |_\ \ (_| | || __/\ V V / (_| | |_| \__ \ \__/\| \__/\\\n\ 12 | \____/\__,_|\__\___| \_/\_/ \__,_|\__, |___/\____/ \____/\n\ 13 | __/ | \n\ 14 | |___/ \n" 15 | 16 | menuItems = [ 17 | {"Check connection to assetchain": tuilib.getinfo_tui}, 18 | {"Check assetchain mempool": tuilib.print_mempool}, 19 | {"Check connection to KMD": tuilib.getinfo_tui}, 20 | {"Connect to KMD daemon": tuilib.rpc_kmd_connection_tui}, 21 | {"View assetchain Gateway Info": tuilib.gateway_info_tui}, 22 | {"Send KMD gateway deposit transaction": tuilib.gateways_send_kmd}, 23 | {"Execute gateways deposit": tuilib.gateways_deposit_tui}, 24 | {"Execute gateways claim": tuilib.gateways_claim_tui}, 25 | {"Execute gateways withdrawal": tuilib.gateways_withdrawal_tui}, 26 | {"Exit": exit} 27 | ] 28 | 29 | def main(): 30 | while True: 31 | os.system('clear') 32 | print(tuilib.colorize(header, 'pink')) 33 | print(tuilib.colorize('CLI version 0.2\n', 'green')) 34 | for item in menuItems: 35 | print(tuilib.colorize("[" + str(menuItems.index(item)) + "] ", 'blue') + list(item.keys())[0]) 36 | choice = input(">> ") 37 | try: 38 | if int(choice) < 0: 39 | raise ValueError 40 | # Call the matching function 41 | if list(menuItems[int(choice)].keys())[0] == "Exit": 42 | list(menuItems[int(choice)].values())[0]() 43 | # We have to call KMD specific functions with connection to KMD daemon 44 | elif list(menuItems[int(choice)].keys())[0] == "Connect to KMD daemon": 45 | rpc_connection_kmd = list(menuItems[int(choice)].values())[0]() 46 | elif list(menuItems[int(choice)].keys())[0] == "Check connection to KMD": 47 | while True: 48 | try: 49 | list(menuItems[int(choice)].values())[0](rpc_connection_kmd) 50 | break 51 | except Exception as e: 52 | print("Please connect to KMD daemon first!") 53 | input("Press [Enter] to continue...") 54 | break 55 | elif list(menuItems[int(choice)].keys())[0] == "Send KMD gateway deposit transaction": 56 | while True: 57 | try: 58 | list(menuItems[int(choice)].values())[0](rpc_connection_kmd) 59 | break 60 | except Exception as e: 61 | print(e) 62 | print("Please connect to KMD daemon first!") 63 | input("Press [Enter] to continue...") 64 | break 65 | elif list(menuItems[int(choice)].keys())[0] == "Execute gateways deposit": 66 | while True: 67 | try: 68 | list(menuItems[int(choice)].values())[0](rpc_connection, rpc_connection_kmd) 69 | break 70 | except Exception as e: 71 | print(e) 72 | print("Please connect to KMD daemon first!") 73 | input("Press [Enter] to continue...") 74 | break 75 | else: 76 | list(menuItems[int(choice)].values())[0](rpc_connection) 77 | except (ValueError, IndexError): 78 | pass 79 | 80 | 81 | if __name__ == "__main__": 82 | while True: 83 | try: 84 | print(tuilib.colorize("Welcome to the GatewaysCC TUI!\nPlease provide RPC connection details for initialization", "blue")) 85 | rpc_connection = tuilib.rpc_connection_tui() 86 | rpclib.getinfo(rpc_connection) 87 | except Exception: 88 | print(tuilib.colorize("Cant connect to RPC! Please re-check credentials.", "pink")) 89 | else: 90 | print(tuilib.colorize("Succesfully connected!\n", "green")) 91 | with (open("lib/logo.txt", "r")) as logo: 92 | for line in logo: 93 | print(line, end='') 94 | time.sleep(0.04) 95 | print("\n") 96 | break 97 | main() 98 | -------------------------------------------------------------------------------- /scripts/dexp2p/multi-server/clients_spawn_multi_server.py: -------------------------------------------------------------------------------- 1 | import os 2 | import time 3 | import sys 4 | import subprocess 5 | from slickrpc import Proxy, exc 6 | import random 7 | 8 | # init params, nodes amount can't be < than 5 9 | dexp2p_clients_to_start = int(os.getenv('NODESAMOUNT')) 10 | ac_name = 'DEXTEST' 11 | node_ip = os.getenv('NODE_IP') 12 | is_first_server = os.getenv('IS_FIRST') 13 | ips_of_running_servers = [] 14 | with open("ip_list", "r") as f: 15 | for line in f: 16 | ips_of_running_servers.append(line.rstrip('\n')) 17 | 18 | # pre-creating separate folders 19 | for i in range(dexp2p_clients_to_start): 20 | os.mkdir("node_" + str(i)) 21 | open("node_" + str(i) + "/" + ac_name + ".conf", 'a').close() 22 | with open("node_" + str(i) + "/" + ac_name + ".conf", 'a') as conf: 23 | conf.write("rpcuser=test" + '\n') 24 | conf.write("rpcpassword=test" + '\n') 25 | conf.write("rpcport=" + str(7000 + i) + '\n') 26 | conf.write("port=" + str(6000 + i) + '\n') 27 | 28 | # start numnodes daemons, changing folder name and port 29 | for i in range(dexp2p_clients_to_start): 30 | # first server setup - first node shouldn't have any addnode, all other clients we caonnect to the firstnode 31 | if is_first_server == "True": 32 | if i == 0: 33 | subprocess.call(['./komodod', '-ac_name=' + ac_name, 34 | '-conf=' + sys.path[0] + '/node_' + str(i) + "/" + ac_name + ".conf", 35 | '-rpcport=' + str(7000 + i), '-datadir=' + sys.path[0] + '/node_' + str(i), 36 | '-ac_supply=10000000000', '-dexp2p=2', '-whitelist=127.0.0.1', '-daemon']) 37 | time.sleep(3) 38 | # let's connect first few nodes to the seed node to surely have a network 39 | else: 40 | subprocess.call(['./komodod', '-ac_name=' + ac_name, 41 | '-conf=' + sys.path[0] + '/node_' + str(i) + "/" + ac_name + ".conf", 42 | '-rpcport=' + str(7000 + i), '-datadir=' + sys.path[0] + '/node_' + str(i), 43 | '-ac_supply=10000000000', '-dexp2p=2', '-addnode=127.0.0.1:6000', '-whitelist=127.0.0.1', '-daemon']) 44 | time.sleep(3) 45 | # not first server nodes connecting to the random nodes of already started server(s) 46 | else: 47 | daemon_args = ['./komodod', '-ac_name=' + ac_name, 48 | '-conf=' + sys.path[0] + '/node_' + str(i) + "/" + ac_name + ".conf", 49 | '-rpcport=' + str(7000 + i), '-datadir=' + sys.path[0] + '/node_' + str(i), 50 | '-ac_supply=10000000000', '-dexp2p=2', '-whitelist=127.0.0.1', '-daemon'] 51 | already_choosen_ports = [] 52 | if dexp2p_clients_to_start > 4: 53 | # choosing 4 random pre-determined already started nodes ports to connect 54 | for j in range(4): 55 | connect_ip = random.choice(ips_of_running_servers) 56 | connect_port = random.randint(6000, 6000 + dexp2p_clients_to_start - 1) 57 | while True: 58 | # to not connect to the same node twice 59 | if connect_port in already_choosen_ports: 60 | connect_port = random.randint(6000, 6000 + dexp2p_clients_to_start - 1) 61 | else: 62 | already_choosen_ports.append(connect_port) 63 | break 64 | daemon_args.append("-addnode=" + connect_ip + ":" + str(connect_port)) 65 | # 1 node per server mode POC 66 | else: 67 | if len(ips_of_running_servers) < 3: 68 | daemon_args.append("-addnode=" + ips_of_running_servers[0] + ":6000") 69 | else: 70 | already_choosen_ips = [] 71 | for j in range(3): 72 | connect_ip = random.choice(ips_of_running_servers) 73 | if connect_ip in already_choosen_ips: 74 | connect_ip = random.choice(ips_of_running_servers) 75 | else: 76 | already_choosen_ips.append(connect_ip) 77 | for ip in already_choosen_ips: 78 | daemon_args.append("-addnode=" + ip + ":6000") 79 | subprocess.call(daemon_args) 80 | time.sleep(3) 81 | 82 | # creating rpc proxies for all nodes 83 | for i in range(dexp2p_clients_to_start): 84 | rpcport = 7000 + i 85 | globals()['proxy_%s' % i] = Proxy("http://%s:%s@127.0.0.1:%d" % ("test", "test", int(rpcport))) 86 | try: 87 | dex_stats_output = globals()['proxy_%s' % i].DEX_stats() 88 | print(dex_stats_output) 89 | except Exception as e: 90 | print(e) 91 | 92 | # since connection ports were chosen randomly let's try to interconnect orphan nodes 93 | for i in range(dexp2p_clients_to_start): 94 | connections_amount = globals()['proxy_%s' % i].getinfo()["connections"] 95 | print(connections_amount) 96 | 97 | print("All nodes started (hopefully) - you can proceed to loading test") 98 | -------------------------------------------------------------------------------- /scripts/crosschain_migrations.py: -------------------------------------------------------------------------------- 1 | from slickrpc import Proxy 2 | import time 3 | import sys 4 | import datetime 5 | 6 | 7 | def wait_for_confirmation(rpc_connection, tx_id, confirmations_amount_goal): 8 | confirmations_amount = 0 9 | while confirmations_amount < confirmations_amount_goal: 10 | time.sleep(15) 11 | confirmations_amount = int(rpc_connection.gettransaction(tx_id)["confirmations"]) 12 | print("Have " + str(confirmations_amount) + " confirmations") 13 | print("Waiting for more confirmations: " + str(confirmations_amount_goal)) 14 | print("Transaction confirmed!\n") 15 | 16 | 17 | def print_balance(rpc_connection_source, rpc_connection_destination): 18 | balance_source = rpc_connection_source.getbalance() 19 | balance_destination = rpc_connection_destination.getbalance() 20 | source_chain_name = rpc_connection_source.getinfo()["name"] 21 | destination_chain_name = rpc_connection_destination.getinfo()["name"] 22 | print("Source chain " + source_chain_name + " balance: " + str(balance_source)) 23 | print("Destination chain " + destination_chain_name + " balance: " + str(balance_destination)) 24 | 25 | 26 | # SET RPC CONNECTION DETAILS HERE 27 | rpc_connection_sourcechain = Proxy("http://%s:%s@127.0.0.1:%d"%("user", "pass", 30667)) 28 | rpc_connection_destinationchain = Proxy("http://%s:%s@127.0.0.1:%d"%("user", "pass", 50609)) 29 | rpc_connection_kmdblockchain = Proxy("http://%s:%s@127.0.0.1:%d"%("user", "pass", 7771)) 30 | # SET ADDRESS AND MIGRATION AMOUNT HERE 31 | address = "RHq3JsvLxU45Z8ufYS6RsDpSG4wi6ucDev" 32 | amount = 0.1 33 | 34 | t0 = time.time() 35 | 36 | print_balance(rpc_connection_sourcechain, rpc_connection_destinationchain) 37 | 38 | print("Sending " + str(amount) + " coins from " + rpc_connection_sourcechain.getinfo()["name"] + " chain " +\ 39 | "to " + rpc_connection_destinationchain.getinfo()["name"] + " chain") 40 | 41 | # Creating rawtransaction 42 | raw_transaction = rpc_connection_sourcechain.createrawtransaction([], {address: amount}) 43 | export_data = rpc_connection_sourcechain.migrate_converttoexport(raw_transaction, rpc_connection_destinationchain.getinfo()["name"]) 44 | export_raw = export_data["exportTx"] 45 | 46 | # Fund it 47 | export_funded_data = rpc_connection_sourcechain.fundrawtransaction(export_raw) 48 | export_funded_transaction = export_funded_data["hex"] 49 | payouts = export_data["payouts"] 50 | 51 | # Sign rawtx and export 52 | signed_hex = rpc_connection_sourcechain.signrawtransaction(export_funded_transaction) 53 | sent_tx = rpc_connection_sourcechain.sendrawtransaction(signed_hex["hex"]) 54 | 55 | # Check if export transaction was created successfully 56 | if len(sent_tx) != 64: 57 | print(signed_hex) 58 | print(sent_tx) 59 | print("Export TX not successfully created") 60 | sys.exit() 61 | 62 | # Wait for a confirmation on source chain 63 | wait_for_confirmation(rpc_connection_sourcechain, sent_tx, 3) 64 | print(rpc_connection_sourcechain.getinfo()["name"] + " : Confirmed export " + str(sent_tx)) 65 | 66 | # Use migrate_createimporttransaction to create the import TX 67 | while True: 68 | # ? 69 | time.sleep(60) 70 | try: 71 | import_tx = rpc_connection_sourcechain.migrate_createimporttransaction(signed_hex["hex"], payouts) 72 | except Exception as e: 73 | print(e) 74 | print("Import transaction not created yet, waiting for 60 seconds more") 75 | pass 76 | else: 77 | print("Seems tx created") 78 | break 79 | 80 | # Use migrate_completeimporttransaction on KMD to complete the import tx 81 | while True: 82 | time.sleep(60) 83 | try: 84 | complete_tx = rpc_connection_kmdblockchain.migrate_completeimporttransaction(import_tx) 85 | except Exception as e: 86 | print(e) 87 | print("Import transaction on KMD not created yet, waiting for 60 seconds more") 88 | pass 89 | else: 90 | print("Seems tx created") 91 | break 92 | 93 | # Broadcast tx to target chain 94 | attempts = 0 95 | while True: 96 | time.sleep(60) 97 | if attempts < 60: 98 | try: 99 | sent_itx = rpc_connection_destinationchain.sendrawtransaction(complete_tx) 100 | except Exception: 101 | attempts = attempts + 1 102 | print("Tried to broadcast " + str(attempts) + " times") 103 | print("Will try to do it 60 times in total") 104 | else: 105 | break 106 | else: 107 | print("To many attempts. Bye bye.") 108 | sys.exit() 109 | 110 | final_confirmations = 0 111 | #wait_for_confirmation(rpc_connection_destinationchain, sent_itx, 3) 112 | while final_confirmations < 0: 113 | try: 114 | final_confirmations = int(rpc_connection_destinationchain.getrawtransaction(sent_itx, 1)["confirmations"]) 115 | except Exception as e: 116 | print(e) 117 | pass 118 | else: 119 | print("Waiting") 120 | print(rpc_connection_destinationchain.getinfo()["name"] + " : Confirmed import " + sent_itx + " at: " + str(datetime.datetime.today().strftime('%Y-%m-%d'))) 121 | print_balance(rpc_connection_sourcechain, rpc_connection_destinationchain) 122 | t1 = time.time() 123 | print(str(t1-t0) + " migration time (sec)") -------------------------------------------------------------------------------- /rogue_tui.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from lib import rpclib, tuilib 4 | import os 5 | import time 6 | import sys 7 | import platform 8 | 9 | header = "\ 10 | ______ _____ _____ \n\ 11 | | ___ \ / __ \/ __ \\\n\ 12 | | |_/ /___ __ _ _ _ ___| / \/| / \/\n\ 13 | | // _ \ / _` | | | |/ _ \ | | |\n\ 14 | | |\ \ (_) | (_| | |_| | __/ \__/\| \__/\\\n\ 15 | \_| \_\___/ \__, |\__,_|\___|\____/ \____/\n\ 16 | __/ |\n\ 17 | |___/\n" 18 | 19 | 20 | menuItems = [ 21 | {"Check current connection": tuilib.getinfo_tui}, 22 | {"Check mempool": tuilib.print_mempool}, 23 | {"Check my warriors list": tuilib.print_players_list}, 24 | {"Transfer warrior to other pubkey": tuilib.warrior_trasnfer}, 25 | {"TOP-20 ROGUE Warriors": tuilib.top_warriors_rating}, 26 | {"Set warriors name": tuilib.set_warriors_name}, 27 | {"Start singleplayer training game (creating, registering and starting game)": tuilib.rogue_newgame_singleplayer}, 28 | {"Create multiplayer game": tuilib.rogue_newgame_multiplayer}, 29 | {"Join (register) multiplayer game": tuilib.rogue_join_multiplayer_game}, 30 | {"Check my multiplayer games status / start": tuilib.play_multiplayer_game}, 31 | {"Check if somebody wants to buy your warrior (incoming bids)": tuilib.print_icoming_bids}, 32 | {"Place order to sell warrior": tuilib.sell_warrior}, 33 | {"Place order to buy someones warrior": tuilib.place_bid_on_warriror}, 34 | {"Check if somebody selling warrior": tuilib.find_warriors_asks}, 35 | {"Check / cancel my warriors trade orders": tuilib.warriors_orders_check}, 36 | # {"Manually exit the game (bailout)": "test"}, 37 | # {"Manually claim ROGUE coins for game (highlander)": "test"}, 38 | {"Exit": tuilib.exit} 39 | ] 40 | 41 | def main(): 42 | while True: 43 | operating_system = platform.system() 44 | if operating_system != 'Win64' and operating_system != 'Windows': 45 | os.system('clear') 46 | else: 47 | os.system('cls') 48 | print(tuilib.colorize(header, 'pink')) 49 | print(tuilib.colorize('TUI v0.0.3\n', 'green')) 50 | menu_items_counter = 0 51 | for item in menuItems: 52 | if menu_items_counter == 0: 53 | print("\nUtility:\n") 54 | menu_items_counter = menu_items_counter + 1 55 | print(tuilib.colorize("[" + str(menuItems.index(item)) + "] ", 'blue') + list(item.keys())[0]) 56 | if menu_items_counter == 6: 57 | print("\nNew singleplayer game:\n") 58 | if menu_items_counter == 7: 59 | print("\nMultiplayer games:\n") 60 | if menu_items_counter == 10: 61 | print("\nDEX features:\n") 62 | choice = input(">> ") 63 | try: 64 | if int(choice) < 0: 65 | raise ValueError 66 | # Call the matching function 67 | if list(menuItems[int(choice)].keys())[0] == "Exit": 68 | list(menuItems[int(choice)].values())[0]() 69 | else: 70 | list(menuItems[int(choice)].values())[0](rpc_connection) 71 | except (ValueError, IndexError): 72 | pass 73 | 74 | 75 | if __name__ == "__main__": 76 | while True: 77 | chain = "ROGUE" 78 | try: 79 | print(tuilib.colorize("Welcome to the RogueCC TUI!\n" 80 | "Please provide asset chain RPC connection details for initialization", "blue")) 81 | rpc_connection = rpclib.def_credentials(chain) 82 | rpclib.getinfo(rpc_connection) 83 | # waiting until chain is in sync 84 | while True: 85 | have_blocks = rpclib.getinfo(rpc_connection)["blocks"] 86 | longest_chain = rpclib.getinfo(rpc_connection)["longestchain"] 87 | if have_blocks != longest_chain: 88 | print(tuilib.colorize("ROGUE not synced yet.", "red")) 89 | print("Have " + str(have_blocks) + " from " + str(longest_chain) + " blocks") 90 | time.sleep(5) 91 | else: 92 | print(tuilib.colorize("Chain is synced!", "green")) 93 | break 94 | # checking if pubkey is set and set valid if not 95 | info = rpclib.getinfo(rpc_connection) 96 | if "pubkey" in info.keys(): 97 | print("Pubkey is already set") 98 | else: 99 | valid_address = rpc_connection.getaccountaddress("") 100 | valid_pubkey = rpc_connection.validateaddress(valid_address)["pubkey"] 101 | rpc_connection.setpubkey(valid_pubkey) 102 | print(tuilib.colorize("Pubkey is succesfully set!", "green")) 103 | # copy ROGUE config to current daemon directory if it's not here 104 | tuilib.check_if_config_is_here(rpc_connection, "ROGUE") 105 | except Exception: 106 | print(tuilib.colorize("Cant connect to ROGUE daemon RPC! Please check if daemon is up.", "pink")) 107 | tuilib.exit() 108 | else: 109 | print(tuilib.colorize("Succesfully connected!\n", "green")) 110 | with (open("lib/logo.txt", "r")) as logo: 111 | for line in logo: 112 | print(line, end='') 113 | time.sleep(0.04) 114 | print("\n") 115 | break 116 | main() 117 | -------------------------------------------------------------------------------- /lib/rpclib.py: -------------------------------------------------------------------------------- 1 | import re 2 | import os 3 | import http 4 | import platform 5 | from slickrpc import Proxy 6 | 7 | 8 | # RPC connection 9 | def get_rpc_details(chain): 10 | rpcport =''; 11 | operating_system = platform.system() 12 | if operating_system == 'Darwin': 13 | ac_dir = os.environ['HOME'] + '/Library/Application Support/Komodo' 14 | elif operating_system == 'Linux': 15 | ac_dir = os.environ['HOME'] + '/.komodo' 16 | elif operating_system == 'Win64' or operating_system == 'Windows': 17 | ac_dir = '%s/komodo/' % os.environ['APPDATA'] 18 | if chain == 'KMD': 19 | coin_config_file = str(ac_dir + '/komodo.conf') 20 | else: 21 | coin_config_file = str(ac_dir + '/' + chain + '/' + chain + '.conf') 22 | with open(coin_config_file, 'r') as f: 23 | for line in f: 24 | l = line.rstrip() 25 | if re.search('rpcuser', l): 26 | rpcuser = l.replace('rpcuser=', '') 27 | elif re.search('rpcpassword', l): 28 | rpcpassword = l.replace('rpcpassword=', '') 29 | elif re.search('rpcport', l): 30 | rpcport = l.replace('rpcport=', '') 31 | if len(rpcport) == 0: 32 | if chain == 'KMD': 33 | rpcport = 7771 34 | else: 35 | print("rpcport not in conf file, exiting") 36 | print("check "+coin_config_file) 37 | exit(1) 38 | return rpcuser, rpcpassword, rpcport 39 | 40 | def def_credentials(chain): 41 | rpc = get_rpc_details(chain) 42 | try: 43 | rpc_connection = Proxy("http://%s:%s@127.0.0.1:%d"%(rpc[0], rpc[1], int(rpc[2]))) 44 | except Exception: 45 | raise Exception("Connection error! Probably no daemon on selected port.") 46 | return rpc_connection 47 | 48 | def rpc_connect(rpc_user, rpc_password, port): 49 | try: 50 | rpc_connection = Proxy("http://%s:%s@127.0.0.1:%d"%(rpc_user, rpc_password, port)) 51 | except Exception: 52 | raise Exception("Connection error! Probably no daemon on selected port.") 53 | return rpc_connection 54 | 55 | 56 | # Non CC calls 57 | def getinfo(rpc_connection): 58 | try: 59 | getinfo = rpc_connection.getinfo() 60 | except Exception: 61 | raise Exception("Connection error!") 62 | return getinfo 63 | 64 | 65 | def sendrawtransaction(rpc_connection, hex): 66 | tx_id = rpc_connection.sendrawtransaction(hex) 67 | return tx_id 68 | 69 | 70 | def gettransaction(rpc_connection, tx_id): 71 | transaction_info = rpc_connection.gettransaction(tx_id) 72 | return transaction_info 73 | 74 | 75 | def getrawtransaction(rpc_connection, tx_id): 76 | rawtransaction = rpc_connection.getrawtransaction(tx_id) 77 | return rawtransaction 78 | 79 | 80 | def getbalance(rpc_connection): 81 | balance = rpc_connection.getbalance() 82 | return balance 83 | 84 | # Token CC calls 85 | def token_create(rpc_connection, name, supply, description): 86 | token_hex = rpc_connection.tokencreate(name, supply, description) 87 | return token_hex 88 | 89 | 90 | def token_info(rpc_connection, token_id): 91 | token_info = rpc_connection.tokeninfo(token_id) 92 | return token_info 93 | 94 | 95 | #TODO: have to add option with pubkey input 96 | def token_balance(rpc_connection, token_id): 97 | token_balance = rpc_connection.tokenbalance(token_id) 98 | return token_balance 99 | 100 | def token_list(rpc_connection): 101 | token_list = rpc_connection.tokenlist() 102 | return token_list 103 | 104 | 105 | def token_convert(rpc_connection, evalcode, token_id, pubkey, supply): 106 | token_convert_hex = rpc_connection.tokenconvert(evalcode, token_id, pubkey, supply) 107 | return token_convert_hex 108 | 109 | def get_rawmempool(rpc_connection): 110 | mempool = rpc_connection.getrawmempool() 111 | return mempool 112 | 113 | # Oracle CC calls 114 | def oracles_create(rpc_connection, name, description, data_type): 115 | oracles_hex = rpc_connection.oraclescreate(name, description, data_type) 116 | return oracles_hex 117 | 118 | def oracles_fund(rpc_connection, oracle_id): 119 | oracles_fund_hex = rpc_connection.oraclesfund(oracle_id) 120 | return oracles_fund_hex 121 | 122 | def oracles_register(rpc_connection, oracle_id, data_fee): 123 | oracles_register_hex = rpc_connection.oraclesregister(oracle_id, data_fee) 124 | return oracles_register_hex 125 | 126 | 127 | def oracles_subscribe(rpc_connection, oracle_id, publisher_id, data_fee): 128 | oracles_subscribe_hex = rpc_connection.oraclessubscribe(oracle_id, publisher_id, data_fee) 129 | return oracles_subscribe_hex 130 | 131 | 132 | def oracles_info(rpc_connection, oracle_id): 133 | oracles_info = rpc_connection.oraclesinfo(oracle_id) 134 | return oracles_info 135 | 136 | 137 | def oracles_data(rpc_connection, oracle_id, hex_string): 138 | oracles_data = rpc_connection.oraclesdata(oracle_id, hex_string) 139 | return oracles_data 140 | 141 | 142 | def oracles_list(rpc_connection): 143 | oracles_list = rpc_connection.oracleslist() 144 | return oracles_list 145 | 146 | 147 | def oracles_samples(rpc_connection, oracletxid, batonutxo, num): 148 | oracles_sample = rpc_connection.oraclessamples(oracletxid, batonutxo, num) 149 | return oracles_sample 150 | 151 | 152 | # Gateways CC calls 153 | # Arguments changing dynamically depends of M N, so supposed to wrap it this way 154 | # token_id, oracle_id, coin_name, token_supply, M, N + pubkeys for each N 155 | def gateways_bind(rpc_connection, *args): 156 | gateways_bind_hex = rpc_connection.gatewaysbind(*args) 157 | return gateways_bind_hex 158 | 159 | 160 | def gateways_deposit(rpc_connection, gateway_id, height, coin_name,\ 161 | coin_txid, claim_vout, deposit_hex, proof, dest_pub, amount): 162 | gateways_deposit_hex = rpc_connection.gatewaysdeposit(gateway_id, str(height), coin_name,\ 163 | coin_txid, str(claim_vout), deposit_hex, proof, dest_pub, str(amount)) 164 | return gateways_deposit_hex 165 | 166 | 167 | def gateways_claim(rpc_connection, gateway_id, coin_name, deposit_txid, dest_pub, amount): 168 | gateways_claim_hex = rpc_connection.gatewaysclaim(gateway_id, coin_name, deposit_txid, dest_pub, str(amount)) 169 | return gateways_claim_hex 170 | 171 | 172 | def gateways_withdraw(rpc_connection, gateway_id, coin_name, withdraw_pub, amount): 173 | gateways_withdraw_hex = rpc_connection.gatewayswithdraw(gateway_id, coin_name, withdraw_pub, amount) 174 | return gateways_withdraw_hex 175 | 176 | def gateways_list(rpc_connection): 177 | gateways_list = rpc_connection.gatewayslist() 178 | return gateways_list 179 | 180 | def pegs_fund(rpc_connection, pegs_txid, token_txid, amount): 181 | pegsfund_hex = rpc_connection.pegsfund(pegs_txid, token_txid, str(amount)) 182 | return pegsfund_hex 183 | 184 | def pegs_get(rpc_connection, pegs_txid, token_txid, amount): 185 | pegsget_hex = rpc_connection.pegsget(pegs_txid, token_txid, str(amount)) 186 | return pegsget_hex -------------------------------------------------------------------------------- /docs/pegs_module.md: -------------------------------------------------------------------------------- 1 | ## tl;dr ## 2 | 3 | Note: Build Komodo using the https://github.com/Mixa84/komodo/tree/pegsCC repo, and set `export CONFIGURE_FLAGS='CPPFLAGS=-DTESTMODE'` 4 | 5 | The Pegs Creation TUI will perform the steps below: 6 | 1 - Create Tokens 7 | 2 - Create an Oracle, register as a publisher and subscribe. 8 | 3 - Bind the Tokens and Oracles into a Gateway 9 | 4 - Create a Pegs Contract 10 | 5 - Stop the Pegs chain, and restart with `earlytxid` launch parameter 11 | 6 - Run the Oraclefeed app to maintain the Gateway and monitor deposits / withdrawls. 12 | 13 | To interact with an existing Pegs Contract, use the Pegs Usage TUI. Use a different node and pubkey! To create a pegs account, follow the steps below: 14 | 15 | 1 - Execute a gateways deposit from the source chain (e.g. KMD) 16 | 2 - Wait for the deposit to be notarised (which is validated by the Oraclefeed dapp) 17 | 3 - Claim your tokens on the Pegs chain 18 | 4 - Use `pegsfund` to deposit the tokens into the Pegs contract 19 | 5 - Use `pegsget` to convert the deposited tokens into the pegged asset tokens 20 | 21 | More infomation at https://github.com/Mixa84/komodo/wiki/Pegs-CC 22 | 23 | [ A full tutorial with Pegs command line RPC methods info, will be added to http://developers.komodo.com/ soon] 24 | 25 | PegCC builds upon on the existing Antara modules Tokens, Gateways, Prices and Oracles. 26 | Tokens are created, and transmitted across chains using Gateways for use within the Pegs chain. 27 | 28 | First, a Tokens contract is created on the Pegs chain. The token name must be set to the ticker of the source chain (e.g. KMD). These tokens will represent coins from the source chain which are redeemed as a loan, backed by the value of the source coins (tracked via the Prices module) deposited into the Gateway. As the source coin value fluctuates, the Prices module monitors the debt ratio of a user's deposit against the Tokens on loan. 29 | 30 | Next an Oracle is created to monitor the chain state of the source coin, and communicate information about coins deposited via the Gateway. This oracle must also have the name value set to the source coin ticker, and the datatype set to 'Ihh' to store the source chain's block headers. 31 | 32 | Next, a Gateways contract is created by binding the Tokens contract with the Oracle transaction ID and one or more pubkeys. These pubkeys allow for protecting withdrawl of coins locked in the Gateway via "M of N" multisig security. The name value of the Gateway must also be set to the source coin ticker, and the total supply balance of all tokens created in the binded Tokens contract. Additionally, the source coin's pubtype, p2shtype and wiftype are required for the Gateway to function as intended. 33 | 34 | Finally, a Pegs contract is created for a set amount of funds, linked to one or more gateways. These funds can be accessed as a secured loan via a Gateways deposit from the external chain. Each chain can only have a single Pegs Contract - to ensure this the Pegs creation transaction ID is added as a launch parameter value for the Pegs chain (e.g. -earlytxid=5ccdff0d29f2f47fb1e349c1ff9ae17977a58763abacf693cd27e98b38fad3f3) 35 | 36 | _Note: Pubkeys used to create the Gateway, Token, Oracle and Pegs Contract can not be used to perform gateway deposit._ 37 | 38 | Once the above Token, Oracle, Gateway and Pegs Contracts are prepared, an Oraclefeed app is built and started, using the Gateway and Oracle creation transaction IDs as launch parameters. The Oraclefeed app validates deposits from the source chain (e.g. KMD) to the Pegs chain (e.g PEGSTEST). This app must be active on one or more full nodes running both chains, launched with one of the pubkeys used to bind the Gateway. It is important to ensure these pubkeys are registered as an oracle publisher on the Pegs chain, and sufficiently funded via oracle subscription to cover datafees associated with recording source chain block hashes. With multisig gateways - at a minimum - enough fullnodes and pubkeys must be running the Oraclefeed to validate multisig transactions. 39 | 40 | ## How it works ## 41 | 42 | Via the above, 80% of the value of deposited tokens can be exchanged for a “stablecoin” (e.g. USDK) at current Prices market value as reported by the trustless oracle. It is effectively a “deposit and loan” system, where deposited tokens secure the loan. 43 | The USDK tokens can be traded for fiat / other crypto, or redeemed for the originally deposited crypto used to create them. 44 | If the value of the deposited coin rises, additional USDK is created and available to account holder to withdraw, improving their debt ratio. 45 | If the value of the deposited coin falls, the worst accounts are subject to liquidation. In this event, a third party can gain a 5% return by paying the debt of the account with an excessive debt ratio (e.g. > 90%). The remainder will be applied to the chain as a whole to improve the global debt ratio to prevent underlying assets of the chain falling below the value of total USDK issued. 46 | 47 | For example: 48 | Bob uses gatewaysdeposit to convert 100 KMD to KMDT when the market value is $5 per KMD 49 | Bob uses pegsfund to open a new account and then pegsget to convert this KMDT for 375 USDK. 50 | Bob now has 100 KMD (worth $500) securing a “loan” of 375 USDK (worth $375), effectively a 75% debt ratio (375:500). 51 | Note: This is the opposite of fractional reserve lending! 52 | After some time, KMD rises to $10. Bob’s debt ratio is now a very healthy 37.5% (375:1000). 53 | Bob decides to take some profit and exchanges for an additional 375 USDK, rising his debt ratio to 75% (750:1000). 54 | Bob trades 250 USDK over the counter for $250 USD fiat. 55 | At this stage, Bob’s original 100 KMDT deposit worth $500 at time of account creation has been converted into 750 USDK. He has sold part of this for $250 in fiat, still has 100KMD (worth $1000) securing his account, and has 500 USDK (worth $500) to trade with - a combined total value of $1750 from his original input of 100KMD ($500 at time of account creation). 56 | 57 | After some more time passes, the price of KMD drops back down to $8.25. Bob’s debt ratio is now at a dangerous level of 90.0909% (750:825), and subject to liquidation. 58 | Alice uses pegsworstaccounts and sees Bob’s debt ratio has left him vulnerable. She decides to liquidate Bob’s account using pegsliquidate, buying out Bob’s account for 750 USDK. 59 | At the current market price of $8.25, the 100KMD which was securing Bob’s account is worth $825. Alice receives a 5% bonus worth 37.5 USDK on top of the 750 USDK cost of liquidating Bob’s account, which is paid out in the form of 95.4545 KMDT, worth $787.5 at the current KMD price of $8.25. 60 | The remaining 4.5454 KMDT from Bob’s account is used to maintain the integrity of the pegs chain by reducing the global debt ratio. 61 | Bob still has his remaining 500 USDK (worth $500), and the US$250 fiat he traded for earlier ($750 total). 62 | The liquidated 100 KMDT account previously securing Bob’s account (worth $825) is closed, netting Bob a loss of $75 against current $8.25 KMD price at liquidation for failing to maintain a good debt ratio. Fortunately for Bob, he’s still up $250 against the original $500 input at account creation (100 KMD at $5), and has suffered no net loss. 63 | As Bob no longer has an account, he can use pegsexchange to convert his USDK to KMDT and either cash out with pegsredeem to reclaim 90 KMD, or use pegsfund to open a new account and then pegsget to convert up to 80% of his KMDT to USDK. -------------------------------------------------------------------------------- /scripts/crosschain_migrations_v2.py: -------------------------------------------------------------------------------- 1 | from slickrpc import Proxy 2 | import time 3 | import sys 4 | import datetime 5 | 6 | 7 | def print_balance(rpc_connection_source, rpc_connection_destination): 8 | balance_source = rpc_connection_source.getbalance() 9 | balance_destination = rpc_connection_destination.getbalance() 10 | source_chain_name = rpc_connection_source.getinfo()["name"] 11 | destination_chain_name = rpc_connection_destination.getinfo()["name"] 12 | print("Source chain " + source_chain_name + " balance: " + str(balance_source)) 13 | print("Destination chain " + destination_chain_name + " balance: " + str(balance_destination)) 14 | 15 | 16 | def create_import_transactions(rpc_connection, signed_hex, payouts, import_tx_list): 17 | while True: 18 | try: 19 | import_tx = rpc_connection.migrate_createimporttransaction(signed_hex["hex"], payouts) 20 | except Exception as e: 21 | print(e) 22 | print("Import transaction not created yet, waiting for 10 seconds more") 23 | time.sleep(10) 24 | pass 25 | else: 26 | print("Seems tx created") 27 | is_created = True 28 | import_tx_list.append(import_tx) 29 | break 30 | return is_created 31 | 32 | 33 | def migrate_import_transactions(rpc_connection, import_tx, complete_tx_list): 34 | while True: 35 | try: 36 | complete_tx = rpc_connection.migrate_completeimporttransaction(import_tx) 37 | except Exception as e: 38 | print(e) 39 | print("Import transaction on KMD not created yet, waiting for 10 seconds more") 40 | time.sleep(10) 41 | pass 42 | else: 43 | print("Seems tx created") 44 | is_imported = True 45 | complete_tx_list.append(complete_tx) 46 | break 47 | return is_imported 48 | 49 | 50 | def broadcast_on_destinationchain(rpc_connection, complete_tx, dest_tx_list): 51 | attempts = 0 52 | while True: 53 | if attempts < 60: 54 | try: 55 | sent_itx = rpc_connection.sendrawtransaction(complete_tx) 56 | except Exception: 57 | attempts = attempts + 1 58 | print("Tried to broadcast " + str(attempts) + " times") 59 | print("Will try to do it up to 60 times in total. Now rest for 15 seconds.") 60 | time.sleep(15) 61 | else: 62 | print("Transactinon broadcasted on destination chain") 63 | dest_tx_list.append(sent_itx) 64 | is_broadcasted = True 65 | break 66 | else: 67 | print("Too many attempts. Bye bye.") 68 | sys.exit() 69 | return is_broadcasted 70 | 71 | 72 | # SET RPC CONNECTION DETAILS HERE 73 | rpc_connection_sourcechain = Proxy("http://%s:%s@127.0.0.1:%d"%("user", "pass", 30667)) 74 | rpc_connection_destinationchain = Proxy("http://%s:%s@127.0.0.1:%d"%("user", "pass", 50609)) 75 | rpc_connection_kmdblockchain = Proxy("http://%s:%s@127.0.0.1:%d"%("user", "pass", 7771)) 76 | # SET ADDRESS AND MIGRATION AMOUNT HERE 77 | address = "RHq3JsvLxU45Z8ufYS6RsDpSG4wi6ucDev" 78 | amount = 2 79 | migrations_amount = 500 80 | 81 | t0 = time.time() 82 | 83 | print_balance(rpc_connection_sourcechain, rpc_connection_destinationchain) 84 | 85 | print("Sending " + str(amount) + " coins from " + rpc_connection_sourcechain.getinfo()["name"] + " chain " +\ 86 | "to " + rpc_connection_destinationchain.getinfo()["name"] + " chain") 87 | 88 | counter_raw = migrations_amount 89 | sent_tx_list = [] 90 | payouts_list = [] 91 | signed_hex_list = [] 92 | while counter_raw > 0: 93 | raw_transaction = rpc_connection_sourcechain.createrawtransaction([], {address: amount}) 94 | export_data = rpc_connection_sourcechain.migrate_converttoexport(raw_transaction, rpc_connection_destinationchain.getinfo()["name"]) 95 | export_raw = export_data["exportTx"] 96 | export_funded_data = rpc_connection_sourcechain.fundrawtransaction(export_raw) 97 | export_funded_transaction = export_funded_data["hex"] 98 | payouts = export_data["payouts"] 99 | payouts_list.append(payouts) 100 | signed_hex = rpc_connection_sourcechain.signrawtransaction(export_funded_transaction) 101 | signed_hex_list.append(signed_hex) 102 | sent_tx = rpc_connection_sourcechain.sendrawtransaction(signed_hex["hex"]) 103 | if len(sent_tx) != 64: 104 | print(signed_hex) 105 | print(sent_tx) 106 | print("Export TX not successfully created") 107 | sys.exit() 108 | sent_tx_list.append(sent_tx) 109 | counter_raw = counter_raw - 1 110 | 111 | print(str(len(sent_tx_list)) + " export transactions sent:\n") 112 | for sent_tx in sent_tx_list: 113 | print(sent_tx + "\n") 114 | 115 | 116 | # Wait for a confirmation on source chain 117 | while True: 118 | confirmed = all(int(rpc_connection_sourcechain.gettransaction(sent_tx)["confirmations"]) > 0 for sent_tx in sent_tx_list) 119 | if not confirmed: 120 | print("Waiting for all export transactions to be confirmed on source chain") 121 | time.sleep(5) 122 | else: 123 | print("All export transactions confirmed!") 124 | break 125 | 126 | # Use migrate_createimporttransaction to create the import TX 127 | import_list = [] 128 | while True: 129 | import_tx_created = all(create_import_transactions(rpc_connection_sourcechain, signed_hex, payouts, import_list) for signed_hex, payouts in zip(signed_hex_list, payouts_list)) 130 | if not import_tx_created: 131 | print("Waiting for all import transactions to be created on source chain") 132 | else: 133 | print("All import transactions created!") 134 | break 135 | 136 | # Use migrate_completeimporttransaction on KMD to complete the import tx 137 | complete_list = [] 138 | while True: 139 | migration_complete = all(migrate_import_transactions(rpc_connection_kmdblockchain, import_tx, complete_list) for import_tx in import_list) 140 | if not migration_complete: 141 | print("Waiting for all migrations to be completed on Komodo blockchain") 142 | else: 143 | print("All migrations are completed on Komodo blockchain") 144 | break 145 | 146 | # Broadcast tx to target chain 147 | dest_txs = [] 148 | while True: 149 | broadcasted_on_target = all(broadcast_on_destinationchain(rpc_connection_destinationchain, complete_tx, dest_txs) for complete_tx in complete_list) 150 | if not broadcasted_on_target: 151 | print("Waiting for imports to be broadcasted on destination chain") 152 | else: 153 | print("All imports are broadcasted to destination chain") 154 | break 155 | 156 | # Wait for a confirmation on destination chain 157 | while True: 158 | try: 159 | confirmed = all(int(rpc_connection_destinationchain.getrawtransaction(dest_tx, 1)["confirmations"]) > 0 for dest_tx in dest_txs) 160 | except Exception as e: 161 | print(e) 162 | print("Transaction is not on blockchain yet. Let's wait a little.") 163 | time.sleep(10) 164 | pass 165 | else: 166 | if not confirmed: 167 | print("Waiting for all export transactions to be confirmed on source chain") 168 | time.sleep(5) 169 | else: 170 | print("All export transactions confirmed!") 171 | break 172 | 173 | for sent_itx in dest_txs: 174 | print(rpc_connection_destinationchain.getinfo()["name"] + " : Confirmed import " + sent_itx + " at: " + str(datetime.datetime.today().strftime('%Y-%m-%d-%M:%S'))) 175 | 176 | t1 = time.time() 177 | print("Total migrations amount: " + str(migrations_amount)) 178 | print(str(t1-t0) + " migration time (sec)") -------------------------------------------------------------------------------- /scripts/chainstart/chainstart.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | import time 4 | import subprocess 5 | import wget 6 | import tarfile 7 | from slickrpc import Proxy 8 | from slickrpc.exc import RpcException as RPCError 9 | from pycurl import error as HttpError 10 | 11 | 12 | def create_proxy(node_params_dictionary): 13 | try: 14 | proxy = Proxy("http://%s:%s@%s:%d" % (node_params_dictionary.get('rpc_user'), 15 | node_params_dictionary.get('rpc_password'), 16 | node_params_dictionary.get('rpc_ip'), 17 | node_params_dictionary.get('rpc_port')), timeout=120) 18 | except Exception as e: 19 | raise Exception("Connection error! Probably no daemon on selected port. Error: ", e) 20 | return proxy 21 | 22 | 23 | def validate_proxy(env_params_dictionary, proxy, node=0): 24 | attempts = 0 25 | while True: # base connection check 26 | try: 27 | getinfo_output = proxy.getinfo() 28 | print(getinfo_output) 29 | break 30 | except Exception as e: 31 | print("Coennction failed, error: ", e, "\nRetrying") 32 | attempts += 1 33 | time.sleep(10) 34 | if attempts > 15: 35 | raise ChildProcessError("Node ", node, " does not respond") 36 | print("IMPORTING PRIVKEYS") 37 | res = proxy.importprivkey(env_params_dictionary.get('test_wif')[node], '', True) 38 | print(res) 39 | assert proxy.validateaddress(env_params_dictionary.get('test_address')[node])['ismine'] 40 | try: 41 | pubkey = env_params_dictionary.get('test_pubkey')[node] 42 | assert proxy.getinfo()['pubkey'] == pubkey 43 | except (KeyError, IndexError): 44 | print("\nNo -pubkey= runtime parameter specified") 45 | assert proxy.verifychain() 46 | time.sleep(15) 47 | print("\nBalance: " + str(proxy.getbalance())) 48 | print("Each node should have at least 777 coins to perform CC tests\n") 49 | 50 | 51 | def enable_mining(proxy): 52 | cores = os.cpu_count() 53 | if cores > 2: 54 | threads_count = cores - 2 55 | else: 56 | threads_count = 1 57 | tries = 0 58 | while True: 59 | try: 60 | proxy.setgenerate(True, threads_count) 61 | break 62 | except (RPCError, HttpError) as e: 63 | print(e, " Waiting chain startup\n") 64 | time.sleep(10) 65 | tries += 1 66 | if tries > 30: 67 | raise ChildProcessError("Node did not start correctly, aborting\n") 68 | 69 | 70 | def load_env_config(): 71 | tp = {} # test env parameters 72 | if os.name == 'posix': 73 | envconfig = './envconfig.json' 74 | else: 75 | envconfig = 'envconfig.json' 76 | if os.environ['CHAIN']: 77 | tp.update({'clients_to_start': int(os.environ['CLIENTS'])}) 78 | tp.update({'is_bootstrap_needed': os.environ['IS_BOOTSTRAP_NEEDED']}) 79 | tp.update({'bootstrap_url': os.environ['BOOTSTRAP_URL']}) 80 | tp.update({'chain_start_mode': os.environ['CHAIN_MODE']}) 81 | tp.update({'ac_name': os.environ['CHAIN']}) 82 | test_wif_list = [] # preset empty params lists 83 | test_addr_list = [] 84 | test_pubkey_list = [] 85 | for i in range(tp.get('clients_to_start')): 86 | test_wif_list.append(os.environ["TEST_WIF" + str(i)]) 87 | test_addr_list.append(os.environ["TEST_ADDY" + str(i)]) 88 | if os.environ['CHAIN_MODE'] not in ['DEX1', 'DEX2']: 89 | test_pubkey_list.append(os.environ["TEST_PUBKEY" + str(i)]) 90 | tp.update({'test_wif': test_wif_list}) 91 | tp.update({'test_address': test_addr_list}) 92 | tp.update({'test_pubkey': test_pubkey_list}) 93 | elif os.path.isfile(envconfig) and not os.environ['CHAIN']: 94 | with open(envconfig, 'r') as f: 95 | tp = json.load(f) 96 | else: 97 | raise EnvironmentError("\nNo test env configuration provided") 98 | return tp 99 | 100 | 101 | def load_ac_params(asset, chain_mode='default'): 102 | try: 103 | binary_path = os.environ['BINARYPATH'] 104 | except (KeyError, IndexError): 105 | if os.name == 'posix': 106 | binary_path = '../../src/komodod' 107 | else: 108 | binary_path = (os.getcwd() + '\\..\\..\\src\\komodod.exe') 109 | if os.name == 'posix': 110 | chainconfig = './chainconfig.json' 111 | else: 112 | chainconfig = (os.getcwd() + '\\chainconfig.json') 113 | if os.path.isfile(chainconfig): 114 | with open(chainconfig, 'r') as f: 115 | jsonparams = json.load(f) 116 | ac = jsonparams.get(asset) # asset chain parameters 117 | ac.update({'binary_path': binary_path}) 118 | if chain_mode == 'REGTEST': 119 | ac.update({'daemon_params': ['-daemon', '-whitelist=127.0.0.1', '-regtest']}) 120 | elif chain_mode == 'DEX1': 121 | ac.update({'daemon_params': ['-daemon', '-whitelist=127.0.0.1', '-dexp2p=1']}) 122 | elif chain_mode == 'DEX2': 123 | ac.update({'daemon_params': ['-daemon', '-whitelist=127.0.0.1', '-dexp2p=2']}) 124 | else: 125 | ac.update({'daemon_params': ['-daemon', '-whitelist=127.0.0.1']}) 126 | else: 127 | raise EnvironmentError("\nNo asset chains configuration provided") 128 | return ac 129 | 130 | 131 | def create_configs(asset, node=0): 132 | if os.name == 'posix': 133 | confpath = ('./node_' + str(node) + '/' + asset + '.conf') 134 | else: 135 | confpath = (os.getcwd() + '\\node_' + str(node) + '\\' + asset + '.conf') 136 | if os.path.isfile(confpath) or os.path.isdir(os.getcwd() + '/node_' + str(node)): 137 | for root, dirs, files in os.walk('node_' + str(node), topdown=False): 138 | for name in files: 139 | os.remove(os.path.join(root, name)) 140 | for name in dirs: 141 | os.rmdir(os.path.join(root, name)) 142 | os.rmdir('node_' + str(node)) 143 | print("Clean up done") 144 | os.mkdir('node_' + str(node)) 145 | open(confpath, 'a').close() 146 | with open(confpath, 'a') as conf: 147 | conf.write("rpcuser=test\n") 148 | conf.write("rpcpassword=test\n") 149 | conf.write('rpcport=' + str(7000 + node) + '\n') 150 | conf.write("rpcbind=0.0.0.0\n") 151 | conf.write("rpcallowip=0.0.0.0/0\n") 152 | 153 | 154 | def main(): 155 | env_params = load_env_config() 156 | clients_to_start = env_params.get('clients_to_start') 157 | aschain = env_params.get('ac_name') 158 | if env_params.get('is_bootstrap_needed'): # bootstrap chains 159 | if env_params.get('bootstrap_url'): 160 | if os.path.isfile('bootstrap.tar.gz'): 161 | os.remove('bootstrap.tar.gz') 162 | print("Downloading bootstrap") 163 | wget.download(env_params.get('bootstrap_url'), "bootstrap.tar.gz") 164 | if not os.path.isfile('bootstrap.tar.gz'): 165 | raise FileNotFoundError("bootstrap.tar.gz not found") 166 | try: 167 | tf = tarfile.open("bootstrap.tar.gz") 168 | btrp = True 169 | except FileNotFoundError: 170 | tf = "" 171 | btrp = False 172 | for i in range(clients_to_start): 173 | create_configs(aschain, i) 174 | if btrp: 175 | tf.extractall("node_" + str(i)) 176 | mode = env_params.get('chain_start_mode') 177 | ac_params = load_ac_params(aschain, mode) 178 | for i in range(clients_to_start): # start daemons 179 | if os.name == 'posix': 180 | confpath = (os.getcwd() + '/node_' + str(i) + '/' + aschain + '.conf') 181 | datapath = (os.getcwd() + '/node_' + str(i)) 182 | else: 183 | confpath = (os.getcwd() + '\\node_' + str(i) + '\\' + aschain + '.conf') 184 | datapath = (os.getcwd() + '\\node_' + str(i)) 185 | cl_args = [ac_params.get('binary_path'), 186 | '-conf=' + confpath, 187 | '-datadir=' + datapath 188 | ] 189 | try: 190 | pubkey = env_params.get('test_pubkey')[i] 191 | cl_args.append('-pubkey=' + pubkey) 192 | except IndexError: 193 | pass 194 | if i == 0: 195 | for key in ac_params.keys(): 196 | if key not in ['binary_path', 'daemon_params', 'rpc_user', 'rpcpassword'] and ac_params.get(key): 197 | cl_args.append('-' + key + '=' + str(ac_params.get(key))) 198 | else: 199 | cl_args.append('-addnode=127.0.0.1:' + str(ac_params.get('port'))) 200 | for key in ac_params.keys(): 201 | if key not in ['binary_path', 'daemon_params', 'rpc_user', 'rpcpassword'] and ac_params.get(key): 202 | if isinstance(ac_params.get(key), int): 203 | data = ac_params.get(key) + i 204 | cl_args.append('-' + key + '=' + str(data)) 205 | else: 206 | cl_args.append('-' + key + '=' + str(ac_params.get(key))) 207 | cl_args.extend(ac_params.get('daemon_params')) 208 | print(cl_args) 209 | if os.name == "posix": 210 | subprocess.call(cl_args) 211 | else: 212 | subprocess.Popen(cl_args, shell=False, stderr=subprocess.PIPE, stdout=subprocess.PIPE) 213 | time.sleep(5) 214 | for i in range(clients_to_start): 215 | node_params = { 216 | 'rpc_user': 'test', 217 | 'rpc_password': 'test', 218 | 'rpc_ip': '127.0.0.1', 219 | 'rpc_port': 7000 + i 220 | } 221 | rpc_p = create_proxy(node_params) 222 | validate_proxy(env_params, rpc_p, i) 223 | enable_mining(rpc_p) 224 | 225 | 226 | if __name__ == '__main__': 227 | main() 228 | -------------------------------------------------------------------------------- /lib/visualization_lib.py: -------------------------------------------------------------------------------- 1 | import csv 2 | from datetime import datetime 3 | import sys 4 | from lib import tuilib 5 | 6 | 7 | def create_prices_csv(rpc_connection, depth): 8 | prices_json = rpc_connection.prices(depth) 9 | timestamps = prices_json["timestamps"] 10 | dates = [] 11 | for timestamp in timestamps: 12 | dates.append(datetime.utcfromtimestamp(timestamp).strftime('%Y-%m-%dT%H:%M')) 13 | prices_rows = [] 14 | for pair in prices_json["pricefeeds"]: 15 | i = 0 16 | for price in pair["prices"]: 17 | pair_prices_row = [] 18 | pair_prices_row.append(dates[i]) 19 | pair_prices_row.append(price[0]) 20 | pair_prices_row.append(price[1]) 21 | pair_prices_row.append(price[2]) 22 | pair_prices_row.append(pair["name"]) 23 | i = i + 1 24 | prices_rows.append(pair_prices_row) 25 | 26 | with open('prices.csv', 'w') as f: 27 | filewriter = csv.writer(f, delimiter=',', 28 | quotechar='|', quoting=csv.QUOTE_MINIMAL) 29 | filewriter.writerow(["date", "price1", "price2", "price3", "pair"]) 30 | for row in prices_rows: 31 | filewriter.writerow(row) 32 | f.close() 33 | 34 | 35 | def create_delayed_prices_csv(rpc_connection, depth): 36 | prices_json = rpc_connection.prices(depth) 37 | timestamps = prices_json["timestamps"] 38 | dates = [] 39 | for timestamp in timestamps: 40 | dates.append(datetime.utcfromtimestamp(timestamp - 86400).strftime('%Y-%m-%dT%H:%M')) 41 | prices_rows = [] 42 | for pair in prices_json["pricefeeds"]: 43 | i = 0 44 | for price in pair["prices"]: 45 | pair_prices_row = [] 46 | pair_prices_row.append(dates[i]) 47 | pair_prices_row.append(price[0]) 48 | pair_prices_row.append(price[1]) 49 | pair_prices_row.append(price[2]) 50 | pair_prices_row.append(pair["name"]) 51 | i = i + 1 52 | prices_rows.append(pair_prices_row) 53 | 54 | with open('delayed_prices.csv', 'w') as f: 55 | filewriter = csv.writer(f, delimiter=',', 56 | quotechar='|', quoting=csv.QUOTE_MINIMAL) 57 | filewriter.writerow(["date", "price1", "price2", "price3", "pair"]) 58 | for row in prices_rows: 59 | filewriter.writerow(row) 60 | f.close() 61 | 62 | 63 | def get_pairs_names(rpc_connection): 64 | prices_json = rpc_connection.prices("1") 65 | pairs_names = [] 66 | for pair in prices_json["pricefeeds"]: 67 | pairs_names.append(pair["name"]) 68 | return pairs_names 69 | 70 | # opened bets 71 | def create_csv_with_bets(rpc_connection, open_or_closed): 72 | priceslist = rpc_connection.mypriceslist(open_or_closed) 73 | bets_rows = [] 74 | for price in priceslist: 75 | if price == "48194bab8d377a7fa0e62d5e908474dae906675395753f09969d4c4bea4a7518": 76 | pass 77 | else: 78 | pricesinfo = rpc_connection.pricesinfo(price) 79 | bets_rows_single = [] 80 | bets_rows_single.append(price) 81 | bets_rows_single.append(pricesinfo["rekt"]) 82 | expression = pricesinfo["expression"].split(",") 83 | adopted_expression = "" 84 | for element in expression: 85 | adopted_expression = adopted_expression + element 86 | bets_rows_single.append(adopted_expression) 87 | bets_rows_single.append(pricesinfo["leverage"]) 88 | bets_rows_single.append(pricesinfo["TotalPositionSize"]) 89 | bets_rows_single.append(pricesinfo["TotalProfits"]) 90 | bets_rows_single.append(pricesinfo["equity"]) 91 | bets_rows_single.append(pricesinfo["LastPrice"]) 92 | bets_rows_single.append(pricesinfo["LastHeight"]) 93 | bets_rows.append(bets_rows_single) 94 | if open_or_closed == 'open': 95 | filename = 'betlist.csv' 96 | if open_or_closed == 'closed': 97 | filename = 'betlist_history.csv' 98 | with open(filename, 'w') as f: 99 | filewriter = csv.writer(f, delimiter=',', 100 | quotechar='|', quoting=csv.QUOTE_MINIMAL) 101 | filewriter.writerow(["txid", "is rekt", "expression", "leverage", "TotalPositionSize", "TotalProfits", "equity", "LastPrice", "LastHeight"]) 102 | for row in bets_rows: 103 | filewriter.writerow(row) 104 | f.close 105 | 106 | 107 | # function checking if prices for pair or inversed pair availiable on chain 108 | def is_pair_availiable(rpc_connection, pair): 109 | is_pair_in_list = False 110 | is_pair_reversed = False 111 | # getting known pairs list 112 | known_pair_names = [] 113 | prices_output = rpc_connection.prices("1") 114 | # getting reversed version of pairname 115 | try: 116 | splitted_synthetic = pair.split("_") 117 | reversed_synthetic = splitted_synthetic[1] + "_" + splitted_synthetic[0] 118 | except Exception: 119 | return is_pair_in_list, is_pair_reversed 120 | for feed in prices_output["pricefeeds"]: 121 | known_pair_names.append(feed["name"]) 122 | if pair in known_pair_names: 123 | is_pair_in_list = True 124 | elif reversed_synthetic in known_pair_names: 125 | is_pair_in_list = True 126 | is_pair_reversed = True 127 | return is_pair_in_list, is_pair_reversed 128 | 129 | 130 | # function returning list with prices for pair name if it presist in list 131 | # with inverted price if it inverted price, and with error if no such pair in prices call output 132 | def return_prices_for_pair(rpc_connection, pair, depth): 133 | prices_json = rpc_connection.prices(depth) 134 | timestamps = prices_json["timestamps"] 135 | # checking if it possible to get price for pair 136 | pair_availability = is_pair_availiable(rpc_connection, pair) 137 | # no such pair in prices output 138 | if not pair_availability[0] and not pair_availability[1]: 139 | print("Can't get price for this pair. Aborting.") 140 | # pair available in prices output 141 | if pair_availability[0] and not pair_availability[1]: 142 | for feed in prices_json["pricefeeds"]: 143 | if feed["name"] == pair: 144 | prices = [] 145 | for price in feed["prices"]: 146 | for price_value in price: 147 | prices.append(price_value) 148 | return prices, timestamps 149 | # pair reversed version of some prices output pair 150 | if pair_availability[0] and pair_availability[1]: 151 | splitted_operator = pair.split("_") 152 | reversed_operator = splitted_operator[1] + "_" + splitted_operator[0] 153 | for pair in prices_json["pricefeeds"]: 154 | if pair["name"] == reversed_operator: 155 | prices = [] 156 | for price in pair["prices"]: 157 | for price_value in price: 158 | prices.append(1/price_value) 159 | return prices, timestamps 160 | 161 | 162 | # function returning list with stacks lists 163 | def split_synthetic_on_stacks(rpc_connection, synthetic, depth): 164 | stacks_list = [] 165 | stack_end = 0 166 | for i in range(0, len(synthetic)): 167 | if synthetic[i] == '*' or synthetic[i] == '/': 168 | temp = synthetic[stack_end:(i + 1)] 169 | stacks_list.append(temp) 170 | stack_end = i + 1 171 | return stacks_list 172 | 173 | 174 | def count_stack(rpc_connection, stack, depth): 175 | # 2 pairs in stack case 176 | if len(stack) == 4: 177 | prices1 = return_prices_for_pair(rpc_connection, stack[0], depth) 178 | prices2 = return_prices_for_pair(rpc_connection, stack[1], depth) 179 | # if operator is / dividing stuff, if operator is * multiplying stuff 180 | if stack[2] == "/": 181 | stack_prices = [(float(prices1[0][i])) / (float(prices2[0][i])) for i in range(len(prices1[0]))] 182 | elif stack[2] == "*": 183 | stack_prices = [float(prices1[0][i]) * float(prices2[0][i]) for i in range(len(prices1[0]))] 184 | # 3 pairs in stack case 185 | elif len(stack) == 5: 186 | prices1 = return_prices_for_pair(rpc_connection, stack[0], depth) 187 | prices2 = return_prices_for_pair(rpc_connection, stack[1], depth) 188 | prices3 = return_prices_for_pair(rpc_connection, stack[2], depth) 189 | if stack[3] == "/": 190 | stack_prices = [(float(prices1[0][i])) / (float(prices2[0][i])) / (float(prices3[0][i])) for i in range(len(prices1[0]))] 191 | elif stack[3] == "*": 192 | stack_prices = [float(prices1[0][i]) * float(prices2[0][i]) * float(prices3[0][i]) for i in range(len(prices1[0]))] 193 | else: 194 | return "Incorrect stack!" 195 | print(stack) 196 | return stack_prices 197 | 198 | 199 | def make_csv_for_stack(rpc_connection, stack, stack_name, depth): 200 | stack_prices = count_stack(rpc_connection, stack, depth) 201 | timestamps = rpc_connection.prices(depth)["timestamps"] 202 | dates = [] 203 | for timestamp in timestamps: 204 | dates.append(datetime.utcfromtimestamp(timestamp).strftime('%Y-%m-%dT%H:%M')) 205 | prices_rows = [] 206 | pair_prices_row = [] 207 | j = 0 208 | pair_name = "" 209 | for element in stack: 210 | pair_name = pair_name + element 211 | for i in range(0, len(stack_prices), 3): 212 | pair_prices_row.append(dates[j]) 213 | j = j + 1 214 | pair_prices_row.append(stack_prices[i]) 215 | pair_prices_row.append(stack_prices[i+1]) 216 | pair_prices_row.append(stack_prices[i+2]) 217 | pair_prices_row.append(pair_name) 218 | prices_rows.append(pair_prices_row) 219 | pair_prices_row = [] 220 | 221 | with open(sys.path[0] + '/usergraphs/' + pair_name + '_user', 'w') as f: 222 | filewriter = csv.writer(f, delimiter=',', 223 | quotechar='|', quoting=csv.QUOTE_MINIMAL) 224 | filewriter.writerow(["date", "price1", "price2", "price3", "pair"]) 225 | for row in prices_rows: 226 | filewriter.writerow(row) 227 | f.close() 228 | 229 | 230 | def draw_a_graph(): 231 | pass 232 | -------------------------------------------------------------------------------- /antara_tui.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from lib import rpclib, tuilib 4 | import os 5 | import time 6 | 7 | oracles = {} 8 | oracles['header'] = "\ 9 | _ ____ _ __ __ _ _ \n\ 10 | /\ | | / __ \ | | | \/ | | | | | \n\ 11 | / \ _ __ | |_ __ _ _ __ __ _ | | | |_ __ __ _ ___| | ___ ___ | \ / | ___ __| |_ _| | ___ \n\ 12 | / /\ \ | '_ \| __/ _` | '__/ _` | | | | | '__/ _` |/ __| |/ _ \/ __| | |\/| |/ _ \ / _` | | | | |/ _ \ \n\ 13 | / ____ \| | | | || (_| | | | (_| | | |__| | | | (_| | (__| | __/\__ \ | | | | (_) | (_| | |_| | | __/ \n\ 14 | /_/ \_\_| |_|\__\__,_|_| \__,_| \____/|_| \__,_|\___|_|\___||___/ |_| |_|\___/ \__,_|\__,_|_|\___| \n" 15 | 16 | oracles['menu'] = [ 17 | # TODO: Have to implement here native oracle file uploader / reader, should be dope 18 | # TODO: data publisher / converter for different types 19 | {"Check current connection": tuilib.getinfo_tui}, 20 | {"Check mempool": tuilib.print_mempool}, 21 | {"View oracle info": tuilib.oracles_info}, 22 | {"Create oracle": tuilib.oracle_create_tui}, 23 | {"Register as publisher for oracle": tuilib.oracle_register_tui}, 24 | {"Subscribe on oracle (+UTXO generator)": tuilib.oracle_subscription_utxogen}, 25 | {"Upload file to oracle": tuilib.convert_file_oracle_D}, 26 | {"Display list of files uploaded to this AC": tuilib.display_files_list}, 27 | {"Download files from oracle": tuilib.files_downloader}, 28 | {"Return to Antara modules menu": tuilib.exit_main}, 29 | {"Exit TUI": tuilib.exit} 30 | ] 31 | oracles['author'] = 'Welcome to the OraclesCC TUI!\n"CLI version 0.2 by Anton Lysakov & Thorn Mennet\n' 32 | 33 | pegs_usage = {} 34 | pegs_usage['header'] = "\ 35 | _ _____ __ __ _ _ \n\ 36 | /\ | | | __ \ | \/ | | | | | \n\ 37 | / \ _ __ | |_ __ _ _ __ __ _ | |__) |__ __ _ ___ | \ / | ___ __| |_ _| | ___ \n\ 38 | / /\ \ | '_ \| __/ _` | '__/ _` | | ___/ _ \/ _` / __| | |\/| |/ _ \ / _` | | | | |/ _ \ \n\ 39 | / ____ \| | | | || (_| | | | (_| | | | | __/ (_| \__ \ | | | | (_) | (_| | |_| | | __/ \n\ 40 | /_/ \_\_| |_|\__\__,_|_| \__,_| |_| \___|\__, |___/ |_| |_|\___/ \__,_|\__,_|_|\___| \n\ 41 | __/ | \n\ 42 | |___/ \n" 43 | 44 | pegs_usage['menu'] = [ 45 | {"Pegs Module Readme": tuilib.readme_tui}, 46 | {"Check connection to assetchain": tuilib.getinfo_tui}, 47 | {"Check assetchain mempool": tuilib.print_mempool}, 48 | {"Check connection to KMD": tuilib.getinfo_tui}, 49 | {"Connect to KMD daemon": tuilib.rpc_kmd_connection_tui}, 50 | {"View assetchain Gateway Info": tuilib.gateway_info_tui}, 51 | {"Deposit KMD in Gateway and claim Tokens": tuilib.gateways_deposit_claim_tokens}, 52 | {"Execute Pegs funding": tuilib.pegs_fund_tui}, 53 | {"Execute Pegs get": tuilib.pegs_get_tui}, 54 | {"Check Pegs info": tuilib.pegsinfo_tui}, 55 | {"Check Pegs account history": tuilib.pegs_accounthistory_tui}, 56 | {"Check Pegs account info": tuilib.pegs_accountinfo_tui}, 57 | {"Check Pegs addresses": tuilib.pegs_addresses_tui}, 58 | {"Check Pegs worst accounts": tuilib.pegs_worstaccounts_tui}, 59 | {"Return to Antara modules menu": tuilib.exit_main}, 60 | {"Exit TUI": tuilib.exit} 61 | ] 62 | pegs_usage['author'] = 'Welcome to the Pegs Usage TUI!\n"CLI version 0.2 by Thorn Mennet\n' 63 | 64 | pegs_create = {} 65 | pegs_create['header'] = "\ 66 | _ _____ __ __ _ _ \n\ 67 | /\ | | | __ \ | \/ | | | | | \n\ 68 | / \ _ __ | |_ __ _ _ __ __ _ | |__) |__ __ _ ___ | \ / | ___ __| |_ _| | ___ \n\ 69 | / /\ \ | '_ \| __/ _` | '__/ _` | | ___/ _ \/ _` / __| | |\/| |/ _ \ / _` | | | | |/ _ \ \n\ 70 | / ____ \| | | | || (_| | | | (_| | | | | __/ (_| \__ \ | | | | (_) | (_| | |_| | | __/ \n\ 71 | /_/ \_\_| |_|\__\__,_|_| \__,_| |_| \___|\__, |___/ |_| |_|\___/ \__,_|\__,_|_|\___| \n\ 72 | __/ | \n\ 73 | |___/ \n" 74 | 75 | pegs_create['menu'] = [ 76 | {"Pegs Module Readme": tuilib.readme_tui}, 77 | {"Create a Pegs assetchain": tuilib.pegs_create_tui}, 78 | {"Run oraclefeed": tuilib.oraclefeed_tui}, 79 | {"Return to Antara modules menu": tuilib.exit_main}, 80 | {"Exit TUI": tuilib.exit} 81 | ] 82 | pegs_create['author'] = 'Welcome to the Pegs Creation TUI!\n"CLI version 0.2 by Thorn Mennet\n' 83 | 84 | 85 | 86 | gw_create = {} 87 | gw_create['header'] = "\ 88 | _ _____ _ __ __ _ _ \n\ 89 | /\ | | / ____| | | | \/ | | | | | \n \ 90 | / \ _ __ | |_ __ _ _ __ __ _ | | __ __ _| |_ _____ ____ _ _ _ ___ | \ / | ___ __| |_ _| | ___ \n \ 91 | / /\ \ | '_ \| __/ _` | '__/ _` | | | |_ |/ _` | __/ _ \ \ /\ / / _` | | | / __| | |\/| |/ _ \ / _` | | | | |/ _ \ \n \ 92 | / ____ \| | | | || (_| | | | (_| | | |__| | (_| | || __/\ V V / (_| | |_| \__ \ | | | | (_) | (_| | |_| | | __/ \n \ 93 | /_/ \_\_| |_|\__\__,_|_| \__,_| \_____|\__,_|\__\___| \_/\_/ \__,_|\__, |___/ |_| |_|\___/ \__,_|\__,_|_|\___| \n \ 94 | __/ | \n \ 95 | |___/ \n " 96 | 97 | 98 | gw_create['menu'] = [ 99 | {"Check current connection": tuilib.getinfo_tui}, 100 | {"Check mempool": tuilib.print_mempool}, 101 | {"Create token": tuilib.token_create_tui}, 102 | {"Create oracle": tuilib.oracle_create_tui}, 103 | {"Register as publisher for oracle": tuilib.oracle_register_tui}, 104 | {"Subscribe on oracle (+UTXO generator)": tuilib.oracle_subscription_utxogen}, 105 | {"Bind Gateway": tuilib.gateways_bind_tui}, 106 | {"Return to Antara modules menu": tuilib.exit_main}, 107 | {"Exit TUI": tuilib.exit} 108 | ] 109 | gw_create['author'] = 'Welcome to the Gateways Creation TUI!\n"CLI version 0.2 by Anton Lysakov & Thorn Mennet\n' 110 | 111 | 112 | gw_use = {} 113 | gw_use['header'] = "\ 114 | _ _____ _ __ __ _ _ \n\ 115 | /\ | | / ____| | | | \/ | | | | | \n \ 116 | / \ _ __ | |_ __ _ _ __ __ _ | | __ __ _| |_ _____ ____ _ _ _ ___ | \ / | ___ __| |_ _| | ___ \n \ 117 | / /\ \ | '_ \| __/ _` | '__/ _` | | | |_ |/ _` | __/ _ \ \ /\ / / _` | | | / __| | |\/| |/ _ \ / _` | | | | |/ _ \ \n \ 118 | / ____ \| | | | || (_| | | | (_| | | |__| | (_| | || __/\ V V / (_| | |_| \__ \ | | | | (_) | (_| | |_| | | __/ \n \ 119 | /_/ \_\_| |_|\__\__,_|_| \__,_| \_____|\__,_|\__\___| \_/\_/ \__,_|\__, |___/ |_| |_|\___/ \__,_|\__,_|_|\___| \n \ 120 | __/ | \n \ 121 | |___/ \n " 122 | 123 | gw_use['menu'] = [ 124 | {"Check connection to assetchain": tuilib.getinfo_tui}, 125 | {"Check assetchain mempool": tuilib.print_mempool}, 126 | {"Check connection to KMD": tuilib.getinfo_tui}, 127 | {"Connect to KMD daemon": tuilib.rpc_kmd_connection_tui}, 128 | {"View assetchain Gateway Info": tuilib.gateway_info_tui}, 129 | {"Send KMD gateway deposit transaction": tuilib.gateways_send_kmd}, 130 | {"Execute gateways deposit": tuilib.gateways_deposit_tui}, 131 | {"Execute gateways claim": tuilib.gateways_claim_tui}, 132 | {"Execute gateways withdrawal": tuilib.gateways_withdrawal_tui}, 133 | {"Return to Antara modules menu": tuilib.exit_main}, 134 | {"Exit TUI": tuilib.exit} 135 | ] 136 | gw_use['author'] = 'Welcome to the Gateways Creation TUI!\n"CLI version 0.2 by Anton Lysakov & Thorn Mennet\n' 137 | 138 | payments = {} 139 | payments['header'] = "\ 140 | _ _____ _ __ __ _ _ \n\ 141 | /\ | | | __ \ | | | \/ | | | | | \n\ 142 | / \ _ __ | |_ __ _ _ __ __ _ | |__) |_ _ _ _ _ __ ___ ___ _ __ | |_ ___ | \ / | ___ __| |_ _| | ___ \n\ 143 | / /\ \ | '_ \| __/ _` | '__/ _` | | ___/ _` | | | | '_ ` _ \ / _ \ '_ \| __/ __| | |\/| |/ _ \ / _` | | | | |/ _ \ \n\ 144 | / ____ \| | | | || (_| | | | (_| | | | | (_| | |_| | | | | | | __/ | | | |_\__ \ | | | | (_) | (_| | |_| | | __/ \n\ 145 | /_/ \_\_| |_|\__\__,_|_| \__,_| |_| \__,_|\__, |_| |_| |_|\___|_| |_|\__|___/ |_| |_|\___/ \__,_|\__,_|_|\___| \n\ 146 | __/ | \n\ 147 | |___/ \n" 148 | 149 | payments['menu'] = [ 150 | {"Check current connection": tuilib.getinfo_tui}, 151 | {"Check mempool": tuilib.print_mempool}, 152 | {"View Payments contracts": tuilib.payments_info}, 153 | {"Create Payments contract": tuilib.payments_create}, 154 | {"Fund Payments contract": tuilib.payments_fund}, 155 | {"Merge Payments contract funds": tuilib.payments_merge}, 156 | {"Release Payments contract funds": tuilib.payments_release}, 157 | {"Return to Antara modules menu": tuilib.exit_main}, 158 | {"Exit TUI": tuilib.exit} 159 | ] 160 | payments['author'] = '"Welcome to the Payments Module TUI!\n"CLI version 0.2 by Thorn Mennet\n' 161 | 162 | antara = {} 163 | antara['header'] = "\ 164 | _ _____ _ _ _ __ __ _ _ \n\ 165 | /\ | | / ____| | | | | (_) | \/ | | | | | \n\ 166 | / \ _ __ | |_ __ _ _ __ __ _ | (___ _ __ ___ __ _ _ __| |_ ___| |__ __ _ _ _ __ | \ / | ___ __| |_ _| | ___ ___ \n\ 167 | / /\ \ | '_ \| __/ _` | '__/ _` | \___ \| '_ ` _ \ / _` | '__| __/ __| '_ \ / _` | | '_ \ | |\/| |/ _ \ / _` | | | | |/ _ \/ __| \n\ 168 | / ____ \| | | | || (_| | | | (_| | ____) | | | | | | (_| | | | || (__| | | | (_| | | | | | | | | | (_) | (_| | |_| | | __/\__ \ \n\ 169 | /_/ \_\_| |_|\__\__,_|_| \__,_| |_____/|_| |_| |_|\__,_|_| \__\___|_| |_|\__,_|_|_| |_| |_| |_|\___/ \__,_|\__,_|_|\___||___/ \n" 170 | 171 | antara['menu'] = [ 172 | {"Oracles": oracles}, 173 | {"Gateways Creation": gw_create}, 174 | {"Gateways Usage": gw_use}, 175 | {"Pegs Creation": pegs_create}, 176 | {"Pegs Usage": pegs_usage}, 177 | {"Payments": payments}, 178 | {"Exit TUI": tuilib.exit} 179 | ] 180 | antara['author'] = "Welcome to the Antara Modules TUI!\nCLI version 0.2 by Anton Lysakov & Thorn Mennet\n" 181 | 182 | 183 | 184 | ac_rpc_options = [] 185 | main_menu_options = ["Oracles", "Gateways Creation", "Gateways Usage", "Pegs Creation", "Pegs Usage", "Payments"] 186 | kmd_ac_rpc_options = ["Deposit KMD in Gateway and claim Tokens"] 187 | kmd_rpc_options = ["Check connection to KMD", "Send KMD gateway deposit transaction", "Execute gateways deposit"] 188 | kmd_connect_options = ["Connect to KMD daemon"] 189 | no_param_options = ["Exit TUI"] 190 | # TODO: add more readme docs 191 | docs_options = ["Pegs Module Readme"] 192 | readme_files = ['docs/pegs_module.md'] 193 | def submenu(menu): 194 | menuItems = menu['menu'] 195 | while True: 196 | os.system('clear') 197 | print(tuilib.colorize(menu['header'], 'blue')) 198 | print(tuilib.colorize(menu['author'], 'green')) 199 | for item in menuItems: 200 | print(tuilib.colorize("[" + str(menuItems.index(item)) + "] ", 'blue') + list(item.keys())[0]) 201 | choice = input(">> ") 202 | try: 203 | if int(choice) < 0: 204 | raise ValueError 205 | if list(menuItems[int(choice)].keys())[0] == "Return to Antara modules menu": 206 | submenu(antara) 207 | elif list(menuItems[int(choice)].keys())[0] in main_menu_options: 208 | submenu(list(menuItems[int(choice)].values())[0]) 209 | elif list(menuItems[int(choice)].keys())[0] in no_param_options: 210 | list(menuItems[int(choice)].values())[0]() 211 | elif list(menuItems[int(choice)].keys())[0] in docs_options: 212 | index = docs_options.index(list(menuItems[int(choice)].keys())[0]) 213 | list(menuItems[int(choice)].values())[0](readme_files[index]) 214 | elif list(menuItems[int(choice)].keys())[0] in kmd_connect_options: 215 | rpc_connection_kmd = list(menuItems[int(choice)].values())[0]() 216 | elif list(menuItems[int(choice)].keys())[0] in kmd_rpc_options: 217 | while True: 218 | try: 219 | list(menuItems[int(choice)].values())[0](rpc_connection_kmd) 220 | break 221 | except Exception as e: 222 | print("Please connect to KMD daemon first!") 223 | input("Press [Enter] to continue...") 224 | break 225 | elif list(menuItems[int(choice)].keys())[0] in kmd_ac_rpc_options: 226 | while True: 227 | try: 228 | list(menuItems[int(choice)].values())[0](rpc_connection, rpc_connection_kmd) 229 | break 230 | except Exception as e: 231 | print(e) 232 | print("Please connect to KMD daemon first!") 233 | input("Press [Enter] to continue...") 234 | break 235 | else: 236 | list(menuItems[int(choice)].values())[0](rpc_connection) 237 | except (ValueError, IndexError): 238 | pass 239 | 240 | def main(): 241 | menuItems = antara['menu'] 242 | while True: 243 | os.system('clear') 244 | print(tuilib.colorize(antara['header'], 'blue')) 245 | print(tuilib.colorize(antara['author'], 'green')) 246 | for item in menuItems: 247 | print(tuilib.colorize("[" + str(menuItems.index(item)) + "] ", 'blue') + list(item.keys())[0]) 248 | choice = input(">> ") 249 | try: 250 | if int(choice) < 0: 251 | raise ValueError 252 | # Call the matching function 253 | if list(menuItems[int(choice)].keys())[0] == "Exit TUI": 254 | list(menuItems[int(choice)].values())[0]() 255 | else: 256 | submenu(list(menuItems[int(choice)].values())[0]) 257 | except (ValueError, IndexError): 258 | pass 259 | 260 | 261 | if __name__ == "__main__": 262 | while True: 263 | try: 264 | info = rpclib.getinfo(rpc_connection) 265 | chain = info['name'] 266 | if "pubkey" in info.keys(): 267 | print("Pubkey is already set") 268 | else: 269 | valid_address = rpc_connection.getaccountaddress("") 270 | print(valid_address) 271 | valid_pubkey = rpc_connection.validateaddress(valid_address)["pubkey"] 272 | print(valid_pubkey) 273 | rpc_connection.setpubkey(valid_pubkey) 274 | print(tuilib.colorize("Pubkey is succesfully set!", "green")) 275 | except Exception as e: 276 | try: 277 | print(antara['author']) 278 | rpc_connection = tuilib.rpc_connection_tui() 279 | except Exception as e: 280 | print(e) 281 | print(tuilib.colorize("Cant connect to RPC! Please re-check credentials and make sure smartchain is running.", "red")) 282 | pass 283 | pass 284 | else: 285 | print(tuilib.colorize("Succesfully connected to "+chain+" smartchain!\n", "green")) 286 | time.sleep(1.6) 287 | with (open("lib/logo.txt", "r")) as logo: 288 | for line in logo: 289 | parts = line.split(' ') 290 | row = '' 291 | for part in parts: 292 | if part.find('.') == -1: 293 | row += tuilib.colorize(part, 'blue') 294 | else: 295 | row += tuilib.colorize(part, 'black') 296 | print(row, end='') 297 | #print(line, end='') 298 | time.sleep(0.04) 299 | time.sleep(0.4) 300 | print("\n") 301 | break 302 | main() 303 | -------------------------------------------------------------------------------- /prices_app_v2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import dash 4 | from dash.dependencies import Input, Output, State 5 | import dash_core_components as dcc 6 | import dash_html_components as html 7 | import dash_table 8 | import dash_auth 9 | import configparser 10 | 11 | import qrcode 12 | import qrcode.image.svg 13 | 14 | import flask 15 | import pandas as pd 16 | import time 17 | import os, sys 18 | 19 | from lib import tuilib, visualization_lib 20 | from os import listdir 21 | from os.path import isfile, join 22 | 23 | def make_qr(qr_data, img_name='qrcode', method='basic'): 24 | if method == 'basic': 25 | # Simple factory, just a set of rects. 26 | factory = qrcode.image.svg.SvgImage 27 | elif method == 'fragment': 28 | # Fragment factory (also just a set of rects) 29 | factory = qrcode.image.svg.SvgFragmentImage 30 | elif method == 'path': 31 | # Combined path factory, fixes white space that may occur when zooming 32 | factory = qrcode.image.svg.SvgPathImage 33 | # Set data to qrcode 34 | img = qrcode.make(qr_data, image_factory = factory) 35 | # Save svg file somewhere 36 | filename = "static/"+img_name+".svg" 37 | img.save(filename) 38 | return filename 39 | 40 | def config(filename, section): 41 | parser = configparser.RawConfigParser() 42 | conf_file = (os.path.join(os.getcwd(),filename)) 43 | parser.read(conf_file) 44 | config_params = {} 45 | if parser.has_section(section): 46 | params = parser.items(section) 47 | for param in params: 48 | config_params[param[0]] = param[1] 49 | return config_params 50 | 51 | auth_data = config('dash.ini','auth') 52 | 53 | VALID_USERNAME_PASSWORD_PAIRS = [ 54 | [ auth_data['user'], auth_data['pass'] ] 55 | ] 56 | 57 | AC_NAME = "CFEKBET1" 58 | 59 | # connection to assetchain 60 | rpc_connection = tuilib.def_credentials(AC_NAME) 61 | 62 | account_address = rpc_connection.getaccountaddress("") 63 | print(account_address) 64 | 65 | server = flask.Flask('app') 66 | server.secret_key = os.environ.get('secret_key', 'secret') 67 | 68 | # pre-creating needed csv files on user side 69 | visualization_lib.create_prices_csv(rpc_connection, "300") 70 | visualization_lib.create_delayed_prices_csv(rpc_connection, "155") 71 | visualization_lib.create_csv_with_bets(rpc_connection, "open") 72 | visualization_lib.create_csv_with_bets(rpc_connection, "closed") 73 | 74 | # pre-creating tickers for graph 75 | pair_names = visualization_lib.get_pairs_names(rpc_connection) 76 | options_arg = [] 77 | for pair in pair_names: 78 | pair_arg = {} 79 | pair_arg['label'] = pair 80 | pair_arg['value'] = pair 81 | options_arg.append(pair_arg) 82 | 83 | user_args = [] 84 | graphs_files_list = [f for f in listdir('usergraphs') if isfile(join('usergraphs', f))] 85 | for file in graphs_files_list: 86 | file_arg = {} 87 | file_arg['label'] = file 88 | file_arg['value'] = file 89 | user_args.append(file_arg) 90 | 91 | # and load it into dash to draw graphs and etc 92 | df = pd.read_csv('prices.csv') 93 | df2 = pd.read_csv('delayed_prices.csv') 94 | df3 = pd.read_csv('betlist.csv') 95 | df4 = pd.read_csv('betlist_history.csv') 96 | 97 | # amount of records per table page 98 | PAGE_SIZE = 15 99 | 100 | # application object 101 | app = dash.Dash(__name__, server=server, static_folder='static') 102 | auth = dash_auth.BasicAuth( 103 | app, 104 | VALID_USERNAME_PASSWORD_PAIRS 105 | ) 106 | 107 | # init configuration, second param allow to make dynamic callbacks 108 | app.css.config.serve_locally = True 109 | app.scripts.config.serve_locally = True 110 | app.config['suppress_callback_exceptions'] = True 111 | 112 | # static layout 113 | app.layout = html.Div([ 114 | html.Link(href='/static/undo-redo.css', rel='stylesheet'), 115 | html.Title("PricesCC trading web-interface"), 116 | html.H5("Pairs from prices RPC call:"), 117 | dcc.Dropdown( 118 | id='my-dropdown', 119 | options=options_arg, 120 | value='BTC_USD'), 121 | html.H5("User custom prices:"), 122 | dcc.Dropdown( 123 | id='user-dropdown', 124 | options=user_args, 125 | value=user_args[0]["value"]), 126 | dcc.Input( 127 | placeholder='Input synthetic for custom graph...', 128 | type='text', 129 | value='', 130 | id='graph_synthetic', 131 | style={'marginBottom': 15, 'marginTop': 10} 132 | ), 133 | html.Button('Build custom price', id='graph_build_button', style={'marginBottom': 25}), 134 | dcc.Loading(dcc.Graph(id='my-graph')), 135 | html.Br(), 136 | dcc.Tabs(id="tabs", value='tab-1', children=[ 137 | # positions constructor, user should be able to see balance 138 | dcc.Tab(label='Open position', value='tab-1'), 139 | # active positions, user should be able to see position details and add funding 140 | dcc.Tab(label='Active positions', value='tab-2'), 141 | # history with closed positions 142 | dcc.Tab(label='Closed positions (history)', value='tab-3'), 143 | # Account deposit / withdraw 144 | dcc.Tab(label='Manage Account', value='tab-4'), 145 | ]), 146 | html.Div(id='tabs-content'), 147 | ], className="container") 148 | 149 | 150 | # custom price creation callback, as result updating dropdown 151 | @app.callback(Output('user-dropdown', 'options'), [Input('graph_build_button', 'n_clicks')], 152 | [State('graph_synthetic', 'value')]) 153 | def create_custom_price(n_clicks, synthetic): 154 | if n_clicks is not None and n_clicks > 0: 155 | synthetic_elems = synthetic.split(",") 156 | synthetic_elems = list(map(str.strip, synthetic_elems)) 157 | visualization_lib.make_csv_for_stack(rpc_connection, synthetic_elems, synthetic.strip(), "725") 158 | user_args = [] 159 | graphs_files_list = [f for f in listdir('usergraphs') if isfile(join('usergraphs', f))] 160 | for file in graphs_files_list: 161 | file_arg = {} 162 | file_arg['label'] = file 163 | file_arg['value'] = file 164 | user_args.append(file_arg) 165 | return user_args 166 | 167 | # getting data from blockchain and rendering graph 168 | @app.callback(Output('my-graph', 'figure'), 169 | [Input('my-dropdown', 'value'), Input('user-dropdown', 'value')]) 170 | def update_graph(selected_dropdown_value, user_dropdown_value): 171 | # TODO: there is a not comfortable moment: when choosing user graph in dropdown - cant back to not user one (it's because of this check) 172 | # so have to clear user graph selection by cross 173 | if user_dropdown_value is not None and "_user" in user_dropdown_value: 174 | df = pd.read_csv(sys.path[0] +'/usergraphs/'+ user_dropdown_value) 175 | #print(df['pair']) 176 | dff = df[df['pair'] == user_dropdown_value[:-5]] 177 | #print(dff) 178 | else: 179 | visualization_lib.create_prices_csv(rpc_connection, "300") 180 | visualization_lib.create_delayed_prices_csv(rpc_connection, "155") 181 | df = pd.read_csv('prices.csv') 182 | df2 = pd.read_csv('delayed_prices.csv') 183 | dff = df[df['pair'] == selected_dropdown_value] 184 | dff2 = df2[df2['pair'] == selected_dropdown_value] 185 | return { 186 | 'data': [ 187 | 188 | { 189 | 'x': dff.date, 190 | 'y': dff.price1, 191 | 'line': { 192 | 'width': 3, 193 | 'shape': 'spline' 194 | } 195 | }, 196 | 197 | { 198 | 'x': dff.date, 199 | 'y': dff.price2, 200 | 'line': { 201 | 'width': 3, 202 | 'shape': 'spline' 203 | } 204 | }, 205 | 206 | { 207 | 'x': dff.date, 208 | 'y': dff.price3, 209 | 'line': { 210 | 'width': 3, 211 | 'shape': 'spline' 212 | } 213 | }, 214 | # { 215 | # 'x': dff2.date, 216 | # 'y': dff.price3, 217 | # 'line': { 218 | # 'width': 3, 219 | # 'shape': 'spline' 220 | # } 221 | # } 222 | ], 223 | 'layout': { 224 | 'margin': { 225 | 'l': 30, 226 | 'r': 20, 227 | 'b': 30, 228 | #'t': 20 229 | }, 230 | 'title': 'Prices provided by Komodo PricesCC trustless oracle' 231 | } 232 | } 233 | 234 | # loading local static files from static dir 235 | @app.server.route('/assets/') 236 | def static_file(path): 237 | static_folder = os.path.join(os.getcwd(), 'static') 238 | return flask.send_from_directory(static_folder, path) 239 | 240 | 241 | # tabs content rendering 242 | @app.callback(Output('tabs-content', 'children'), 243 | [Input('tabs', 'value')]) 244 | def render_content(tab): 245 | # tab 1 is bets constructor 246 | if tab == 'tab-1': 247 | balance = rpc_connection.getbalance() 248 | unconfirmed = rpc_connection.getunconfirmedbalance() 249 | if unconfirmed > 0: 250 | bal_string = str(balance)+" "+AC_NAME+" ("+str(unconfirmed)+" unconfirmed)" 251 | else: 252 | bal_string = str(balance) 253 | # left side of first tab 254 | return html.Div([ 255 | html.Br(), 256 | html.H5('User balance: ' + bal_string), 257 | html.H5('Address: ' + account_address), 258 | html.Div(id='output-container-button', 259 | children='Enter values and press submit', style={'marginBottom': 5, 'marginTop': 5, 'font-size': '16px'}), 260 | dcc.Input( 261 | placeholder='Input bet amount...', 262 | type='text', 263 | value='', 264 | id='betamount_text', 265 | style={'marginBottom': 10, 'marginTop': 10} 266 | ), 267 | html.Br(), 268 | dcc.Input( 269 | placeholder='Input leverage...', 270 | type='text', 271 | value='', 272 | id='leverage_text', 273 | style={'marginBottom': 10, 'marginTop': 10} 274 | ), 275 | html.Br(), 276 | dcc.Input( 277 | placeholder='Input synthetic...', 278 | type='text', 279 | value='', 280 | id='synthetic_text', 281 | style={'marginBottom': 15, 'marginTop': 10} 282 | ), 283 | html.Br(), 284 | html.Button('Open position', id='button', style={'marginBottom': 25})], style={'width': '50%', 'float': 'left'}),\ 285 | html.Div([html.Div(id='daemon_output', 286 | children='Daemon output print', style={'marginBottom': 10, 'marginTop': 15})], style={'width': '50%', 'float': 'right'}) 287 | # tab 2 displaying active positions with possibility to add leverage or close it 288 | elif tab == 'tab-2': 289 | balance = rpc_connection.getbalance() 290 | unconfirmed = rpc_connection.getunconfirmedbalance() 291 | if unconfirmed > 0: 292 | bal_string = str(balance)+" "+AC_NAME+" ("+str(unconfirmed)+" unconfirmed)" 293 | else: 294 | bal_string = str(balance) 295 | visualization_lib.create_csv_with_bets(rpc_connection, "open") 296 | df3 = pd.read_csv('betlist.csv') 297 | return html.Div([ 298 | html.H5('User balance: ' + bal_string), 299 | html.H5('Address: ' + account_address), 300 | dash_table.DataTable( 301 | id='table', 302 | columns=[{"name": i, "id": i} for i in df3.columns], 303 | data=df3.to_dict("rows"), 304 | sorting=True, 305 | row_selectable='single', 306 | selected_rows=[], 307 | style_cell={ 308 | 'minWidth': '0px', 'maxWidth': '240px', 309 | 'whiteSpace': 'normal' 310 | }, 311 | css=[{ 312 | 'selector': '.dash-cell div.dash-cell-value', 313 | 'rule': 'display: inline; white-space: inherit; overflow: inherit; text-overflow: inherit;' 314 | }], 315 | pagination_settings={ 316 | 'current_page': 0, 317 | 'page_size': PAGE_SIZE, 318 | } 319 | ), 320 | html.H5("Select position to add funding or close it"), 321 | html.Div(id='position-select-container', children='', style={'marginBottom': 10, 'marginTop': 15}), 322 | dcc.Input( 323 | placeholder='Input funding...', 324 | type='text', 325 | value='', 326 | id='funding_text', 327 | style={'marginBottom': 10, 'marginTop': 10} 328 | ), 329 | html.Button('Add funding', id='funding-button'), 330 | html.Button('Cashout position', id='close-button', style={'marginBottom': 100}), 331 | html.Div(id='position-closing-output', style={'width': '50%', 'float': 'right'}), 332 | html.Div([html.Div(id='daemon_output2', 333 | children='Daemon output print', style={'marginBottom': 10, 'marginTop': 15})], 334 | style={'width': '50%', 'float': 'right'}) 335 | ]) 336 | # tab 3 displaying bet history (closed bets) 337 | elif tab == 'tab-3': 338 | visualization_lib.create_csv_with_bets(rpc_connection, "closed") 339 | df4 = pd.read_csv('betlist_history.csv') 340 | return html.Div([ 341 | dash_table.DataTable( 342 | id='table_history', 343 | columns=[{"name": i, "id": i} for i in df4.columns], 344 | data=df4.to_dict("rows"), 345 | sorting=True, 346 | selected_rows=[], 347 | style_cell={ 348 | 'minWidth': '0px', 'maxWidth': '320px', 349 | 'whiteSpace': 'normal' 350 | }, 351 | css=[{ 352 | 'selector': '.dash-cell div.dash-cell-value', 353 | 'rule': 'display: inline; white-space: inherit; overflow: inherit; text-overflow: inherit;' 354 | }], 355 | pagination_settings={ 356 | 'current_page': 0, 357 | 'page_size': PAGE_SIZE, 358 | } 359 | ) 360 | ]) 361 | # tab 4 deposit/withdraw funds 362 | elif tab == 'tab-4': 363 | #visualization_lib.create_csv_with_accounttx(rpc_connection, "closed") 364 | #df4 = pd.read_csv('account_history.csv') 365 | balance = rpc_connection.getbalance() 366 | unconfirmed = rpc_connection.getunconfirmedbalance() 367 | if unconfirmed > 0: 368 | bal_string = str(balance)+" "+AC_NAME+" ("+str(unconfirmed)+" unconfirmed)" 369 | else: 370 | bal_string = str(balance) 371 | return html.Div([ 372 | html.Br(), 373 | html.H5('Scan QR Code or copy address to send funds',style={'margin': 'auto'}), 374 | html.Img(id='qr_img', src=make_qr(account_address),style={'margin': 'auto'}), 375 | html.H5('User balance: ' + bal_string,style={'margin': 'auto'}), 376 | html.H5('Address: ' + account_address,style={'margin': 'auto'}), 377 | dcc.Input( 378 | placeholder='Input withdrawal address', 379 | type='text', 380 | value='', 381 | id='withdraw_address', 382 | style={'marginBottom': 10, 'marginTop': 10} 383 | ), 384 | dcc.Input( 385 | placeholder='Input withdrawal amount...', 386 | type='text', 387 | value='', 388 | id='withdraw_amount', 389 | style={'marginBottom': 10, 'marginTop': 10} 390 | ), 391 | html.Br(), 392 | html.Button('Withdraw', id='withdraw-button', style={'marginBottom': 25})], style={'width': '50%', 'float': 'left'}),\ 393 | html.Div([html.Div(id='daemon_output4', 394 | children='Daemon output print', style={'marginBottom': 10, 'marginTop': 15})], style={'width': '50%', 'float': 'right'}) 395 | 396 | 397 | # bet placing button callback 398 | @app.callback(Output('daemon_output', 'children'), [Input('button', 'n_clicks')], 399 | [State('betamount_text', 'value'), State('leverage_text', 'value'), State('synthetic_text', 'value')]) 400 | #TODO: have to add confirmation popup 401 | def on_click(n_clicks, betamount, leverage, synthetic): 402 | try: 403 | if n_clicks > 0: 404 | daemon_output = rpc_connection.pricesbet(betamount, leverage, synthetic) 405 | try: 406 | position_txid = rpc_connection.sendrawtransaction(daemon_output['hex']) 407 | return str(daemon_output) + "\n transaction broadcasted: " + str(position_txid) 408 | except KeyError: 409 | return str(daemon_output) + "\n transaction not broadcasted, please check error above" 410 | else: 411 | pass 412 | except TypeError: 413 | pass 414 | 415 | # callback on radio select on tab2 416 | @app.callback( 417 | Output('position-select-container','children'), 418 | [Input('table', 'derived_virtual_data'), 419 | Input('table', 'derived_virtual_selected_rows')]) 420 | def update_position_selection(rows,derived_virtual_selected_rows): 421 | if derived_virtual_selected_rows is None: 422 | derived_virtual_selected_rows = [] 423 | if rows is None: 424 | dff3 = df3 425 | else: 426 | dff3 = pd.DataFrame(rows) 427 | try: 428 | active_row_txid = dff3['txid'][derived_virtual_selected_rows[0]] 429 | return html.Div([ 430 | html.H5("Selected position: " + active_row_txid), 431 | html.Div(id='active_row_txid', children=active_row_txid, style={'display': 'none'}) 432 | ] 433 | ) 434 | except Exception as e: 435 | pass 436 | 437 | # addfunding button callback 438 | @app.callback(Output('daemon_output2', 'children'), [Input('funding-button', 'n_clicks')], 439 | [State('active_row_txid', 'children'),State('funding_text', 'value')]) 440 | #TODO: have to add confirmation popup 441 | def on_click(n_clicks, txid, funding_amount): 442 | if n_clicks > 0: 443 | daemon_output = rpc_connection.pricesaddfunding(str(txid), str(funding_amount)) 444 | try: 445 | position_txid = rpc_connection.sendrawtransaction(daemon_output['hex']) 446 | return str(daemon_output) + "\n transaction broadcasted: " + str(position_txid) 447 | except KeyError: 448 | return str(daemon_output) + "\n transaction not broadcasted, please check error above" 449 | else: 450 | pass 451 | 452 | 453 | # closeposition button callback 454 | @app.callback(Output('position-closing-output', 'children'), [Input('close-button', 'n_clicks')], 455 | [State('active_row_txid', 'children')]) 456 | #TODO: have to add confirmation popup 457 | def on_click(n_clicks, txid): 458 | if n_clicks > 0: 459 | daemon_output = rpc_connection.pricessetcostbasis(str(txid)) 460 | try: 461 | costbasis_txid = rpc_connection.sendrawtransaction(daemon_output['hex']) 462 | finally: 463 | daemon_output = rpc_connection.pricescashout(str(txid)) 464 | try: 465 | cashout_txid = rpc_connection.sendrawtransaction(daemon_output['hex']) 466 | return str(daemon_output) + "\n transaction broadcasted: " + str(cashout_txid) 467 | except KeyError: 468 | return str(daemon_output) + "\n transaction not broadcasted, please check error above" 469 | else: 470 | pass 471 | 472 | # withdraw button callback 473 | @app.callback(Output('daemon_output4', 'children'), [Input('withdraw-button', 'n_clicks')], 474 | [State('withdraw_address', 'value'),State('withdraw_amount', 'value')]) 475 | #TODO: have to add confirmation popup 476 | def on_click(n_clicks, withdraw_address, withdraw_amount): 477 | if n_clicks > 0: 478 | if rpc_connection.validateaddress(withdraw_address)['isvalid'] is True: 479 | if withdraw_amount.isnumeric() and float(withdraw_amount) > 0.001 and float(withdraw_amount) < rpc_connection.getbalance(): 480 | try: 481 | daemon_output = rpc_connection.sendtoaddress(withdraw_address, str(withdraw_amount), "", "", True) 482 | return "Transaction broadcasted: " + str(daemon_output) 483 | except KeyError: 484 | return str(daemon_output) + "\n transaction not broadcasted, please check error above" 485 | pass 486 | else: 487 | return "Invalid Amount! Try again?" 488 | else: 489 | return "Invalid Address! Try again?" 490 | else: 491 | pass 492 | print(daemon_output) 493 | if __name__ == '__main__': 494 | app.run_server(host = '0.0.0.0', port=777) 495 | --------------------------------------------------------------------------------