Ejemplo n.º 1
0
 def bitcoind_export(self):
     descriptor = self.descriptor()
     export_range = (self.address_index,
                     self.address_index + self.export_size)
     rpc = WalletRPC('bitboy')
     rpc.export(descriptor, export_range, False)  # FIXME: change=False
     # FIXME: hackily update address index based on unspent descriptors ...
     # this could miss spent transactions ...
     # FIXME: skips exports between old and new index
     unspent = rpc.rpc().listunspent(0, 9999999, [], True)
     for u in unspent:
         desc = u['desc']
         ai = int(desc[desc.find('/') + 1:desc.find(']')])
         self.address_index = max(self.address_index, ai + 1)
     self.save()
Ejemplo n.º 2
0
 def open(cls):
     with open(cls.filename, 'r') as f:
         raw_json = f.read()
         wallet = cls.deserialize(raw_json)
         # load associated Bitcoin Core watch-only wallet
         WalletRPC('').load_wallet('bitboy')
         return wallet
Ejemplo n.º 3
0
 def create(cls, xpub=None):
     if isfile(cls.filename):
         raise OSError("wallet file already exists")
     xpub = HDPublicKey.parse(BytesIO(xpub.encode()))
     WalletRPC('').create_watchonly_wallet('bitboy')
     wallet = cls(xpub)
     wallet.bitcoind_export()
     wallet.save()
     return wallet
Ejemplo n.º 4
0
 def balance(self):
     unconfirmed_balance = 0
     confirmed_balance = 0
     unspent = WalletRPC('bitboy').listunspent(0, 9999999, [], True)
     for u in unspent:
         if u['confirmations'] > 0:
             confirmed_balance += u['amount']
         else:
             unconfirmed_balance += u['amount']
     return unconfirmed_balance, confirmed_balance
Ejemplo n.º 5
0
def add_signature():
    if request.method == 'GET':
        return render_template('add-signature.html')
    else:
        wallet = Wallet.open()
        script_sig = Script.parse(
            BytesIO(bytes.fromhex(request.json['signature'])))
        tx = Tx.parse(BytesIO(bytes.fromhex(wallet.tx_data['tx'])))
        for i, tx_in in enumerate(tx.tx_ins):
            if tx_in.script_sig.cmds == []:
                tx.tx_ins[i].script_sig = script_sig
                print('filled in script sig')
                break
        # FIXME: for some reason script_sig is None ...
        if all([tx_in.script_sig.cmds != [] for tx_in in tx.tx_ins]):
            rpc = WalletRPC('bitboy')
            print(tx.serialize().hex())
            rpc.broadcast(tx.serialize().hex())
            print('broadcasted')
            # wallet.tx_data = None
            # FIXME
            return tx.id()
        wallet.save()
        return 'ok'
Ejemplo n.º 6
0
    def prepare_tx(self, address, amount, fee):
        # FIXME: amount -> satoshis
        rpc = WalletRPC('bitboy')

        # create unfunded transaction
        tx_ins = []
        tx_outs = [
            {
                address: sat_to_btc(amount)
            },
        ]
        rawtx = rpc.create_raw_transaction(tx_ins, tx_outs)

        # fund it
        change_address = self.consume_address()
        fundedtx = rpc.fund_raw_transaction(rawtx, change_address)

        # input metadata
        input_meta = []
        decoded = rpc.rpc().decoderawtransaction(fundedtx)
        for tx_in in decoded['vin']:
            print('iterate input')
            tx_id = tx_in['txid']
            tx_index = tx_in['vout']
            prev_tx = rpc.rpc().getrawtransaction(tx_id, True)
            script_pubkey = encode_varstr(
                bytes.fromhex(
                    prev_tx['vout'][tx_index]['scriptPubKey']['hex'])).hex()
            input_address = prev_tx['vout'][tx_index]['scriptPubKey'][
                'addresses'][0]
            pubkey, path = self.lookup_pubkey(input_address)
            derivation_path = f"m/69'/{path[2:]}"
            print('PATH', derivation_path)
            input_meta = [{
                'script_pubkey': script_pubkey,
                'derivation_path': derivation_path
            }]

        # output metadata
        output_meta = []
        for tx_out in decoded['vout']:
            print('iterate output')
            address = tx_out['scriptPubKey']['addresses'][0]
            pubkey, path = self.lookup_pubkey(address)
            if path is None:
                output_meta.append({'change': False})
            else:
                derivation_path = f"m/69'/{path[2:]}"
                output_meta.append({
                    'change': True,
                    'derivation_path': derivation_path
                })

        return fundedtx, input_meta, output_meta
Ejemplo n.º 7
0
 def transactions(self):
     return WalletRPC('bitboy').get_transactions()
Ejemplo n.º 8
0
 def unspent(self):
     return WalletRPC('bitboy').get_unspent()
Ejemplo n.º 9
0
 def balance(self):
     return WalletRPC('bitboy').get_balance()