Exemplo n.º 1
0
 def _pay_key_fee(self, address, fee_lbc, name):
     log.info("Pay key fee %s --> %s", dewies_to_lbc(fee_lbc), address)
     reserved_points = self.wallet.reserve_points(address, fee_lbc)
     if reserved_points is None:
         raise InsufficientFundsError(
             'Unable to pay the key fee of {} for {}'.format(dewies_to_lbc(fee_lbc), name)
         )
     return f2d(self.wallet.send_points_to_address(reserved_points, fee_lbc))
Exemplo n.º 2
0
 def encode_transaction(self, tx):
     return {
         'txid': tx.id,
         'height': tx.height,
         'inputs': [self.encode_input(txo) for txo in tx.inputs],
         'outputs': [self.encode_output(txo) for txo in tx.outputs],
         'total_input': dewies_to_lbc(tx.input_sum),
         'total_output': dewies_to_lbc(tx.input_sum - tx.fee),
         'total_fee': dewies_to_lbc(tx.fee),
         'hex': hexlify(tx.raw).decode(),
     }
Exemplo n.º 3
0
def format_amount_value(obj):
    if isinstance(obj, dict):
        for k, v in obj.items():
            if k in ('amount', 'effective_amount'):
                if not isinstance(obj[k], float):
                    obj[k] = dewies_to_lbc(obj[k])
            elif k == 'supports' and isinstance(v, list):
                obj[k] = [{'txid': txid, 'nout': nout, 'amount': dewies_to_lbc(amount)}
                          for (txid, nout, amount) in v]
            elif isinstance(v, (list, dict)):
                obj[k] = format_amount_value(v)
    elif isinstance(obj, list):
        obj = [format_amount_value(o) for o in obj]
    return obj
Exemplo n.º 4
0
    def encode_output(self, txo):
        tx_height = txo.tx_ref.height
        best_height = self.ledger.headers.height
        output = {
            'txid':
            txo.tx_ref.id,
            'nout':
            txo.position,
            'amount':
            dewies_to_lbc(txo.amount),
            'address':
            txo.get_address(self.ledger),
            'height':
            tx_height,
            'confirmations':
            (best_height + 1) - tx_height if tx_height > 0 else tx_height
        }
        if txo.is_change is not None:
            output['is_change'] = txo.is_change
        if txo.is_my_account is not None:
            output['is_mine'] = txo.is_my_account

        if txo.script.is_claim_involved:
            output.update({
                'name': txo.claim_name,
                'claim_id': txo.claim_id,
                'permanent_url': txo.permanent_url,
            })

            if txo.script.is_claim_name or txo.script.is_update_claim:
                claim = txo.claim
                output['value'] = claim.claim_dict
                if claim.has_signature:
                    output['valid_signature'] = None
                    if txo.channel is not None:
                        output['channel_name'] = txo.channel.claim_name
                        try:
                            output[
                                'valid_signature'] = claim.validate_signature(
                                    txo.get_address(self.ledger),
                                    txo.channel.claim,
                                    name=txo.claim_name)
                        except BadSignatureError:
                            output['valid_signature'] = False
                        except ValueError:
                            log.exception(
                                'txo.id: %s, txo.channel.id:%s, output: %s',
                                txo.id, txo.channel.id, output)
                            output['valid_signature'] = False

            if txo.script.is_claim_name:
                output['type'] = 'claim'
            elif txo.script.is_update_claim:
                output['type'] = 'update'
            elif txo.script.is_support_claim:
                output['type'] = 'support'
            else:
                output['type'] = 'basic'

        return output
Exemplo n.º 5
0
 def _format_support(outpoint, supported_id, amount, address):
     return {
         "txid": outpoint.split(":")[0],
         "nout": int(outpoint.split(":")[1]),
         "claim_id": supported_id,
         "amount": dewies_to_lbc(amount),
         "address": address,
     }
Exemplo n.º 6
0
 async def _report_state(self):
     for account in self.accounts:
         total_receiving = len((await account.receiving.get_addresses()))
         total_change = len((await account.change.get_addresses()))
         channel_count = await account.get_channel_count()
         claim_count = await account.get_claim_count()
         balance = dewies_to_lbc(await account.get_balance())
         log.info("Loaded account %s with %s LBC, %d receiving addresses (gap: %d), "
                  "%d change addresses (gap: %d), %d channels, %d certificates and %d claims. ",
                  account.id, balance, total_receiving, account.receiving.gap, total_change, account.change.gap,
                  channel_count, len(account.certificates), claim_count)
Exemplo n.º 7
0
    async def claim_new_channel(self, channel_name, amount, account):
        address = await account.receiving.get_or_create_usable_address()
        cert, key = generate_certificate()
        tx = await Transaction.claim(channel_name, cert, amount, address,
                                     [account], account)
        await account.ledger.broadcast(tx)
        account.add_certificate_private_key(tx.outputs[0].ref, key.decode())
        # TODO: release reserved tx outputs in case anything fails by this point

        await self.old_db.save_claims([
            self._old_get_temp_claim_info(tx, tx.outputs[0], address, cert,
                                          channel_name, dewies_to_lbc(amount))
        ])
        return tx
Exemplo n.º 8
0
 def as_dict(self) -> typing.Dict:
     return {
         "name": self.claim_name,
         "claim_id": self.claim_id,
         "address": self.claim_address,
         "claim_sequence": self.claim_sequence,
         "value": self.claim,
         "height": self.height,
         "amount": dewies_to_lbc(self.amount),
         "nout": self.nout,
         "txid": self.txid,
         "channel_claim_id": self.channel_claim_id,
         "channel_name": self.channel_name
     }
Exemplo n.º 9
0
 async def tip_claim(self, amount, claim_id, account):
     claim_to_tip = await self.get_claim_by_claim_id(claim_id)
     tx = await Transaction.support(claim_to_tip['name'], claim_id, amount,
                                    claim_to_tip['address'], [account],
                                    account)
     await account.ledger.broadcast(tx)
     await self.old_db.save_supports(claim_id,
                                     [{
                                         'txid': tx.id,
                                         'nout': tx.position,
                                         'address': claim_to_tip['address'],
                                         'claim_id': claim_id,
                                         'amount': dewies_to_lbc(amount)
                                     }])
     return tx
Exemplo n.º 10
0
 async def support_claim(self, claim_name, claim_id, amount, account):
     holding_address = await account.receiving.get_or_create_usable_address(
     )
     tx = await Transaction.support(claim_name, claim_id, amount,
                                    holding_address, [account], account)
     await account.ledger.broadcast(tx)
     await self.old_db.save_supports(claim_id,
                                     [{
                                         'txid': tx.id,
                                         'nout': tx.position,
                                         'address': holding_address,
                                         'claim_id': claim_id,
                                         'amount': dewies_to_lbc(amount)
                                     }])
     return tx
Exemplo n.º 11
0
def _format_claim_response(outpoint, claim_id, name, amount, height, serialized, channel_id, address, claim_sequence):
    r = {
        "name": name,
        "claim_id": claim_id,
        "address": address,
        "claim_sequence": claim_sequence,
        "value": ClaimDict.deserialize(unhexlify(serialized)).claim_dict,
        "height": height,
        "amount": dewies_to_lbc(amount),
        "nout": int(outpoint.split(":")[1]),
        "txid": outpoint.split(":")[0],
        "channel_claim_id": channel_id,
        "channel_name": None
    }
    return r
Exemplo n.º 12
0
 async def claim_name(self,
                      account,
                      name,
                      amount,
                      claim_dict,
                      certificate=None,
                      claim_address=None):
     claim = ClaimDict.load_dict(claim_dict)
     if not claim_address:
         claim_address = await account.receiving.get_or_create_usable_address(
         )
     if certificate:
         claim = claim.sign(
             certificate.private_key,
             claim_address,
             certificate.claim_id,
             curve=SECP256k1,
             name=name,
             force_detached=
             False  # TODO: delete it and make True default everywhere when its out
         )
     existing_claims = await account.get_claims(
         claim_name_type__any={
             'is_claim': 1,
             'is_update': 1
         },  # exclude is_supports
         claim_name=name)
     if len(existing_claims) == 0:
         tx = await Transaction.claim(name, claim, amount, claim_address,
                                      [account], account)
     elif len(existing_claims) == 1:
         tx = await Transaction.update(existing_claims[0], claim, amount,
                                       claim_address, [account], account)
     else:
         raise NameError(
             f"More than one other claim exists with the name '{name}'.")
     await account.ledger.broadcast(tx)
     await self.old_db.save_claims([
         self._old_get_temp_claim_info(tx, tx.outputs[0], claim_address,
                                       claim_dict, name,
                                       dewies_to_lbc(amount))
     ])
     # TODO: release reserved tx outputs in case anything fails by this point
     return tx
Exemplo n.º 13
0
 async def get_history(account: BaseAccount, **constraints):
     headers = account.ledger.headers
     txs = await account.get_transactions(**constraints)
     history = []
     for tx in txs:
         ts = headers[tx.height]['timestamp'] if tx.height > 0 else None
         item = {
             'txid':
             tx.id,
             'timestamp':
             ts,
             'date':
             datetime.fromtimestamp(ts).isoformat(' ')[:-3]
             if tx.height > 0 else None,
             'confirmations':
             (headers.height + 1) - tx.height if tx.height > 0 else 0,
             'claim_info': [],
             'update_info': [],
             'support_info': [],
             'abandon_info': []
         }
         is_my_inputs = all([txi.is_my_account for txi in tx.inputs])
         if is_my_inputs:
             # fees only matter if we are the ones paying them
             item['value'] = dewies_to_lbc(tx.net_account_balance + tx.fee)
             item['fee'] = dewies_to_lbc(-tx.fee)
         else:
             # someone else paid the fees
             item['value'] = dewies_to_lbc(tx.net_account_balance)
             item['fee'] = '0.0'
         for txo in tx.my_claim_outputs:
             item['claim_info'].append({
                 'address':
                 txo.get_address(account.ledger),
                 'balance_delta':
                 dewies_to_lbc(-txo.amount),
                 'amount':
                 dewies_to_lbc(txo.amount),
                 'claim_id':
                 txo.claim_id,
                 'claim_name':
                 txo.claim_name,
                 'nout':
                 txo.position
             })
         for txo in tx.my_update_outputs:
             if is_my_inputs:  # updating my own claim
                 previous = None
                 for txi in tx.inputs:
                     if txi.txo_ref.txo is not None:
                         other_txo = txi.txo_ref.txo
                         if (other_txo.is_claim or other_txo.script.is_support_claim) \
                                 and other_txo.claim_id == txo.claim_id:
                             previous = other_txo
                             break
                 if previous is not None:
                     item['update_info'].append({
                         'address':
                         txo.get_address(account.ledger),
                         'balance_delta':
                         dewies_to_lbc(previous.amount - txo.amount),
                         'amount':
                         dewies_to_lbc(txo.amount),
                         'claim_id':
                         txo.claim_id,
                         'claim_name':
                         txo.claim_name,
                         'nout':
                         txo.position
                     })
             else:  # someone sent us their claim
                 item['update_info'].append({
                     'address':
                     txo.get_address(account.ledger),
                     'balance_delta':
                     dewies_to_lbc(0),
                     'amount':
                     dewies_to_lbc(txo.amount),
                     'claim_id':
                     txo.claim_id,
                     'claim_name':
                     txo.claim_name,
                     'nout':
                     txo.position
                 })
         for txo in tx.my_support_outputs:
             item['support_info'].append({
                 'address':
                 txo.get_address(account.ledger),
                 'balance_delta':
                 dewies_to_lbc(
                     txo.amount if not is_my_inputs else -txo.amount),
                 'amount':
                 dewies_to_lbc(txo.amount),
                 'claim_id':
                 txo.claim_id,
                 'claim_name':
                 txo.claim_name,
                 'is_tip':
                 not is_my_inputs,
                 'nout':
                 txo.position
             })
         for txo in tx.other_support_outputs:
             item['support_info'].append({
                 'address':
                 txo.get_address(account.ledger),
                 'balance_delta':
                 dewies_to_lbc(-txo.amount),
                 'amount':
                 dewies_to_lbc(txo.amount),
                 'claim_id':
                 txo.claim_id,
                 'claim_name':
                 txo.claim_name,
                 'is_tip':
                 is_my_inputs,
                 'nout':
                 txo.position
             })
         for txo in tx.my_abandon_outputs:
             item['abandon_info'].append({
                 'address':
                 txo.get_address(account.ledger),
                 'balance_delta':
                 dewies_to_lbc(txo.amount),
                 'amount':
                 dewies_to_lbc(txo.amount),
                 'claim_id':
                 txo.claim_id,
                 'claim_name':
                 txo.claim_name,
                 'nout':
                 txo.position
             })
         history.append(item)
     return history
Exemplo n.º 14
0
def calculate_effective_amount(
        amount: str,
        supports: typing.Optional[typing.List[typing.Dict]] = None) -> str:
    return dewies_to_lbc(
        lbc_to_dewies(amount) +
        sum([lbc_to_dewies(support['amount']) for support in supports]))
Exemplo n.º 15
0
 async def get_history(account: BaseAccount, **constraints):
     headers = account.ledger.headers
     txs = await account.get_transactions(**constraints)
     history = []
     for tx in txs:
         ts = headers[tx.height]['timestamp'] if tx.height > 0 else None
         item = {
             'txid':
             tx.id,
             'timestamp':
             ts,
             'value':
             dewies_to_lbc(tx.net_account_balance),
             'fee':
             dewies_to_lbc(tx.fee),
             'date':
             datetime.fromtimestamp(ts).isoformat(' ')[:-3]
             if tx.height > 0 else None,
             'confirmations':
             headers.height - tx.height if tx.height > 0 else 0,
             'claim_info': [],
             'update_info': [],
             'support_info': [],
             'abandon_info': []
         }
         for txo in tx.my_claim_outputs:
             item['claim_info'].append({
                 'address':
                 txo.get_address(account.ledger),
                 'balance_delta':
                 dewies_to_lbc(-txo.amount),
                 'amount':
                 dewies_to_lbc(txo.amount),
                 'claim_id':
                 txo.claim_id,
                 'claim_name':
                 txo.claim_name,
                 'nout':
                 txo.position
             })
         for txo in tx.my_update_outputs:
             item['update_info'].append({
                 'address':
                 txo.get_address(account.ledger),
                 'balance_delta':
                 dewies_to_lbc(-txo.amount),
                 'amount':
                 dewies_to_lbc(txo.amount),
                 'claim_id':
                 txo.claim_id,
                 'claim_name':
                 txo.claim_name,
                 'nout':
                 txo.position
             })
         for txo in tx.my_support_outputs:
             is_tip = next(tx.my_inputs, None) is None
             item['support_info'].append({
                 'address':
                 txo.get_address(account.ledger),
                 'balance_delta':
                 dewies_to_lbc(txo.amount if is_tip else -txo.amount),
                 'amount':
                 dewies_to_lbc(txo.amount),
                 'claim_id':
                 txo.claim_id,
                 'claim_name':
                 txo.claim_name,
                 'is_tip':
                 is_tip,
                 'nout':
                 txo.position
             })
         for txo in tx.other_support_outputs:
             is_tip = next(tx.my_inputs, None) is not None
             item['support_info'].append({
                 'address':
                 txo.get_address(account.ledger),
                 'balance_delta':
                 dewies_to_lbc(-txo.amount),
                 'amount':
                 dewies_to_lbc(txo.amount),
                 'claim_id':
                 txo.claim_id,
                 'claim_name':
                 txo.claim_name,
                 'is_tip':
                 is_tip,
                 'nout':
                 txo.position
             })
         for txo in tx.my_abandon_outputs:
             item['abandon_info'].append({
                 'address':
                 txo.get_address(account.ledger),
                 'balance_delta':
                 dewies_to_lbc(-txo.amount),
                 'amount':
                 dewies_to_lbc(txo.amount),
                 'claim_id':
                 txo.claim_id,
                 'claim_name':
                 txo.claim_name,
                 'nout':
                 txo.position
             })
         if all([txi.txo_ref.txo is not None for txi in tx.inputs]):
             item['fee'] = dewies_to_lbc(tx.fee)
         else:
             item['fee'] = '0'  # can't calculate fee without all input txos
         history.append(item)
     return history