示例#1
0
    def finalize(self, parent, proposal, broadcast=False):

        with ConnCtx(parent.credentials, parent.critical) as cc:
            connection = cc.connection
            check_wallet_unlocked(connection)
            check_not_mine(proposal['u_address_r'], connection)

            (incomplete_tx, _, _, fee_p, _, _,
             _) = swap.parse_accepted(*[proposal[k] for k in ACCEPTED_KEYS],
                                      connection=connection)

            msg = 'Are you sure you want to execute this swap?\n\n' \
                  'Paying fees {:.8f} L-BTC.'.format(sat2btc(fee_p))
            ans = QMessageBox.question(parent, 'Confirm', msg)
            if ans != QMessageBox.Yes:
                return

            ret = swap.finalize(incomplete_tx, connection, broadcast)
            if broadcast:
                msg = 'Transaction ID: {}'.format(ret)
                QMessageBox.information(parent, 'Transaction sent', msg)
                InitialWindow(parent)
            else:
                parent.copy_dialog(text=ret,
                                   title='Copy Transaction Hex',
                                   suggested_name='transaction.txt')
示例#2
0
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self.setupUi(parent)

        setup_toolbar(parent, self)

        with ConnCtx(parent.credentials, parent.critical, True) as cc:
            parent.asset_data.update(cc.connection)

        self.buttonReceiveAddNew.clicked.connect(
            lambda: parent.add_new_asset(self.comboBoxReceiveAsset))
        self.buttonGenerateProposal.clicked.connect(
            lambda: self.generate_proposal(parent))

        # combo boxes
        self.comboBoxSendAsset.addItem('')
        for asset_id, label in parent.asset_data.labels.items():
            self.comboBoxSendAsset.addItem(label, asset_id)

        # available balance is shown in the status tip
        self.comboBoxSendAsset.currentTextChanged.connect(
            lambda: set_balance_label(parent.asset_data, self.
                                      comboBoxSendAsset, self.
                                      labelSendAvailable))

        self.comboBoxReceiveAsset.addItem('')
        for asset_id, label in parent.asset_data.labels.items():
            self.comboBoxReceiveAsset.addItem(label, asset_id)
        for asset_id, label in parent.asset_data.temp_labels.items():
            self.comboBoxReceiveAsset.addItem(label, asset_id)

        set_re_float(self.lineEditSendAmount)
        set_re_float(self.lineEditReceiveAmount)
示例#3
0
def finalize(obj, payload, send):
    """Finalize a swap

    Sign the remaining inputs, print the transaction or broadcast it.
    """

    with ConnCtx(obj.credentials, critical) as cc:
        connection = cc.connection
        do_initial_checks(connection, obj.is_mainnet)
        proposal = decode_payload(payload.read())
        check_wallet_unlocked(connection)
        check_not_mine(proposal['u_address_r'], connection)

        (incomplete_tx, _, _, _, _, _,
         _) = swap.parse_accepted(*[proposal[k] for k in ACCEPTED_KEYS],
                                  connection)

        ret = swap.finalize(incomplete_tx, connection, broadcast=send)

        if send:
            d = {'broadcast': True, 'txid': ret}
        else:
            d = {'broadcast': False, 'transaction': ret}

        click.echo(json.dumps(d, indent=4))
示例#4
0
 def change_service_url(self, action):
     d = URLDialog(self)
     ret = d.exec_()
     if ret:
         temp = self.credentials
         temp['service_url'] = d.lineEditURL.text()
         with ConnCtx(temp, self.critical) as cc:
             do_initial_checks(cc.connection, self.is_mainnet)
             self.credentials = temp
             set_url_tip(self.credentials['service_url'], action)
示例#5
0
def info(obj, payload):
    """Show proposal in human readable format

    Proposal could be either in two status: proposed or accepted.
    """

    with ConnCtx(obj.credentials, critical) as cc:
        connection = cc.connection
        do_initial_checks(connection, obj.is_mainnet)

        proposal = decode_payload(payload.read())
        status = get_status(proposal)

        if status == 'proposed':
            (tx, address_p, amount_p, asset_p, fee_p, amount_r, asset_r,
             map_amount, map_asset, unspents_details) = swap.parse_proposed(
                 *[proposal[k] for k in PROPOSED_KEYS], connection)
            is_proposer = is_mine(address_p, connection)
            proposer_leg_is_funded, receiver_leg_is_funded = True, False
            fee_r = 0

        elif status == 'accepted':
            (signed_tx, amount_p, asset_p, fee_p, amount_r, asset_r,
             fee_r) = swap.parse_accepted(
                 *[proposal[k] for k in ACCEPTED_KEYS], connection)
            is_proposer = is_mine(proposal['u_address_p'], connection)
            proposer_leg_is_funded, receiver_leg_is_funded = True, True

        d = {
            'status':
            status,
            'legs': [
                {
                    'incoming': not is_proposer,
                    'funded': proposer_leg_is_funded,
                    'asset': asset_p,
                    'amount': sat2btc(amount_p),
                    'fee': sat2btc(fee_p),
                },
                {
                    'incoming': is_proposer,
                    'funded': receiver_leg_is_funded,
                    'asset': asset_r,
                    'amount': sat2btc(amount_r),
                    'fee': sat2btc(fee_r),
                },
            ]
        }
        click.echo(json.dumps(d, indent=4))
示例#6
0
def propose(obj, asset_p, amount_p, asset_r, amount_r, output, fee_rate):
    """Propose a swap

    A swap consists in sending AMOUNT_P of ASSET_P and receiving AMOUNT_R of
    ASSET_R.
    """

    with ConnCtx(obj.credentials, critical) as cc:
        connection = cc.connection
        do_initial_checks(connection, obj.is_mainnet)

        proposal = swap.propose(btc2sat(amount_p), asset_p, btc2sat(amount_r),
                                asset_r, connection, fee_rate)
        encoded_payload = encode_payload(proposal)
        click.echo(encoded_payload, file=output)
示例#7
0
 def change_conf_file(self, action):
     filename, _ = QFileDialog.getOpenFileName(
         self, 'Choose elements.conf',
         self.credentials['elements_conf_file'] or os.path.expanduser('~'))
     if not filename:
         return
     try:
         with open(filename, 'r') as r:
             temp = self.credentials
             temp['elements_conf_file'] = filename
             with ConnCtx(temp, self.critical) as cc:
                 do_initial_checks(cc.connection, self.is_mainnet)
                 self.credentials = temp
                 set_conf_tip(self.credentials['elements_conf_file'],
                              action)
     except IOError:
         # FIXME: is this reachable?
         pass
示例#8
0
def accept(obj, payload, output, fee_rate):
    """Accept a swap

    Fund and (partially) sign a proposed transaction.
    """

    with ConnCtx(obj.credentials, critical) as cc:
        connection = cc.connection
        do_initial_checks(connection, obj.is_mainnet)
        proposal = decode_payload(payload.read())

        check_wallet_unlocked(connection)
        check_not_mine(proposal['u_address_p'], connection)

        ret = swap.parse_proposed(*[proposal[k] for k in PROPOSED_KEYS],
                                  connection)
        accepted_swap = swap.accept(*ret, connection, fee_rate)
        encoded_payload = encode_payload(accepted_swap)
        click.echo(encoded_payload, file=output)
示例#9
0
    def __init__(self,
                 service_url=None,
                 elements_conf_file=None,
                 is_mainnet=False):
        QMainWindow.__init__(self)

        self.credentials = {
            'elements_conf_file': elements_conf_file,
            'service_url': service_url,
            'service_port': (None if is_mainnet else DEFAULT_REGTEST_RPC_PORT),
        }
        self.is_mainnet = is_mainnet
        self.asset_data = AssetsData()

        self.center()

        with ConnCtx(self.credentials, self.critical) as cc:
            do_initial_checks(cc.connection, is_mainnet)

        InitialWindow(parent=self)
示例#10
0
    def generate_proposal(self, parent):
        asset_p = self.comboBoxSendAsset.currentData()
        amount_p = btc2sat(float(self.lineEditSendAmount.text() or 0))
        asset_r = self.comboBoxReceiveAsset.currentData()
        amount_r = btc2sat(float(self.lineEditReceiveAmount.text() or 0))

        with ConnCtx(parent.credentials, parent.critical) as cc:
            connection = cc.connection
            fee_rate = float(connection.getnetworkinfo()['relayfee'])

            proposal = swap.propose(amount_p=amount_p,
                                    asset_p=asset_p,
                                    amount_r=amount_r,
                                    asset_r=asset_r,
                                    connection=connection,
                                    fee_rate=fee_rate)

            encoded_payload = encode_payload(proposal)
            parent.copy_dialog(text=encoded_payload,
                               suggested_name='proposal.txt')
示例#11
0
    def accept(self, parent, proposal):
        with ConnCtx(parent.credentials, parent.critical) as cc:
            connection = cc.connection
            check_wallet_unlocked(connection)
            check_not_mine(proposal['u_address_p'], connection)

            ret = swap.parse_proposed(*[proposal[k] for k in PROPOSED_KEYS],
                                      connection=connection)

            fee_rate = float(connection.getnetworkinfo()['relayfee'])
            accepted_swap = swap.accept(*ret, connection, fee_rate)
            encoded_payload = encode_payload(accepted_swap)

            tx = accepted_swap['tx']
            fee_p = ret[4]
            fee_r = compute_receiver_fee(connection, tx, fee_p)
            msg = 'Are you sure you want to accept this swap?\n\n' \
                  'Paying fees {:.8f} L-BTC.\n\nReceiving address: {}.'.format(
                    sat2btc(fee_r), accepted_swap['u_address_r'])
            ans = QMessageBox.question(parent, 'Confirm', msg)
            if ans == QMessageBox.Yes:
                parent.copy_dialog(text=encoded_payload,
                                   suggested_name='accepted.txt')
示例#12
0
    def __init__(self, parent, proposal):
        QMainWindow.__init__(self, parent)
        self.setupUi(parent)

        setup_toolbar(parent, self)

        self.buttonExecute.clicked.connect(
            lambda: self.finalize(parent, proposal, broadcast=True))

        with ConnCtx(parent.credentials, parent.critical, True) as cc:
            connection = cc.connection
            parent.asset_data.update(connection)
            check_not_mine(proposal['u_address_r'], connection)

            (tx, amount_p, asset_p, fee_p, amount_r, asset_r,
             fee_r) = swap.parse_accepted(
                 *[proposal[k] for k in ACCEPTED_KEYS], connection=connection)

            self.labelProposerAmountValue.setText(f2s(sat2btc(amount_p)))
            self.labelProposerAssetValue.setText(
                parent.asset_data.get_label(asset_p))
            self.labelReceiverAmountValue.setText(f2s(sat2btc(amount_r)))
            self.labelReceiverAssetValue.setText(
                parent.asset_data.get_label(asset_r))
示例#13
0
    def __init__(self, parent, proposal):
        QMainWindow.__init__(self, parent)
        self.setupUi(parent)

        setup_toolbar(parent, self)

        self.buttonAccept.clicked.connect(
            lambda: self.accept(parent, proposal))

        with ConnCtx(parent.credentials, parent.critical, True) as cc:
            connection = cc.connection
            parent.asset_data.update(connection)
            check_not_mine(proposal['u_address_p'], connection)

            (tx, address_p, amount_p, asset_p, fee_p, amount_r, asset_r,
             map_amount, map_asset, unspents_details) = swap.parse_proposed(
                 *[proposal[k] for k in PROPOSED_KEYS], connection=connection)

            self.labelProposerAmountValue.setText(f2s(sat2btc(amount_p)))
            self.labelProposerAssetValue.setText(
                parent.asset_data.get_label(asset_p))
            self.labelReceiverAmountValue.setText(f2s(sat2btc(amount_r)))
            self.labelReceiverAssetValue.setText(
                parent.asset_data.get_label(asset_r))