new MoneroWalletDaemon, MoneroWalletRPCConnection classes

This commit is contained in:
The MMGen Project 2020-02-12 10:38:26 +00:00
commit 779f522d16
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
5 changed files with 106 additions and 0 deletions

View file

@ -84,6 +84,15 @@
# Set the Ethereum testnet name
# eth_testnet_chain_name kovan
# Set the Monero wallet RPC host:
# monero_wallet_rpc_host localhost
# Set the Monero wallet RPC username:
# monero_wallet_rpc_user monero
# Set the Monero wallet RPC password to something secure:
# monero_wallet_rpc_password passw0rd
#####################################################################
# The following options are probably of interest only to developers #
#####################################################################

View file

@ -137,6 +137,61 @@ class Daemon(MMGenObject):
for k in cls.subclasses_must_implement:
assert k in subcls.__dict__, m.format(k,subcls.__name__)
class MoneroWalletDaemon(Daemon):
desc = 'RPC daemon'
net_desc = 'Monero wallet'
daemon_id = 'xmr'
network = 'wallet RPC'
def __init__(self,wallet_dir,test_suite=False):
self.platform = g.platform
self.wallet_dir = wallet_dir
if test_suite:
self.datadir = os.path.join('test','monero-wallet-rpc')
self.rpc_port = 13142
else:
self.datadir = 'monero-wallet-rpc'
self.rpc_port = 13131
self.daemon_port = CoinDaemon('xmr',test_suite=test_suite).rpc_port
self.pidfile = os.path.join(self.datadir,'monero-wallet-rpc.pid')
self.logfile = os.path.join(self.datadir,'monero-wallet-rpc.log')
if not g.monero_wallet_rpc_password:
die(1,
'You must set your Monero wallet RPC password.\n' +
'This can be done on the command line, with the --monero-wallet-rpc-password\n' +
"option (insecure, not recommended), or by setting 'monero_wallet_rpc_password'\n" +
"in the MMGen config file." )
@property
def start_cmd(self):
return ['monero-wallet-rpc',
'--daemon-port={}'.format(self.daemon_port),
'--rpc-bind-port={}'.format(self.rpc_port),
'--wallet-dir='+self.wallet_dir,
'--detach',
'--log-file='+self.logfile,
'--rpc-login={}:{}'.format(g.monero_wallet_rpc_user,g.monero_wallet_rpc_password),
'--pidfile='+self.pidfile]
@property
def state(self):
from mmgen.rpc import MoneroWalletRPCConnection
try:
MoneroWalletRPCConnection(
g.monero_wallet_rpc_host,
self.rpc_port,
g.monero_wallet_rpc_user,
g.monero_wallet_rpc_password).get_version()
return 'ready'
except:
return 'stopped'
@property
def stop_cmd(self):
return ['kill','-Wf',self.pid] if self.platform == 'win' else ['kill',self.pid]
class CoinDaemon(Daemon):
cfg_file_hdr = ''
subclasses_must_implement = ('state','stop_cmd')

View file

@ -92,6 +92,9 @@ class g(object):
rpc_port = 0
rpc_user = ''
rpc_password = ''
monero_wallet_rpc_host = 'localhost'
monero_wallet_rpc_user = 'monero'
monero_wallet_rpc_password = ''
rpc_fail_on_command = ''
rpch = None # global RPC handle
use_cached_balances = False
@ -141,6 +144,7 @@ class g(object):
# 'long' opts - opt sets global var
common_opts = (
'color','no_license','rpc_host','rpc_port','testnet','rpc_user','rpc_password',
'monero_wallet_rpc_host','monero_wallet_rpc_user','monero_wallet_rpc_password',
'daemon_data_dir','force_256_color','regtest','coin','bob','alice',
'accept_defaults','token'
)
@ -162,6 +166,7 @@ class g(object):
cfg_file_opts = (
'color','debug','hash_preset','http_timeout','no_license','rpc_host','rpc_port',
'quiet','tx_fee_adj','usr_randchars','testnet','rpc_user','rpc_password',
'monero_wallet_rpc_host','monero_wallet_rpc_user','monero_wallet_rpc_password',
'daemon_data_dir','force_256_color','regtest','subseeds',
'btc_max_tx_fee','ltc_max_tx_fee','bch_max_tx_fee','eth_max_tx_fee',
'eth_mainnet_chain_name','eth_testnet_chain_name',

View file

@ -205,6 +205,9 @@ common_opts_data = {
--, --rpc-port=p Communicate with {dn} listening on port 'p'
--, --rpc-user=user Override 'rpcuser' in {pn}.conf
--, --rpc-password=pass Override 'rpcpassword' in {pn}.conf
--, --monero-wallet-rpc-host=host Override 'monero_wallet_rpc_host' in mmgen.cfg
--, --monero-wallet-rpc-user=user Override 'monero_wallet_rpc_user' in mmgen.cfg
--, --monero-wallet-rpc-password=pass Override 'monero_wallet_rpc_password' in mmgen.cfg
--, --regtest=0|1 Disable or enable regtest mode
--, --testnet=0|1 Disable or enable testnet
--, --skip-cfg-file Skip reading the configuration file

View file

@ -261,6 +261,40 @@ class EthereumRPCConnection(RPCConnection):
'parity_versionInfo',
)
class MoneroWalletRPCConnection(RPCConnection):
rpcmethods = (
'get_version',
'get_height', # sync height of the open wallet
'get_balance', # { "account_index":0,"address_indices":[0,1] }
'create_wallet', # { "filename":"name","password":"passw0rd","language":"English" }
'open_wallet', # { "filename":"name","password":"passw0rd" }
'close_wallet',
'restore_deterministic_wallet', # name,password,seed (restore_height,language,seed_offset,autosave_current)
'refresh', # {"start_height":100000}
)
def request(self,cmd,*args,**kwargs):
from subprocess import run,PIPE
data = {
'jsonrpc': '2.0',
'id': '0',
'method': cmd,
'params': kwargs,
}
exec_cmd = [
'curl', '--silent','--insecure', '--request', 'POST',
'--digest', '--user', '{}:{}'.format(g.monero_wallet_rpc_user,g.monero_wallet_rpc_password),
'--header', 'Content-Type: application/json',
'--data', json.dumps(data),
'https://{}:{}/json_rpc'.format(self.host,self.port) ]
cp = run(exec_cmd,stdout=PIPE,check=True)
res = json.loads(cp.stdout)
if 'error' in res:
raise RPCFailure(repr(res['error']))
return(res['result'])
def rpc_error(ret):
return type(ret) is tuple and ret and ret[0] == 'rpcfail'