Skip to content

Commit ee2f462

Browse files
nahuhhtecnovert
authored andcommitted
wownero: integration
1 parent c3cd187 commit ee2f462

27 files changed

+1251
-88
lines changed

basicswap/basicswap.py

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
from . import __version__
3535
from .rpc import escape_rpcauth
3636
from .rpc_xmr import make_xmr_rpc2_func
37+
from .rpc_wow import make_wow_rpc2_func
3738
from .ui.util import getCoinName, known_chart_coins
3839
from .util import (
3940
AutomationConstraint,
@@ -180,6 +181,21 @@ def threadPollXMRChainState(swap_client, coin_type):
180181
swap_client.chainstate_delay_event.wait(random.randrange(20, 30)) # Random to stagger updates
181182

182183

184+
def threadPollWOWChainState(swap_client, coin_type):
185+
ci = swap_client.ci(coin_type)
186+
cc = swap_client.coin_clients[coin_type]
187+
while not swap_client.chainstate_delay_event.is_set():
188+
try:
189+
new_height = ci.getChainHeight()
190+
if new_height != cc['chain_height']:
191+
swap_client.log.debug('New {} block at height: {}'.format(ci.ticker(), new_height))
192+
with swap_client.mxDB:
193+
cc['chain_height'] = new_height
194+
except Exception as e:
195+
swap_client.log.warning('threadPollWOWChainState {}, error: {}'.format(ci.ticker(), str(e)))
196+
swap_client.chainstate_delay_event.wait(random.randrange(20, 30)) # Random to stagger updates
197+
198+
183199
def threadPollChainState(swap_client, coin_type):
184200
ci = swap_client.ci(coin_type)
185201
cc = swap_client.coin_clients[coin_type]
@@ -281,7 +297,7 @@ def __init__(self, fp, data_dir, settings, chain, log_name='BasicSwap', transien
281297

282298
# TODO: Set dynamically
283299
self.balance_only_coins = (Coins.LTC_MWEB, )
284-
self.scriptless_coins = (Coins.XMR, Coins.PART_ANON, Coins.FIRO)
300+
self.scriptless_coins = (Coins.XMR, Coins.WOW, Coins.PART_ANON, Coins.FIRO)
285301
self.adaptor_swap_only_coins = self.scriptless_coins + (Coins.PART_BLIND, )
286302
self.coins_without_segwit = (Coins.PIVX, Coins.DASH, Coins.NMC)
287303

@@ -523,7 +539,7 @@ def setCoinConnectParams(self, coin):
523539
if self.coin_clients[coin]['connection_type'] == 'rpc':
524540
if coin == Coins.DCR:
525541
self.coin_clients[coin]['walletrpcport'] = chain_client_settings['walletrpcport']
526-
elif coin == Coins.XMR:
542+
elif coin in (Coins.XMR, Coins.WOW):
527543
self.coin_clients[coin]['rpctimeout'] = chain_client_settings.get('rpctimeout', 60)
528544
self.coin_clients[coin]['walletrpctimeout'] = chain_client_settings.get('walletrpctimeout', 120)
529545
self.coin_clients[coin]['walletrpctimeoutlong'] = chain_client_settings.get('walletrpctimeoutlong', 600)
@@ -561,9 +577,9 @@ def getXMRWalletProxy(self, coin, node_host: str) -> (Optional[str], Optional[in
561577
if self.use_tor_proxy:
562578
have_cc_tor_opt = 'use_tor' in chain_client_settings
563579
if have_cc_tor_opt and chain_client_settings['use_tor'] is False:
564-
self.log.warning('use_tor is true for system but false for XMR.')
580+
self.log.warning('use_tor is true for system but false for ' + coin + '.')
565581
elif have_cc_tor_opt is False and is_private_ip_address(node_host):
566-
self.log.warning(f'Not using proxy for XMR node at private ip address {node_host}.')
582+
self.log.warning(f'Not using proxy for {coin} node at private ip address {node_host}.')
567583
else:
568584
proxy_host = self.tor_proxy_host
569585
proxy_port = self.tor_proxy_port
@@ -585,7 +601,10 @@ def get_rpc_func(rpcport, daemon_login, rpchost):
585601
if proxy_host:
586602
self.log.info(f'Connecting through proxy at {proxy_host}.')
587603

588-
return make_xmr_rpc2_func(rpcport, daemon_login, rpchost, proxy_host=proxy_host, proxy_port=proxy_port)
604+
if coin == Coins.XMR:
605+
return make_xmr_rpc2_func(rpcport, daemon_login, rpchost, proxy_host=proxy_host, proxy_port=proxy_port)
606+
if coin == Coins.WOW:
607+
return make_wow_rpc2_func(rpcport, daemon_login, rpchost, proxy_host=proxy_host, proxy_port=proxy_port)
589608

590609
daemon_login = None
591610
if coin_settings.get('rpcuser', '') != '':
@@ -687,6 +706,12 @@ def createInterface(self, coin):
687706
chain_client_settings = self.getChainClientSettings(coin)
688707
xmr_i.setWalletFilename(chain_client_settings['walletfile'])
689708
return xmr_i
709+
elif coin == Coins.WOW:
710+
from .interface.wow import WOWInterface
711+
wow_i = WOWInterface(self.coin_clients[coin], self.chain, self)
712+
chain_client_settings = self.getChainClientSettings(coin)
713+
wow_i.setWalletFilename(chain_client_settings['walletfile'])
714+
return wow_i
690715
elif coin == Coins.PIVX:
691716
from .interface.pivx import PIVXInterface
692717
return PIVXInterface(self.coin_clients[coin], self.chain, self)
@@ -711,7 +736,7 @@ def createPassthroughInterface(self, coin):
711736

712737
def setCoinRunParams(self, coin):
713738
cc = self.coin_clients[coin]
714-
if coin == Coins.XMR:
739+
if coin in (Coins.XMR, Coins.WOW):
715740
return
716741
if cc['connection_type'] == 'rpc' and cc['rpcauth'] is None:
717742
chain_client_settings = self.getChainClientSettings(coin)
@@ -782,8 +807,14 @@ def start(self):
782807
core_version = ci.getDaemonVersion()
783808
self.log.info('%s Core version %d', ci.coin_name(), core_version)
784809
self.coin_clients[c]['core_version'] = core_version
810+
# thread_func = threadPollXMRChainState if c in (Coins.XMR, Coins.WOW) else threadPollChainState
811+
if c == Coins.XMR:
812+
thread_func = threadPollXMRChainState
813+
elif c == Coins.WOW:
814+
thread_func = threadPollWOWChainState
815+
else:
816+
thread_func = threadPollChainState
785817

786-
thread_func = threadPollXMRChainState if c == Coins.XMR else threadPollChainState
787818
t = threading.Thread(target=thread_func, args=(self, c))
788819
self.threads.append(t)
789820
t.start()
@@ -808,6 +839,12 @@ def start(self):
808839
except Exception as e:
809840
self.log.warning('Can\'t open XMR wallet, could be locked.')
810841
continue
842+
elif c == Coins.WOW:
843+
try:
844+
ci.ensureWalletExists()
845+
except Exception as e:
846+
self.log.warning('Can\'t open WOW wallet, could be locked.')
847+
continue
811848
elif c == Coins.LTC:
812849
ci_mweb = self.ci(Coins.LTC_MWEB)
813850
is_encrypted, _ = self.getLockedState()
@@ -858,7 +895,7 @@ def start(self):
858895
self.log.info('Scanned %d unread messages.', nm)
859896

860897
def stopDaemon(self, coin) -> None:
861-
if coin in (Coins.XMR, Coins.DCR):
898+
if coin in (Coins.XMR, Coins.DCR, Coins.WOW):
862899
return
863900
num_tries = 10
864901
authcookiepath = os.path.join(self.getChainDatadirPath(coin), '.cookie')
@@ -897,7 +934,7 @@ def waitForDaemonRPC(self, coin_type, with_wallet: bool = True) -> None:
897934

898935
if with_wallet:
899936
self.waitForDaemonRPC(coin_type, with_wallet=False)
900-
if coin_type in (Coins.XMR,):
937+
if coin_type in (Coins.XMR, Coins.WOW):
901938
return
902939
ci = self.ci(coin_type)
903940
# checkWallets can adjust the wallet name.
@@ -932,7 +969,7 @@ def checkCoinsReady(self, coin_from, coin_to) -> None:
932969
raise ValueError('{} has an unexpected wallet seed and "restrict_unknown_seed_wallets" is enabled.'.format(ci.coin_name()))
933970
if self.coin_clients[c]['connection_type'] != 'rpc':
934971
continue
935-
if c == Coins.XMR:
972+
if c in (Coins.XMR, Coins.WOW):
936973
continue # TODO
937974
synced = round(ci.getBlockchainInfo()['verificationprogress'], 3)
938975
if synced < 1.0:
@@ -1035,7 +1072,7 @@ def initialiseWallet(self, coin_type, raise_errors: bool = False) -> None:
10351072
db_key_coin_name = ci.coin_name().lower()
10361073
self.log.info('Initialising {} wallet.'.format(ci.coin_name()))
10371074

1038-
if coin_type == Coins.XMR:
1075+
if coin_type in (Coins.XMR, Coins.WOW):
10391076
key_view = self.getWalletKey(coin_type, 1, for_ed25519=True)
10401077
key_spend = self.getWalletKey(coin_type, 2, for_ed25519=True)
10411078
ci.initialiseWallet(key_view, key_spend)
@@ -1951,7 +1988,7 @@ def getFeeRateForCoin(self, coin_type, conf_target: int = 2):
19511988
return self.ci(coin_type).get_fee_rate(conf_target)
19521989

19531990
def estimateWithdrawFee(self, coin_type, fee_rate):
1954-
if coin_type == Coins.XMR:
1991+
if coin_type in (Coins.XMR, Coins.WOW):
19551992
# Fee estimate must be manually initiated
19561993
return None
19571994
tx_vsize = self.ci(coin_type).getHTLCSpendTxVSize()
@@ -1960,7 +1997,7 @@ def estimateWithdrawFee(self, coin_type, fee_rate):
19601997

19611998
def withdrawCoin(self, coin_type, value, addr_to, subfee: bool) -> str:
19621999
ci = self.ci(coin_type)
1963-
if subfee and coin_type == Coins.XMR:
2000+
if subfee and coin_type in (Coins.XMR, Coins.WOW):
19642001
self.log.info('withdrawCoin sweep all {} to {}'.format(ci.ticker(), addr_to))
19652002
else:
19662003
self.log.info('withdrawCoin {} {} to {} {}'.format(value, ci.ticker(), addr_to, ' subfee' if subfee else ''))
@@ -2012,7 +2049,7 @@ def checkWalletSeed(self, c):
20122049
if c == Coins.PART:
20132050
ci.setWalletSeedWarning(False) # All keys should be be derived from the Particl mnemonic
20142051
return True # TODO
2015-
if c == Coins.XMR:
2052+
if c in (Coins.XMR, Coins.WOW):
20162053
expect_address = self.getCachedMainWalletAddress(ci)
20172054
if expect_address is None:
20182055
self.log.warning('Can\'t find expected main wallet address for coin {}'.format(ci.coin_name()))
@@ -2056,7 +2093,7 @@ def reseedWallet(self, coin_type):
20562093
# TODO: How to scan pruned blocks?
20572094

20582095
if not self.checkWalletSeed(coin_type):
2059-
if coin_type == Coins.XMR:
2096+
if coin_type in (Coins.XMR, Coins.WOW):
20602097
raise ValueError('TODO: How to reseed XMR wallet?')
20612098
else:
20622099
raise ValueError('Wallet seed doesn\'t match expected.')
@@ -5865,7 +5902,7 @@ def redeemXmrBidCoinBLockTx(self, bid_id: bytes, session) -> None:
58655902
kbsl = self.getPathKey(coin_from, coin_to, bid.created_at, xmr_swap.contract_count, KeyTypes.KBSL, for_ed25519)
58665903
vkbs = ci_to.sumKeys(kbsl, kbsf)
58675904

5868-
if coin_to == Coins.XMR:
5905+
if coin_to == (Coins.XMR, Coins.WOW):
58695906
address_to = self.getCachedMainWalletAddress(ci_to, session)
58705907
elif coin_to in (Coins.PART_BLIND, Coins.PART_ANON):
58715908
address_to = self.getCachedStealthAddressForCoin(coin_to, session)
@@ -5932,7 +5969,7 @@ def recoverXmrBidCoinBLockTx(self, bid_id: bytes, session) -> None:
59325969
vkbs = ci_to.sumKeys(kbsl, kbsf)
59335970

59345971
try:
5935-
if offer.coin_to == Coins.XMR:
5972+
if offer.coin_to in (Coins.XMR, Coins.WOW):
59365973
address_to = self.getCachedMainWalletAddress(ci_to, session)
59375974
elif coin_to in (Coins.PART_BLIND, Coins.PART_ANON):
59385975
address_to = self.getCachedStealthAddressForCoin(coin_to, session)
@@ -6984,7 +7021,7 @@ def getWalletInfo(self, coin):
69847021
rv['anon_pending'] = walletinfo['unconfirmed_anon'] + walletinfo['immature_anon_balance']
69857022
rv['blind_balance'] = walletinfo['blind_balance']
69867023
rv['blind_unconfirmed'] = walletinfo['unconfirmed_blind']
6987-
elif coin == Coins.XMR:
7024+
elif coin in (Coins.XMR, Coins.WOW):
69887025
rv['main_address'] = self.getCachedMainWalletAddress(ci)
69897026
elif coin == Coins.NAV:
69907027
rv['immature'] = walletinfo['immature_balance']

basicswap/chainparams.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
)
1111

1212
XMR_COIN = 10 ** 12
13+
WOW_COIN = 10 ** 11
1314

1415

1516
class Coins(IntEnum):
@@ -21,13 +22,14 @@ class Coins(IntEnum):
2122
XMR = 6
2223
PART_BLIND = 7
2324
PART_ANON = 8
24-
# ZANO = 9
25+
WOW = 9
2526
# NDAU = 10
2627
PIVX = 11
2728
DASH = 12
2829
FIRO = 13
2930
NAV = 14
3031
LTC_MWEB = 15
32+
# ZANO = 16 was 9
3133

3234

3335
chainparams = {
@@ -247,6 +249,33 @@ class Coins(IntEnum):
247249
'address_prefix': 18,
248250
}
249251
},
252+
Coins.WOW: {
253+
'name': 'wownero',
254+
'ticker': 'WOW',
255+
'client': 'wow',
256+
'decimal_places': 11,
257+
'mainnet': {
258+
'rpcport': 34568,
259+
'walletrpcport': 34572, # todo
260+
'min_amount': 100000,
261+
'max_amount': 10000 * WOW_COIN,
262+
'address_prefix': 4146,
263+
},
264+
'testnet': {
265+
'rpcport': 44568,
266+
'walletrpcport': 44572,
267+
'min_amount': 100000,
268+
'max_amount': 10000 * WOW_COIN,
269+
'address_prefix': 4146,
270+
},
271+
'regtest': {
272+
'rpcport': 54568,
273+
'walletrpcport': 54572,
274+
'min_amount': 100000,
275+
'max_amount': 10000 * WOW_COIN,
276+
'address_prefix': 4146,
277+
}
278+
},
250279
Coins.PIVX: {
251280
'name': 'pivx',
252281
'ticker': 'PIVX',

basicswap/config.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,7 @@
3636
XMR_BINDIR = os.path.expanduser(os.getenv('XMR_BINDIR', os.path.join(DEFAULT_TEST_BINDIR, 'monero')))
3737
XMRD = os.getenv('XMRD', 'monerod' + bin_suffix)
3838
XMR_WALLET_RPC = os.getenv('XMR_WALLET_RPC', 'monero-wallet-rpc' + bin_suffix)
39+
40+
WOW_BINDIR = os.path.expanduser(os.getenv('WOW_BINDIR', os.path.join(DEFAULT_TEST_BINDIR, 'wownero')))
41+
WOWD = os.getenv('WOWD', 'wownerod' + bin_suffix)
42+
WOW_WALLET_RPC = os.getenv('WOW_WALLET_RPC', 'wownero-wallet-rpc' + bin_suffix)

basicswap/http_server.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,22 @@ def page_rpc(self, url_split, post_string):
311311
else:
312312
raise ValueError('Unknown RPC variant')
313313
result = json.dumps(rv, indent=4)
314+
elif coin_type == Coins.WOW:
315+
ci = swap_client.ci(coin_type)
316+
arr = cmd.split(None, 1)
317+
method = arr[0]
318+
params = json.loads(arr[1]) if len(arr) > 1 else []
319+
if coin_id == -8:
320+
rv = ci.rpc_wallet(method, params)
321+
elif coin_id == -7:
322+
rv = ci.rpc(method, params)
323+
elif coin_id == -6:
324+
if params == []:
325+
params = None
326+
rv = ci.rpc2(method, params)
327+
else:
328+
raise ValueError('Unknown WOW RPC variant')
329+
result = json.dumps(rv, indent=4)
314330
else:
315331
if call_type == 'http':
316332
ci = swap_client.ci(coin_type)
@@ -338,6 +354,7 @@ def page_rpc(self, url_split, post_string):
338354

339355
coin_available = listAvailableCoins(swap_client, with_variants=False)
340356
with_xmr: bool = any(c[0] == Coins.XMR for c in coin_available)
357+
with_wow: bool = any(c[0] == Coins.WOW for c in coin_available)
341358
coins = [(str(c[0]) + ',0', c[1]) for c in coin_available if c[0] not in (Coins.XMR, )]
342359

343360
if any(c[0] == Coins.DCR for c in coin_available):
@@ -348,6 +365,10 @@ def page_rpc(self, url_split, post_string):
348365
coins.append((str(int(Coins.XMR)) + ',0', 'Monero'))
349366
coins.append((str(int(Coins.XMR)) + ',1', 'Monero JSON'))
350367
coins.append((str(int(Coins.XMR)) + ',2', 'Monero Wallet'))
368+
if with_wow:
369+
coins.append((str(int(Coins.WOW)) + ',0', 'Wownero'))
370+
coins.append((str(int(Coins.WOW)) + ',1', 'Wownero JSON'))
371+
coins.append((str(int(Coins.WOW)) + ',2', 'Wownero Wallet'))
351372

352373
return self.render_template(template, {
353374
'messages': messages,

0 commit comments

Comments
 (0)