async def key_image_sync(self, line): """ Key image sync with Trezor :param line: :return: """ res = self.wallet_proxy.export_outputs() outputs_data_hex = res["result"]["outputs_data_hex"] outs_data = binascii.unhexlify(outputs_data_hex) exps = await wallet.load_exported_outputs(self.priv_view, outs_data) # Check if for this address match = exps.m_spend_public_key == crypto.encodepoint( self.pub_spend) and exps.m_view_public_key == crypto.encodepoint( self.pub_view) net_ver = monero.net_version(self.network_type, False) addr = monero.encode_addr(net_ver, exps.m_spend_public_key, exps.m_view_public_key) if not match: logger.error("Exported outputs from different wallet: %s" % addr.decode("ascii")) return self.poutput("Exported outputs loaded.") self.poutput("Please confirm the key image sync on the Trezor ") res = await self.agent.import_outputs(exps.tds) # Generate import key image requests key_images = [] for kie in res: key_images.append({ "key_image": binascii.hexlify(kie[0]).decode("ascii"), "signature": binascii.hexlify(kie[1][0] + kie[1][1]).decode("ascii"), }) import_req = {"signed_key_images": key_images} res = self.wallet_proxy.import_key_images(import_req) print("Height: %s" % res["result"]["height"]) print("Spent: %.5f" % wallet.conv_disp_amount(res["result"]["spent"])) print("Unspent: %.5f" % wallet.conv_disp_amount(res["result"]["unspent"]))
def transfer_params(self, params): res = self.wallet_proxy.transfer(params) if "result" not in res: logger.error("Transfer error: %s" % res) raise ValueError("Could not transfer") result = res["result"] print("Fee: %s" % wallet.conv_disp_amount(result["fee"])) ask_res = self.ask_proceed_quit("Do you confirm (y/n) ? ") if ask_res != self.PROCEED_YES: return if "unsigned_txset" not in result: logger.error( "Unsigned transaction not found in the response. " "Please make sure you are using compatible monero-wallet-rpc") logger.debug(res) return unsigned = binascii.unhexlify(result["unsigned_txset"]) self.wait_coro(self.sign_unsigned(unsigned))
async def describe(self, inp, unsigned_txs, keys, key_subs): print("\nInp: %s, #txs: %s, #transfers: %s" % (inp, len(unsigned_txs.txes), len(unsigned_txs.transfers))) for txid, tx in enumerate(unsigned_txs.txes): srcs = tx.sources dsts = tx.splitted_dsts extra = tx.extra change = tx.change_dts account = tx.subaddr_account subs = tx.subaddr_indices mixin = len(srcs[0].outputs) - 1 amnt_in = sum([x.amount for x in srcs]) amnt_out = sum([x.amount for x in dsts]) fee = amnt_in - amnt_out n_inp_additional = sum( [1 for x in srcs if len(x.real_out_additional_tx_keys) > 0] ) change_addr = ( addr.build_address( change.addr.m_spend_public_key, change.addr.m_view_public_key ) if change else None ) out_txs2 = await self.reformat_outs(dsts) num_stdaddresses, num_subaddresses, single_dest_subaddress = addr.classify_subaddresses( out_txs2, change_addr ) print( " tx: %s, #inp: %2d, #inp_add: %2d, #out: %2d, mixin: %2d, acc: %s, subs: %s, " "xmr_in: %10.6f, xmr_out: %10.6f, fee: %10.6f, change: %10.6f, out_clean: %10.6f" % ( txid, len(srcs), n_inp_additional, len(dsts), mixin, account, subs, wallet.conv_disp_amount(amnt_in), wallet.conv_disp_amount(amnt_out), wallet.conv_disp_amount(fee), wallet.conv_disp_amount(change.amount) if change else 0, wallet.conv_disp_amount( (amnt_out - change.amount) if change else amnt_out ), ) ) print( " Out: num_std: %2d, num_sub: %2d, single_dest_sub: %s, total: %s" % ( num_stdaddresses, num_subaddresses, 1 if single_dest_subaddress else 0, len(dsts), ) ) accounts = set() subs = set() for inp in srcs: res = await self.analyze_input(keys, key_subs, inp) accounts.add(res[0]) if res != (0, 0): subs.add(res) print(" Ins: accounts: %s, subs: %s" % (accounts, len(subs))) extras = await monero.parse_extra_fields(extra) extras_val = [] for c in extras: if isinstance(c, TxExtraPubKey): extras_val.append("TxKey") elif isinstance(c, TxExtraNonce): extras_val.append( "Nonce: %s" % binascii.hexlify(c.nonce).decode("ascii") ) elif isinstance(c, TxExtraAdditionalPubKeys): extras_val.append("AdditionalTxKeys: %s" % len(c.data)) else: extras_val.append(str(c)) print(" Extras: %s" % ", ".join(extras_val)) # Final verification for idx, inp in enumerate(tx.sources): self.check_input(inp, keys, key_subs) if not crypto.point_eq( crypto.decodepoint(inp.outputs[inp.real_output][1].mask), crypto.gen_c(crypto.decodeint(inp.mask), inp.amount), ): raise ValueError("Real source entry's mask does not equal spend key's. Inp: %d" % idx)
def do_balance(self, line): res = self.wallet_proxy.balance() print("Balance: %.5f" % wallet.conv_disp_amount(res["result"]["balance"])) print("Unlocked Balance: %.5f" % wallet.conv_disp_amount(res["result"]["unlocked_balance"]))
def conv_disp_amount(self, amount): return wallet.conv_disp_amount(amount)