xmrwallet.py: new MMGenMoneroTX class
This commit is contained in:
parent
2856c8f39d
commit
0bfb03105f
1 changed files with 127 additions and 38 deletions
|
|
@ -20,13 +20,14 @@
|
|||
xmrwallet.py - MoneroWalletOps class
|
||||
"""
|
||||
|
||||
import os,re
|
||||
import os,re,time
|
||||
from collections import namedtuple
|
||||
from .common import *
|
||||
from .addr import KeyAddrList,AddrIdxList
|
||||
from .rpc import MoneroRPCClientRaw, MoneroWalletRPCClient
|
||||
from .daemon import MoneroWalletDaemon
|
||||
from .protocol import _b58a
|
||||
from .protocol import _b58a,init_proto
|
||||
from .obj import CoinAddr,CoinTxID,SeedID,AddrIdx
|
||||
|
||||
xmrwallet_uarg_info = (
|
||||
lambda e,hp: {
|
||||
|
|
@ -39,6 +40,75 @@ xmrwallet_uarg_info = (
|
|||
r'(?:[^:]+):(?:\d+)'
|
||||
)
|
||||
|
||||
class MMGenMoneroTX:
|
||||
|
||||
class Base:
|
||||
|
||||
xmrwallet_tx_data = namedtuple('xmrwallet_tx_data',[
|
||||
'op',
|
||||
'time',
|
||||
'network',
|
||||
'seed_id',
|
||||
'source_idx',
|
||||
'source_account',
|
||||
'dest_idx',
|
||||
'dest_address',
|
||||
'txid',
|
||||
'amount',
|
||||
'fee',
|
||||
'blob',
|
||||
'metadata',
|
||||
])
|
||||
|
||||
def get_info(self,indent=''):
|
||||
d = self.data
|
||||
return fmt("""
|
||||
Transaction info [Seed ID: {}. Network: {}]:
|
||||
TxID: {}
|
||||
Type: {}
|
||||
From: Wallet {}, account {}{}
|
||||
Amt: {} XMR
|
||||
Fee: {} XMR
|
||||
Dest: {}
|
||||
""",strip_char='\t',indent=indent).format(
|
||||
d.seed_id.hl(), d.network.upper(),
|
||||
d.txid.hl(),
|
||||
blue(capfirst(d.op)),
|
||||
d.source_idx.hl(), red(f'#{d.source_account}'),
|
||||
(
|
||||
'' if d.op == 'transfer'
|
||||
else (
|
||||
f'\n{indent} To: ' +
|
||||
(f'Wallet {d.dest_idx.hl()}, new account' if d.dest_idx else 'Same account')
|
||||
)
|
||||
),
|
||||
d.amount.hl(),
|
||||
d.fee.hl(),
|
||||
d.dest_address.hl()
|
||||
)
|
||||
|
||||
class New(Base):
|
||||
|
||||
def __init__(self,*args,**kwargs):
|
||||
assert not args, 'Non-keyword args not permitted'
|
||||
d = self.xmrwallet_tx_data(**kwargs)
|
||||
proto = init_proto('xmr',network=d.network)
|
||||
self.data = self.xmrwallet_tx_data(
|
||||
op = d.op,
|
||||
time = int(d.time),
|
||||
network = d.network,
|
||||
seed_id = SeedID(sid=d.seed_id),
|
||||
source_idx = AddrIdx(d.source_idx),
|
||||
source_account = d.source_account,
|
||||
dest_idx = None if d.dest_idx == None else AddrIdx(d.dest_idx),
|
||||
dest_address = CoinAddr(proto,d.dest_address),
|
||||
txid = CoinTxID(d.txid),
|
||||
amount = proto.coin_amt(d.amount,from_unit='atomic'),
|
||||
fee = proto.coin_amt(d.fee,from_unit='atomic'),
|
||||
blob = d.blob,
|
||||
metadata = d.metadata,
|
||||
)
|
||||
|
||||
class MoneroWalletOps:
|
||||
|
||||
ops = ('create','sync','transfer','sweep')
|
||||
|
|
@ -86,7 +156,6 @@ class MoneroWalletOps:
|
|||
cls.check_uopts(self)
|
||||
id_cur = id(cls.check_uopts)
|
||||
|
||||
from .protocol import init_proto
|
||||
self.proto = init_proto('xmr',testnet=g.testnet)
|
||||
|
||||
def check_uopts(self):
|
||||
|
|
@ -111,8 +180,18 @@ class MoneroWalletOps:
|
|||
if getattr(uopt,opt):
|
||||
check_pat_opt(opt)
|
||||
|
||||
def display_tx_relay_info(self,indent=''):
|
||||
m = re.fullmatch(uarg_info['tx_relay_daemon'].pat,uopt.tx_relay_daemon,re.ASCII)
|
||||
msg(fmt(f"""
|
||||
TX relay info:
|
||||
Host: {blue(m[1])}
|
||||
Proxy: {blue(m[2] or 'None')}
|
||||
""",strip_char='\t',indent=indent))
|
||||
|
||||
def post_main(self): pass
|
||||
|
||||
def stop_daemons(self): pass
|
||||
|
||||
class wallet(base):
|
||||
|
||||
opts = (
|
||||
|
|
@ -176,7 +255,7 @@ class MoneroWalletOps:
|
|||
def stop_daemons(self):
|
||||
if not uopt.no_stop_wallet_daemon:
|
||||
self.wd.stop()
|
||||
if uopt.tx_relay_daemon:
|
||||
if uopt.tx_relay_daemon and hasattr(self,'wd2'):
|
||||
self.wd2.stop()
|
||||
|
||||
def get_wallet_fn(self,d):
|
||||
|
|
@ -307,20 +386,6 @@ class MoneroWalletOps:
|
|||
msg(' ' + cyan(ret))
|
||||
return ret
|
||||
|
||||
def display_tx_relay_info(self):
|
||||
msg('\n TX relay host: {}\n Proxy: {}'.format(
|
||||
blue(self.parent.wd2.daemon_addr),
|
||||
blue(self.parent.wd2.proxy or 'None')
|
||||
))
|
||||
|
||||
def display_tx(self,txid,amt,fee):
|
||||
from .obj import CoinTxID
|
||||
msg(' TxID: {}\n Amount: {}\n Fee: {}'.format(
|
||||
CoinTxID(txid).hl(),
|
||||
hl_amt(amt),
|
||||
hl_amt(fee),
|
||||
))
|
||||
|
||||
async def make_transfer_tx(self,account,addr,amt):
|
||||
res = await self.c.call(
|
||||
'transfer',
|
||||
|
|
@ -330,10 +395,24 @@ class MoneroWalletOps:
|
|||
'address': addr
|
||||
}],
|
||||
do_not_relay = True,
|
||||
get_tx_hex = True,
|
||||
get_tx_metadata = True
|
||||
)
|
||||
self.display_tx( res['tx_hash'], res['amount'], res['fee'] )
|
||||
return res['tx_metadata']
|
||||
return MMGenMoneroTX.New(
|
||||
op = uarg.op,
|
||||
time = time.time(),
|
||||
network = self.parent.proto.network,
|
||||
seed_id = self.parent.kal.al_id.sid,
|
||||
source_idx = self.parent.source.idx,
|
||||
source_account = self.parent.account,
|
||||
dest_idx = None,
|
||||
dest_address = addr,
|
||||
txid = res['tx_hash'],
|
||||
amount = res['amount'],
|
||||
fee = res['fee'],
|
||||
blob = res['tx_blob'],
|
||||
metadata = res['tx_metadata'],
|
||||
)
|
||||
|
||||
async def make_sweep_tx(self,account,addr):
|
||||
res = await self.c.call(
|
||||
|
|
@ -341,25 +420,35 @@ class MoneroWalletOps:
|
|||
address = addr,
|
||||
account_index = account,
|
||||
do_not_relay = True,
|
||||
get_tx_hex = True,
|
||||
get_tx_metadata = True
|
||||
)
|
||||
|
||||
if len(res['tx_hash_list']) > 1:
|
||||
die(3,'More than one TX required. Cannot perform this sweep')
|
||||
|
||||
self.display_tx( res['tx_hash_list'][0], res['amount_list'][0], res['fee_list'][0] )
|
||||
return res['tx_metadata_list'][0]
|
||||
|
||||
def display_txid(self,data):
|
||||
from .obj import CoinTxID
|
||||
msg('\n Relayed {}'.format( CoinTxID(data['tx_hash']).hl() ))
|
||||
return MMGenMoneroTX.New(
|
||||
op = uarg.op,
|
||||
time = time.time(),
|
||||
network = self.parent.proto.network,
|
||||
seed_id = self.parent.kal.al_id.sid,
|
||||
source_idx = self.parent.source.idx,
|
||||
source_account = self.parent.account,
|
||||
dest_idx = self.parent.dest.idx if self.parent.dest else None,
|
||||
dest_address = addr,
|
||||
txid = res['tx_hash_list'][0],
|
||||
amount = res['amount_list'][0],
|
||||
fee = res['fee_list'][0],
|
||||
blob = res['tx_blob_list'][0],
|
||||
metadata = res['tx_metadata_list'][0],
|
||||
)
|
||||
|
||||
async def relay_tx(self,tx_hex):
|
||||
ret = await self.c.call('relay_tx',hex=tx_hex)
|
||||
try:
|
||||
self.display_txid(ret)
|
||||
msg('\n Relayed {}'.format( CoinTxID(ret['tx_hash']).hl() ))
|
||||
except:
|
||||
msg('\n'+str(ret))
|
||||
msg(f'\n Server returned: {ret!s}')
|
||||
|
||||
class create(wallet):
|
||||
name = 'create'
|
||||
|
|
@ -406,7 +495,6 @@ class MoneroWalletOps:
|
|||
chain_height = (await self.dc.call('get_height'))['height']
|
||||
msg(f' Chain height: {chain_height}')
|
||||
|
||||
import time
|
||||
t_start = time.time()
|
||||
|
||||
msg_r(' Opening wallet...')
|
||||
|
|
@ -519,7 +607,6 @@ class MoneroWalletOps:
|
|||
self.account = int(m[2])
|
||||
|
||||
if self.name == 'transfer':
|
||||
from mmgen.obj import CoinAddr
|
||||
self.dest_addr = CoinAddr(self.proto,m[3])
|
||||
self.amount = self.proto.coin_amt(m[4])
|
||||
|
||||
|
|
@ -593,16 +680,19 @@ class MoneroWalletOps:
|
|||
await h2.close_wallet('destination')
|
||||
await h.open_wallet('source',refresh=False)
|
||||
|
||||
msg_r(f'\n Creating {self.name} transaction: wallet {self.source.idx}, account #{self.account}')
|
||||
msg(f'\n Creating {self.name} transaction...')
|
||||
|
||||
if self.name == 'transfer':
|
||||
msg(f', {self.amount} XMR => {cyan(new_addr)}')
|
||||
tx_metadata = await h.make_transfer_tx(self.account,new_addr,self.amount)
|
||||
new_tx = await h.make_transfer_tx(self.account,new_addr,self.amount)
|
||||
elif self.name == 'sweep':
|
||||
msg(f' => {cyan(new_addr)}')
|
||||
tx_metadata = await h.make_sweep_tx(self.account,new_addr)
|
||||
new_tx = await h.make_sweep_tx(self.account,new_addr)
|
||||
|
||||
if keypress_confirm(f'\nRelay {self.name} transaction?'):
|
||||
msg('\n' + new_tx.get_info(indent=' '))
|
||||
|
||||
if uopt.tx_relay_daemon:
|
||||
self.display_tx_relay_info(indent=' ')
|
||||
|
||||
if keypress_confirm(f'Relay {self.name} transaction?'):
|
||||
w_desc = 'source'
|
||||
if uopt.tx_relay_daemon:
|
||||
await h.close_wallet('source')
|
||||
|
|
@ -611,9 +701,8 @@ class MoneroWalletOps:
|
|||
h = self.rpc(self,self.source)
|
||||
w_desc = 'TX relay source'
|
||||
await h.open_wallet(w_desc,refresh=False)
|
||||
h.display_tx_relay_info()
|
||||
msg_r(f'\n Relaying {self.name} transaction...')
|
||||
await h.relay_tx(tx_metadata)
|
||||
await h.relay_tx(new_tx.data.metadata)
|
||||
await h.close_wallet(w_desc)
|
||||
|
||||
gmsg('\n\nAll done')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue