예제 #1
0
    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"]))
예제 #2
0
    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))
예제 #3
0
    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)
예제 #4
0
 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"]))
예제 #5
0
 def conv_disp_amount(self, amount):
     return wallet.conv_disp_amount(amount)