def main(app_config):
    issuing_address = app_config.issuing_address
    chain = app_config.bitcoin_chain
    secret_manager = signer_helper.initialize_signer(app_config)
    certificate_batch_handler = CertificateBatchHandler(
        secret_manager=secret_manager,
        certificate_handler=CertificateV2Handler(),
        merkle_tree=MerkleTreeGenerator())
    if chain == Chain.mocknet:
        transaction_handler = MockTransactionHandler()
    else:
        cost_constants = TransactionCostConstants(app_config.tx_fee,
                                                  app_config.dust_threshold,
                                                  app_config.satoshi_per_byte)
        connector = ServiceProviderConnector(chain, app_config.bitcoind)
        transaction_handler = BitcoinTransactionHandler(
            connector,
            cost_constants,
            secret_manager,
            issuing_address=issuing_address)
    return issue(app_config, certificate_batch_handler, transaction_handler)
 def test_get_cost_4(self):
     cost_constants = TransactionCostConstants(0.0001, 0.0000275, 41)
     total = tx_utils.calculate_tx_total(cost_constants, 1, 2000)
     self.assertEqual(total, 8296282)
 def test_calculate_tx_fee_1(self):
     cost_constants = TransactionCostConstants(0.0001, 0.0000275, 41)
     total = tx_utils.calculate_tx_total(cost_constants, 40, 16)
     self.assertEqual(total, 312837)
def main(app_config):
    unsigned_certs_dir = app_config.unsigned_certificates_dir
    signed_certs_dir = app_config.signed_certificates_dir
    blockcerts_dir = app_config.blockchain_certificates_dir
    work_dir = app_config.work_dir

    # find certificates to issue
    certificates = helpers.find_certificates_to_process(
        unsigned_certs_dir, signed_certs_dir)
    if not certificates:
        logging.warning('No certificates to process')
        raise NoCertificatesFoundError('No certificates to process')

    certificates, batch_metadata = helpers.prepare_issuance_batch(
        unsigned_certs_dir, signed_certs_dir, work_dir)
    logging.info('Processing %d certificates under work path=%s',
                 len(certificates), work_dir)

    issuing_address = app_config.issuing_address
    revocation_address = app_config.revocation_address

    if app_config.wallet_connector_type == 'blockchain.info':
        wallet_credentials = {
            'wallet_guid': app_config.wallet_guid,
            'wallet_password': app_config.wallet_password,
            'api_key': app_config.api_key,
        }
    else:
        wallet_credentials = {}

    connector = ServiceProviderConnector(app_config.netcode,
                                         app_config.wallet_connector_type,
                                         wallet_credentials)
    path_to_secret = os.path.join(app_config.usb_name, app_config.key_file)

    signer = Signer(
        FileSecretManager(path_to_secret=path_to_secret,
                          disable_safe_mode=app_config.safe_mode))
    tx_constants = TransactionCostConstants(app_config.tx_fee,
                                            app_config.dust_threshold,
                                            app_config.satoshi_per_byte)

    issuer = BatchIssuer(netcode=app_config.netcode,
                         issuing_address=issuing_address,
                         certificates_to_issue=certificates,
                         connector=connector,
                         signer=signer,
                         tx_cost_constants=tx_constants,
                         batch_metadata=batch_metadata)

    issuer.validate_schema()

    # verify signed certs are signed with issuing key
    [
        verify_signature(uid, cert.signed_cert_file_name, issuing_address)
        for uid, cert in certificates.items()
    ]

    logging.info('Hashing signed certificates.')
    issuer.hash_certificates()

    # calculate transaction cost
    transaction_cost = issuer.calculate_cost_for_certificate_batch()

    logging.info('Total cost will be %d satoshis', transaction_cost)

    # ensure the issuing address has sufficient balance
    balance = connector.get_balance(issuing_address)

    if transaction_cost > balance:
        error_message = 'Please add {} satoshis to the address {}'.format(
            transaction_cost - balance, issuing_address)
        logging.error(error_message)
        raise InsufficientFundsError(error_message)

    # issue the certificates on the blockchain
    logging.info('Issuing the certificates on the blockchain')
    issuer.issue_on_blockchain(revocation_address=revocation_address)

    blockcerts_tmp_dir = os.path.join(work_dir,
                                      helpers.BLOCKCHAIN_CERTIFICATES_DIR)
    if not os.path.exists(blockcerts_dir):
        os.makedirs(blockcerts_dir)
    for item in os.listdir(blockcerts_tmp_dir):
        s = os.path.join(blockcerts_tmp_dir, item)
        d = os.path.join(blockcerts_dir, item)
        shutil.copy2(s, d)

    logging.info('Your Blockchain Certificates are in %s', blockcerts_dir)
    return blockcerts_dir
def main(app_config, secure_signer=None):
    unsigned_certs_dir = app_config.unsigned_certificates_dir
    signed_certs_dir = app_config.signed_certificates_dir
    blockchain_certificates_dir = app_config.blockchain_certificates_dir
    work_dir = app_config.work_dir
    v2 = app_config.v2
    issuing_address = app_config.issuing_address
    revocation_address = app_config.revocation_address  # not needed for v2

    certificates, batch_metadata = helpers.prepare_issuance_batch(
        unsigned_certs_dir, signed_certs_dir, blockchain_certificates_dir,
        work_dir)
    logging.info('Processing %d certificates under work path=%s',
                 len(certificates), work_dir)

    logging.info('Signing certificates...')
    if not secure_signer:
        secure_signer = secure_signer_helper.initialize_secure_signer(
            app_config)
    connector = ServiceProviderConnector(app_config.bitcoin_chain)
    tx_constants = TransactionCostConstants(app_config.tx_fee,
                                            app_config.dust_threshold,
                                            app_config.satoshi_per_byte)

    if v2:
        certificate_handler = CertificateV2Handler()
        transaction_handler = TransactionV2Handler(
            tx_cost_constants=tx_constants, issuing_address=issuing_address)
    else:
        certificate_handler = CertificateV1_2Handler()
        transaction_handler = TransactionV1_2Handler(
            tx_cost_constants=tx_constants,
            issuing_address=issuing_address,
            certificates_to_issue=certificates,
            revocation_address=revocation_address)
    certificate_batch_handler = CertificateBatchHandler(
        certificates_to_issue=certificates,
        certificate_handler=certificate_handler)
    issuer = Issuer(issuing_address=issuing_address,
                    connector=connector,
                    secure_signer=secure_signer,
                    certificate_batch_handler=certificate_batch_handler,
                    transaction_handler=transaction_handler)
    transaction_cost = issuer.calculate_cost_for_certificate_batch()
    logging.info('Total cost will be %d satoshis', transaction_cost)

    # ensure the issuing address has sufficient balance
    balance = connector.get_balance(issuing_address)

    if transaction_cost > balance:
        error_message = 'Please add {} satoshis to the address {}'.format(
            transaction_cost - balance, issuing_address)
        logging.error(error_message)
        raise InsufficientFundsError(error_message)

    tx_id = issuer.issue_certificates()

    blockcerts_tmp_dir = os.path.join(work_dir,
                                      helpers.BLOCKCHAIN_CERTIFICATES_DIR)
    if not os.path.exists(blockchain_certificates_dir):
        os.makedirs(blockchain_certificates_dir)
    for item in os.listdir(blockcerts_tmp_dir):
        s = os.path.join(blockcerts_tmp_dir, item)
        d = os.path.join(blockchain_certificates_dir, item)
        shutil.copy2(s, d)

    logging.info('Your Blockchain Certificates are in %s',
                 blockchain_certificates_dir)
    return tx_id