示例#1
0
def create_wallet():
    global wallet_name
    if request.method == 'GET':
        return render_template('create-wallet.html')
    else:
        try:
            wallet_name = request.form['name']
            m = int(request.form['m'])
            n = int(request.form['n'])
            MultisigWallet.create(wallet_name, m, n)
            flash_success('Wallet created')
        except JunctionError as e:
            flash_error(str(e))
            return render_template('create-wallet.html')
        return redirect(url_for('wallet'))
示例#2
0
def broadcast():
    wallet = MultisigWallet.open(wallet_name)
    wallet.broadcast()
    wallet.remove_psbt()
    wallet.save()
    flash_success('transaction broadcasted successfully')
    return redirect(url_for('wallet'))
示例#3
0
def sign_psbt(fingerprint):
    wallet = MultisigWallet.open(wallet_name)
    client, device = get_client_and_device(fingerprint)
    psbt = wallet.psbt
    raw_signed_psbt = client.sign_tx(wallet.psbt)['psbt']
    new_psbt = serializations.PSBT()
    new_psbt.deserialize(raw_signed_psbt)
    wallet.psbt = new_psbt
    wallet.save()
    # FIXME: display the signer name here ...
    flash_success(f'{device["type"]} signed successfully')
    return redirect(url_for('wallet'))
示例#4
0
def wallet():
    wallet = MultisigWallet.open(wallet_name)
    devices = commands.enumerate()
    unconfirmed_balance, confirmed_balance = wallet.balances()

    # FIXME: ugly
    if wallet.psbt:
        psbt = wallet.decode_psbt()
        pprint(psbt)
        for signer in wallet.signers:
            signed = False
            # FIXME: this should check they've signed every input, not just one input
            for input in psbt['inputs']:
                for deriv in input['bip32_derivs']:
                    fingerprint_match = deriv['master_fingerprint'] == signer[
                        'fingerprint']
                    pubkey_match = deriv['pubkey'] in input.get(
                        'partial_signatures', [])
                    if fingerprint_match and pubkey_match:
                        signed = True
            signer['signed'] = signed

    else:
        psbt = None

    # FIXME: ugly
    for signer in wallet.signers:
        match = {'error': "Not found"}  # note: "Not found" is used in UI
        for device in devices:
            if device.get('fingerprint') == signer['fingerprint']:
                match = device
        signer['device'] = match

    # FIXME: ugly
    signer_fingerprints = [signer['fingerprint'] for signer in wallet.signers]
    potential_signers = [
        d for d in devices if 'fingerprint' not in d
        or d['fingerprint'] not in signer_fingerprints
    ]

    return render_template('wallet.html',
                           devices=devices,
                           wallet=wallet,
                           psbt=psbt,
                           unconfirmed_balance=unconfirmed_balance,
                           confirmed_balance=confirmed_balance,
                           potential_signers=potential_signers,
                           btc_to_sat=btc_to_sat)
示例#5
0
def add_signer(fingerprint):
    wallet = MultisigWallet.open(wallet_name)
    client, device = get_client_and_device(fingerprint)

    # Add a "signer" to the wallet
    account_path = "m/44h/1h/0h"
    base_key = client.get_pubkey_at_path(account_path)['xpub']
    wallet.add_signer(device['type'], device['fingerprint'], base_key,
                      account_path)

    # FIXME: only works when coldcard added last
    if device['type'] == 'coldcard':
        client.close()
        coldcard_enroll(wallet)

    msg = f"Signer \"{device['type']}\" has been added to your \"{wallet.name}\" wallet"
    flash_success(msg)

    return redirect(url_for('wallet'))
示例#6
0
def create_psbt():
    wallet = MultisigWallet.open(wallet_name)
    wallet.create_psbt(request.form['recipient'],
                       int(request.form['satoshis']))
    return redirect(url_for('wallet'))
示例#7
0
def address():
    wallet = MultisigWallet.open(wallet_name)
    address = wallet.address()
    return address, 200
示例#8
0
def export():
    wallet = MultisigWallet.open(wallet_name)
    wallet.export_watchonly()
    return redirect(url_for('wallet'))
示例#9
0
    devices = commands.enumerate()

    # prompt pins
    for device in devices:
        if device.get('needs_pin_sent'):
            global trezor_client
            trezor_client = trezor.TrezorClient(device['path'])
            trezor_client.prompt_pin()

    everything_unlocked = not any(['error' in device for device in devices])

    return render_template('devices.html',
                           devices=devices,
                           everything_unlocked=everything_unlocked)


if __name__ == '__main__':
    # FIXME: hack to prevent unloaded wallet
    try:
        wallet = MultisigWallet.open(wallet_name)
        wallet.ensure_watchonly()
    except:
        pass

    # Run flask, kill bitcoind on ctrl-c
    try:
        app.run(debug=True, threaded=False)
    except KeyboardInterrupt:
        process.terminate()
        print()