Example #1
0
def validate_data_provider(ctx, param, value):
    """ Validates the data provider sent in via the CLI.

    Args:
        ctx (Click context): Click context object.
        param (str): Parameter that is being validated.
        value (str): Parameter value.
    """
    data_provider_params = {}
    if ctx.obj is None:
        ctx.obj = {}

    if value not in REQUIRED_DATA_PROVIDER_PARAMS:
        ctx.fail("Unknown data provider %s" % value)

    required = REQUIRED_DATA_PROVIDER_PARAMS[value]

    fail = False
    for r in required:
        if r not in ctx.params:
            s = r.replace('_', '-')
            click.echo("--%s is required to use %s." % (s, value))
            fail = True
        else:
            data_provider_params[r] = ctx.params[r]

    if fail:
        ctx.fail("One or more required arguments are missing.")

    dp = None
    if value == 'insight':
        url = ctx.params['insight_url']
        api_path = ctx.params['insight_api_path']
        dp = InsightProvider(insight_host_name=url, insight_api_path=api_path)
    elif value == 'twentyone':
        dp = TwentyOneProvider()

    ctx.obj['data_provider'] = dp
    ctx.obj['data_provider_params'] = data_provider_params
Example #2
0
 def __init__(self, wallet, db=None, db_dir=None):
     """Initialize payment handling for on-chain payments."""
     self.db = db or OnChainSQLite3(db_dir=db_dir)
     self.address = wallet.get_payout_address()
     self.provider = TwentyOneProvider(two1.TWO1_PROVIDER_HOST)
Example #3
0
class OnChain(PaymentBase):
    """Making a payment on the bitcoin blockchain."""

    lock = threading.Lock()
    http_payment_data = 'Bitcoin-Transaction'
    http_402_price = 'Price'
    http_402_address = 'Bitcoin-Address'
    DUST_LIMIT = 3000  # dust limit in satoshi

    def __init__(self, wallet, db=None, db_dir=None):
        """Initialize payment handling for on-chain payments."""
        self.db = db or OnChainSQLite3(db_dir=db_dir)
        self.address = wallet.get_payout_address()
        self.provider = TwentyOneProvider(two1.TWO1_PROVIDER_HOST)

    @property
    def payment_headers(self):
        """List of headers to use for payment processing."""
        return [OnChain.http_payment_data]

    def get_402_headers(self, price, **kwargs):
        """Dict of headers to return in the initial 402 response."""
        return {
            OnChain.http_402_price: price,
            OnChain.http_402_address: kwargs.get('address', self.address)
        }

    def redeem_payment(self, price, request_headers, **kwargs):
        """Validate the transaction and broadcast it to the blockchain."""
        raw_tx = request_headers[OnChain.http_payment_data]
        logger.debug('[BitServ] Receieved transaction: {}'.format(raw_tx))

        # verify txn is above dust limit
        if price < OnChain.DUST_LIMIT:
            raise PaymentBelowDustLimitError(
                'Payment amount is below dust limit ({} Satoshi)'.format(
                    OnChain.DUST_LIMIT))

        try:
            payment_tx = Transaction.from_hex(raw_tx)
        except:
            raise InvalidPaymentParameterError('Invalid transaction hex.')

        # Find the output with the merchant's address
        payment_index = payment_tx.output_index_for_address(
            kwargs.get('address', self.address))
        if payment_index is None:
            raise InvalidPaymentParameterError('Not paid to merchant.')

        # Verify that the payment is made for the correct amount
        if payment_tx.outputs[payment_index].value != price:
            raise InsufficientPaymentError('Incorrect payment amount.')

        # Synchronize the next block of code to manage its atomicity
        with self.lock:
            # Verify that we haven't seen this transaction before
            if self.db.lookup(str(payment_tx.hash)):
                raise DuplicatePaymentError('Payment already used.')
            else:
                self.db.create(str(payment_tx.hash), price)

            try:
                # Broadcast payment to network
                txid = self.provider.broadcast_transaction(raw_tx)
                logger.debug('[BitServ] Broadcasted: ' + txid)
            except Exception as e:
                # Roll back the database entry if the broadcast fails
                self.db.delete(str(payment_tx.hash))
                raise TransactionBroadcastError(str(e))

        return True
Example #4
0
import pytest
from two1.bitcoin.crypto import HDPublicKey
from two1.bitcoin.txn import Transaction
from two1.blockchain.twentyone_provider import TwentyOneProvider
from two1.blockchain.exceptions import DataProviderError

acct_pub_key = HDPublicKey.from_b58check(
    "xpub68YdQASJ3w2RYS7XNT8HkLVjWqKeMD5uAxJR2vqXAh65j7izto1cVSwCNm7awAjjeYExqneCAZzt5xGETXZz1EXa9HntM5HzwdQ9551UErA"
)

twentyone_provider = TwentyOneProvider()
stage_twentyone_provider = TwentyOneProvider("http://blockchain.21-stage.co")


@pytest.mark.parametrize("provider, testnet", [
    (twentyone_provider, False),
    (twentyone_provider, True),
    (stage_twentyone_provider, False),
])
def test_get_transactions(provider, testnet):
    cp = provider
    cp.testnet = testnet
    if testnet:
        address_list = ["myTpteaBCwuHsDsoBQfrN4YjKEBpmoLBii"]
        data = cp.get_transactions(address_list)
        exp = (1, 2)
    else:
        address_list = ["1K4nPxBMy6sv7jssTvDLJWk1ADHBZEoUVb"]
        data = cp.get_transactions(address_list)
        exp = (1, 9)
Example #5
0
import time

import random
from two1.blockchain.twentyone_provider import TwentyOneProvider
from two1.wallet.two1_wallet import Two1Wallet

mnemonics = ['absent paddle capable spell bag reflect rally there swear swallow cook rubber',
             'stairs art mirror spoon clap talk exclude tuna absurd exact grape relief',
             'poem into dune liar already rain swear thunder spread kangaroo monster wise',
             'business lyrics news image duty stone clerk salad harvest shallow follow evoke',
             'another student leg ladder jeans hello cluster type network wrist before sense']

cp = TwentyOneProvider()

# Create wallet objects
wallets = [Two1Wallet.import_from_mnemonic(data_provider=cp,
                                           mnemonic=m,
                                           account_type='BIP32')
           for m in mnemonics]

max_balance_index = -1
max_balance = 0
for i, w in enumerate(wallets):
    balance = w.balances

    if balance['confirmed'] > max_balance:
        max_balance = balance['confirmed']
        max_balance_index = i

    print("\nWallet %d:" % i)
    print("----------")
Example #6
0
 def __init__(self, wallet, db=None, db_dir=None):
     """Initialize payment handling for on-chain payments."""
     self.db = db or OnChainSQLite3(db_dir=db_dir)
     self.address = wallet.get_payout_address()
     self.provider = TwentyOneProvider(two1.TWO1_PROVIDER_HOST)
Example #7
0
class OnChain(PaymentBase):

    """Making a payment on the bitcoin blockchain."""

    lock = threading.Lock()
    http_payment_data = 'Bitcoin-Transaction'
    http_402_price = 'Price'
    http_402_address = 'Bitcoin-Address'
    DUST_LIMIT = 3000  # dust limit in satoshi

    def __init__(self, wallet, db=None, db_dir=None):
        """Initialize payment handling for on-chain payments."""
        self.db = db or OnChainSQLite3(db_dir=db_dir)
        self.address = wallet.get_payout_address()
        self.provider = TwentyOneProvider(two1.TWO1_PROVIDER_HOST)

    @property
    def payment_headers(self):
        """List of headers to use for payment processing."""
        return [OnChain.http_payment_data]

    def get_402_headers(self, price, **kwargs):
        """Dict of headers to return in the initial 402 response."""
        return {OnChain.http_402_price: price,
                OnChain.http_402_address: kwargs.get('address', self.address)}

    def redeem_payment(self, price, request_headers, **kwargs):
        """Validate the transaction and broadcast it to the blockchain."""
        raw_tx = request_headers[OnChain.http_payment_data]
        logger.debug('[BitServ] Receieved transaction: {}'.format(raw_tx))

        # verify txn is above dust limit
        if price < OnChain.DUST_LIMIT:
            raise PaymentBelowDustLimitError(
                'Payment amount is below dust limit ({} Satoshi)'.format(OnChain.DUST_LIMIT))

        try:
            payment_tx = Transaction.from_hex(raw_tx)
        except:
            raise InvalidPaymentParameterError('Invalid transaction hex.')

        # Find the output with the merchant's address
        payment_index = payment_tx.output_index_for_address(kwargs.get('address', self.address))
        if payment_index is None:
            raise InvalidPaymentParameterError('Not paid to merchant.')

        # Verify that the payment is made for the correct amount
        if payment_tx.outputs[payment_index].value != price:
            raise InsufficientPaymentError('Incorrect payment amount.')

        # Synchronize the next block of code to manage its atomicity
        with self.lock:
            # Verify that we haven't seen this transaction before
            if self.db.lookup(str(payment_tx.hash)):
                raise DuplicatePaymentError('Payment already used.')
            else:
                self.db.create(str(payment_tx.hash), price)

            try:
                # Broadcast payment to network
                txid = self.provider.broadcast_transaction(raw_tx)
                logger.debug('[BitServ] Broadcasted: ' + txid)
            except Exception as e:
                # Roll back the database entry if the broadcast fails
                self.db.delete(str(payment_tx.hash))
                raise TransactionBroadcastError(str(e))

        return True
Example #8
0
from two1.bitcoin.crypto import HDPublicKey, PublicKey
from two1.bitcoin.txn import Transaction
from two1.blockchain.twentyone_provider import TwentyOneProvider
from two1.bitcoin.script import Script
from two1.commands.util.currency import Price
from two1.bitcoin.utils import bytes_to_str
from two1.wallet.base_wallet import convert_to_satoshis

with open('{}/.two1/wallet/default_wallet.json'.format(
        expanduser('~'))) as data_file:
    wallet_data = json.load(data_file)

wallet = None
wallet = wallet or Two1Wallet.import_from_mnemonic(
    mnemonic=wallet_data['master_seed'])
provider = TwentyOneProvider()


def execute(wallet_method):
    methodToCall = getattr(wallet, wallet_method)
    result = json.dumps({wallet_method: methodToCall()})
    print(result)


# Loop through methods
del sys.argv[0]
if sys.argv[0] == 'sign':
    pubkey = HDPublicKey.from_hex(sys.argv[1])
    server_privkey = wallet.get_private_for_public(pubkey)
    tx = Transaction.from_hex(sys.argv[2])
    script = Script.from_hex(sys.argv[3])
Example #9
0
import pytest
from unittest.mock import MagicMock
from two1.bitcoin.crypto import HDPublicKey
from two1.bitcoin.txn import Transaction
from two1.blockchain.insight_provider import InsightProvider
from two1.blockchain.twentyone_provider import TwentyOneProvider
from two1.blockchain.exceptions import DataProviderError

acct_pub_key = HDPublicKey.from_b58check(
    "xpub68YdQASJ3w2RYS7XNT8HkLVjWqKeMD5uAxJR2vqXAh65j7izto1cVSwCNm7awAjjeYExqneCAZzt5xGETXZz1EXa9HntM5HzwdQ9551UErA"
)

twentyone_provider = TwentyOneProvider()
insight_provider = InsightProvider("http://blockchain.21-stage.co:3001",
                                   insight_api_path="insight-api")


@pytest.mark.parametrize("provider, testnet", [
    (twentyone_provider, False),
    (insight_provider, False),
])
def test_get_transactions(provider, testnet):
    cp = provider
    cp.testnet = testnet
    if testnet:
        address_list = ["myTpteaBCwuHsDsoBQfrN4YjKEBpmoLBii"]
        data = cp.get_transactions(address_list)
        exp = (1, 2)
    else:
        address_list = ["1K4nPxBMy6sv7jssTvDLJWk1ADHBZEoUVb"]
        data = cp.get_transactions(address_list)
Example #10
0
#!/usr/bin/env python3

from two1.wallet.two1_wallet import Two1Wallet
from two1.blockchain.twentyone_provider import TwentyOneProvider
from two1.bitcoin import utils
from two1.bitcoin import Script
from two1.bitcoin import Transaction, TransactionInput, TransactionOutput

# Create application objects

wallet = Two1Wallet(Two1Wallet.DEFAULT_WALLET_PATH, TwentyOneProvider())


def write_ew_message(msg):
    """Write a message to the blockchain."""
    print("write_ew_message({})" % msg)

    # Create a bitcoin script object with our message
    if len(msg) > 72:
        raise Exception('Message is too long and may not be accepted.')
    msg = "EW " + msg
    message_script = Script('OP_RETURN 0x{}'.format(utils.bytes_to_str(msg.encode())))

    # Define the fee we're willing to pay for the tx
    tx_fee = 11000

    # Get the first UTXO from our set that can cover the fee
    utxo = None
    for utxo_addr, utxos in wallet.get_utxos().items():
        for u in utxos:
            if u.value > tx_fee: