Beispiel #1
0
def get_addrs_from_paymentrequest(pr):

    ret_list = []
    pr_obj = PaymentRequest()
    pr_obj.ParseFromString(pr)

    pd = PaymentDetails()
    pd.ParseFromString(pr_obj.serialized_payment_details)

    for output in pd.outputs:
        script = deserialize_script(output.script)
        if script[0] == OP_DUP and script[1] == OP_HASH160 and script[3] == OP_EQUALVERIFY and script[4] == OP_CHECKSIG:
            ret_list.append(hex_to_b58check(script[2].encode('hex')))

    return ret_list
Beispiel #2
0
    def create_and_send_payment_message(self, payment_request):
        pr = PaymentRequest()
        pr.ParseFromString(payment_request)

        pd = PaymentDetails()
        pd.ParseFromString(pr.serialized_payment_details)

        # Retrieve unique payment_url created by Addressimo and replace with Flask LiveServerTestCase server URL
        payment_uuid = pd.payment_url.rsplit('/', 1)[1]
        payment_url = '%s/payment/%s' % (self.get_server_url(), payment_uuid)

        # Add to payment_uuid Redis cleanup list
        self.redis_pr_store_cleanup.append(payment_uuid)

        # Create Payment output to satisfy PaymentRequest
        priv = sha256('random')
        ins = [{
            'output':
            '35d49e1833a20baffae35fb1423427d0c23e83b428a933eebde95ac7fd1c967a:0',
            'value': 10000,
            'script': 'random_script'
        }]
        outs = [{
            'value': pd.outputs[0].amount,
            'address': '%s' % script_to_address(pd.outputs[0].script)
        }]
        tx = sign(mktx(ins, outs), 0, priv)

        refund_address = '1CpLXM15vjULK3ZPGUTDMUcGATGR9xGitv'

        self.payment = Payment()
        self.payment.merchant_data = pd.merchant_data
        self.payment.memo = 'Payment memo'
        self.payment.transactions.append(tx)

        output = self.payment.refund_to.add()
        output.amount = pd.outputs[0].amount
        output.script = serialize_script([
            OP_DUP, OP_HASH160,
            b58check_to_hex(refund_address), OP_EQUALVERIFY, OP_CHECKSIG
        ]).decode('hex')

        # Set appropriate headers for Payment
        headers = {
            'Content-Type': 'application/bitcoin-payment',
            'Accept': 'application/bitcoin-paymentack',
            'Test-Transaction': True
        }

        response = requests.post(payment_url,
                                 data=self.payment.SerializeToString(),
                                 headers=headers)

        #######################
        # Validation
        #######################

        # PaymentRequest data used for Payment Creation
        self.assertTrue(
            pd.payment_url.startswith('https://%s/payment/' % config.site_url))
        self.assertEqual((33000 * 100000000), pd.outputs[0].amount)
        self.assertEqual(payment_uuid, pd.merchant_data)

        # PaymentRequest meta data used later for Payment validation
        pr_redis = Redis.from_url(config.redis_pr_store)
        pr_data = pr_redis.hgetall(payment_uuid)

        self.assertIsNotNone(pr_data.get('expiration_date'))
        payment_data = json.loads(pr_data.get('payment_validation_data'))
        self.assertEqual(self.test_id_obj.wallet_address,
                         payment_data.keys()[0])
        self.assertEqual((33000 * 100000000),
                         payment_data[self.test_id_obj.wallet_address])

        # Payment meta data used for refund endpoint
        payment_redis = Redis.from_url(config.redis_payment_store)
        payment_data = payment_redis.hgetall('testtxhash')

        self.assertIsNotNone(payment_data.get('expiration_date'))
        self.assertEqual('Payment memo', payment_data.get('memo'))
        self.assertEqual(
            "['76a914819d3b204b99f252da2ef21293c621e75dd1444f88ac']",
            payment_data.get('refund_to'))

        return response
Beispiel #3
0
    def add():

        resolver = PluginManager.get_plugin('RESOLVER', config.resolver_type)
        id_obj = resolver.get_id_obj(get_id())
        if not id_obj:
            return create_json_response(False, 'Invalid Identifier', 404)

        rdata = None
        try:
            rdata = request.get_json()
        except Exception as e:
            log.warn("Exception Parsing JSON: %s" % str(e))
            return create_json_response(False, 'Invalid Request', 400)

        if not rdata:
            return create_json_response(False, 'Invalid Request', 400)

        pr_list = rdata.get('presigned_payment_requests')

        if not pr_list:
            return create_json_response(
                False, 'Missing presigned_payment_requests data', 400)

        if not isinstance(pr_list, list):
            return create_json_response(
                False, 'presigned_payment_requests data must be a list', 400)

        # Validate PaymentRequests
        for pr in pr_list:

            try:
                int(pr, 16)
            except ValueError:
                return create_json_response(
                    False, 'Payment Request Must Be Hex Encoded', 400)

            verify_pr = PaymentRequest()
            try:

                hex_decoded_pr = pr.decode('hex')
                if len(hex_decoded_pr) > PAYMENT_REQUEST_SIZE_MAX:
                    log.warn(
                        'Rejecting Payment Request for Size [ACCEPTED: %d bytes | ACTUAL: %d bytes]'
                        % (PAYMENT_REQUEST_SIZE_MAX, len(hex_decoded_pr)))
                    return create_json_response(
                        False, 'Invalid Payment Request Submitted', 400)

                verify_pr.ParseFromString(hex_decoded_pr)
            except Exception as e:
                log.warn(
                    'Unable to Parse Submitted Payment Request [ID: %s]: %s' %
                    (id_obj.id, str(e)))
                return create_json_response(
                    False, 'Invalid Payment Request Submitted', 400)

            verify_pd = PaymentDetails()
            try:
                verify_pd.ParseFromString(verify_pr.serialized_payment_details)
            except Exception as e:
                log.warn(
                    'Unable to Parse Submitted Payment Request [ID: %s]: %s' %
                    (id_obj.id, str(e)))
                return create_json_response(
                    False, 'Invalid Payment Request Submitted', 400)

        # Validated!
        add_count = 0
        for pr in pr_list:
            id_obj.presigned_payment_requests.append(pr)
            add_count += 1
            if add_count == config.presigned_pr_limit:
                log.info('Presigned Payment Limit Reached [ID: %s]' %
                         id_obj.id)
                break

        log.info('Added %d Pre-Signed Payment Requests [ID: %s]' %
                 (add_count, id_obj.id))
        resolver.save(id_obj)

        return create_json_response(data={'payment_requests_added': add_count})