Example #1
0
def add_metadata_to_tx(request, coin_symbol, tx_hash):
    if not is_valid_hash(tx_hash):
        return Http404

    initial = {}
    form = BaseMetadataForm(initial=initial)
    if request.method == 'POST':
        form = BaseMetadataForm(data=request.POST)
        if form.is_valid():
            metadata_key = form.cleaned_data.get('metadata_key')
            metadata_value = form.cleaned_data.get('metadata_value')

            results = put_metadata(
                    metadata_dict={metadata_key: metadata_value},
                    tx_hash=tx_hash,
                    coin_symbol=coin_symbol,
                    api_key=BLOCKCYPHER_API_KEY,
                    private=False,
                    )

            # import pprint; pprint.pprint(results, width=1)

            if results is True:
                msg = _('<pre>%(key)s</pre>-><pre>%(value)s</pre> succesfully uploaded to %(upload_string)s (<a href="#metadata">scroll down</a>)' % {
                    'key': metadata_key,
                    'value': metadata_value,
                    'upload_string': tx_hash,
                    })
                messages.success(request, msg, extra_tags='safe')
                redir_url = reverse(
                    'transaction_overview',
                    kwargs={
                        'coin_symbol': coin_symbol,
                        'tx_hash': tx_hash,
                        },
                    )
                return HttpResponseRedirect(redir_url)
            elif 'error' in results:
                messages.warning(request, results.get('error'))
            elif 'errors' in results:
                for error in results.get('errors'):
                    messages.warning(request, error)

    elif request.method == 'GET':
        # Preseed tx hex if passed through GET string
        key = request.GET.get('k')
        value = request.GET.get('v')
        if key:
            initial['metadata_key'] = key
        if value:
            initial['metadata_value'] = value
        if key or value:
            form = BaseMetadataForm(initial=initial)
    return {
            'form': form,
            'is_input_page': True,
            'coin_symbol': coin_symbol,
            'tx_hash': tx_hash,
            }
Example #2
0
def add_metadata_to_tx(request, coin_symbol, tx_hash):
    if not is_valid_hash(tx_hash):
        return Http404

    initial = {}
    form = BaseMetadataForm(initial=initial)
    if request.method == 'POST':
        form = BaseMetadataForm(data=request.POST)
        if form.is_valid():
            metadata_key = form.cleaned_data.get('metadata_key')
            metadata_value = form.cleaned_data.get('metadata_value')

            results = put_metadata(
                    metadata_dict={metadata_key: metadata_value},
                    tx_hash=tx_hash,
                    coin_symbol=coin_symbol,
                    api_key=BLOCKCYPHER_API_KEY,
                    private=False,
                    )

            # import pprint; pprint.pprint(results, width=1)

            if results is True:
                msg = _('<pre>%(key)s</pre>-><pre>%(value)s</pre> succesfully uploaded to %(upload_string)s (<a href="#metadata">scroll down</a>)' % {
                    'key': metadata_key,
                    'value': metadata_value,
                    'upload_string': tx_hash,
                    })
                messages.success(request, msg, extra_tags='safe')
                redir_url = reverse(
                    'transaction_overview',
                    kwargs={
                        'coin_symbol': coin_symbol,
                        'tx_hash': tx_hash,
                        },
                    )
                return HttpResponseRedirect(redir_url)
            elif 'error' in results:
                messages.warning(request, results.get('error'))
            elif 'errors' in results:
                for error in results.get('errors'):
                    messages.warning(request, error)

    elif request.method == 'GET':
        # Preseed tx hex if passed through GET string
        key = request.GET.get('k')
        value = request.GET.get('v')
        if key:
            initial['metadata_key'] = key
        if value:
            initial['metadata_value'] = value
        if key or value:
            form = BaseMetadataForm(initial=initial)
    return {
            'form': form,
            'is_input_page': True,
            'coin_symbol': coin_symbol,
            'tx_hash': tx_hash,
            }
Example #3
0
    def clean_search_string(self):
        search_string = self.cleaned_data['search_string'].strip()
        # get rid of non alphanumerics
        search_string = re.sub(r'[^a-zA-Z0-9]+', '', search_string)

        if is_valid_hash(search_string) or is_valid_address(search_string) or is_valid_block_num(search_string):
            return search_string
        else:
            err_msg = _('Not a valid address, transaction hash, or block number')
            raise forms.ValidationError(err_msg)
Example #4
0
    def clean(self):
        where_to_upload = self.cleaned_data.get('where_to_upload')
        upload_string = self.cleaned_data.get('upload_string')
        coin_symbol = self.cleaned_data.get('coin_symbol')
        if not where_to_upload or not upload_string:
            return self.cleaned_data
        if where_to_upload == 'address':
            if not is_valid_address_for_coinsymbol(upload_string, coin_symbol):
                cs_display = COIN_SYMBOL_MAPPINGS[coin_symbol]['display_name']
                msg = _("Sorry, that's not a valid address for %(coin_symbol)s" % {'coin_symbol': cs_display})
                raise forms.ValidationError(msg)
        elif where_to_upload == 'transaction':
            if not is_valid_hash(upload_string):
                msg = _("Sorry, that's not a valid transaction hash")
                raise forms.ValidationError(msg)
        elif where_to_upload == 'block':
            if not is_valid_hash(upload_string):
                msg = _("Sorry, that's not a valid block hash")
                raise forms.ValidationError(msg)
        else:
            raise Exception('Logic Fail: Not Possible')

        return self.cleaned_data
Example #5
0
    def clean_search_string(self):
        search_string = self.cleaned_data['search_string'].strip()
        # process possible Wallet Names
        if is_valid_wallet_name(search_string):
            return search_string

        # get rid of non alphanumerics
        search_string = re.sub(r'[^a-zA-Z0-9]+', '', search_string)

        if is_valid_hash(search_string) or is_valid_address(search_string) or is_valid_block_num(search_string):
            return search_string
        else:
            err_msg = _('Not a valid address, transaction hash, or block number')
            raise forms.ValidationError(err_msg)
Example #6
0
    def clean_search_string(self):
        search_string = self.cleaned_data['search_string'].strip()
        # process possible Wallet Names
        if is_valid_wallet_name(search_string):
            return search_string

        # get rid of non alphanumerics
        if search_string.lower().startswith("0x"):
            search_string = search_string[2:]
        search_string = re.sub(r'[^a-zA-Z0-9]+', '', search_string)
        if is_valid_hash(search_string) or is_valid_address(search_string) or is_valid_eth_address(search_string) or is_valid_block_num(search_string):
            return search_string
        else:
            err_msg = _('Not a valid address, transaction hash, or block number')
            raise forms.ValidationError(err_msg)
Example #7
0
def home(request):
    form = SearchForm(
        initial={
            'search_string': '16Fg2yjwrbtC6fZp61EV9mNVKmwCzGasw5',
            'coin_symbol': 'btc',
        })
    if request.method == 'POST':
        form = SearchForm(data=request.POST)
        if form.is_valid():
            redirect_url = None
            search_string = form.cleaned_data['search_string']
            coin_symbol = form.cleaned_data['coin_symbol']
            kwargs = {'coin_symbol': coin_symbol}
            if is_valid_block_num(search_string):
                kwargs['block_representation'] = search_string
                redirect_url = reverse('block_overview', kwargs=kwargs)
            elif is_valid_hash(search_string):
                if coin_symbol in SHA_COINS:
                    if is_valid_sha_block_hash(search_string):
                        kwargs['block_representation'] = search_string
                        redirect_url = reverse('block_overview', kwargs=kwargs)
                    else:
                        kwargs['tx_hash'] = search_string
                        redirect_url = reverse('transaction_overview',
                                               kwargs=kwargs)
                elif coin_symbol in SCRYPT_COINS:
                    # Try to see if it's a valid TX hash
                    tx_details = get_transaction_details(
                        tx_hash=search_string,
                        coin_symbol=coin_symbol,
                        limit=1,
                        api_key=BLOCKCYPHER_API_KEY,
                    )
                    if 'error' in tx_details:
                        # Not a valid TX hash, see if it's a block hash by checking blockchain
                        block_details = get_block_overview(
                            block_representation=search_string,
                            coin_symbol=coin_symbol,
                            txn_limit=1,
                            api_key=BLOCKCYPHER_API_KEY,
                        )
                        if 'error' in block_details:
                            msg = _(
                                "Sorry, '%(search_string)s' is not a valid transaction or block hash for %(currency)s"
                                % {
                                    'currency': coin_symbol,
                                    'search_string': search_string,
                                })
                            messages.error(request, msg)
                        else:
                            kwargs['block_representation'] = search_string
                            redirect_url = reverse('block_overview',
                                                   kwargs=kwargs)
                    else:
                        kwargs['tx_hash'] = search_string
                        redirect_url = reverse('transaction_overview',
                                               kwargs=kwargs)

            elif is_valid_address(search_string):
                # It's an address
                kwargs['address'] = search_string
                first_char = search_string[0]
                # Override coin_symbol if we can infer it from the blockchain
                # There is now generic constants in the python library (constants.py)
                # Not migrating because this is custom (those constants have overlap/ambiguity)
                if first_char in ('1', ):
                    # Do not force addresses starting with 3 to be BTC because that's also used by LTC
                    kwargs['coin_symbol'] = 'btc'
                elif first_char in ('m', 'n', '2'):
                    # Note that addresses starting in 2 can be LTC testnet, but since we don't support that it's okay to include
                    kwargs['coin_symbol'] = 'btc-testnet'
                elif first_char in ('9', 'A'):
                    kwargs['coin_symbol'] = 'doge'
                elif first_char in ('L', ):
                    # Do not force addresses starting with 3 to be LTC because that's also used by BTC
                    kwargs['coin_symbol'] = 'ltc'
                elif first_char in ('B', 'C'):
                    kwargs['coin_symbol'] = 'bcy'

                redirect_url = reverse('address_overview', kwargs=kwargs)

            elif is_valid_wallet_name(search_string):
                addr = lookup_wallet_name(search_string, kwargs['coin_symbol'])
                if addr:
                    kwargs['address'] = addr
                    kwargs['wallet_name'] = search_string
                    redirect_url = reverse('address_overview', kwargs=kwargs)
                else:
                    msg = _("Sorry, that's not a valid wallet name")
                    messages.error(request, msg)

            if redirect_url:
                return HttpResponseRedirect(redirect_url)

        else:
            currency = COIN_SYMBOL_MAPPINGS[
                request.POST['coin_symbol']]['display_shortname']
            msg = _(
                "Sorry, '%(search_string)s' is not a valid %(currency)s address, wallet name, transaction or block"
                % {
                    'currency': currency,
                    'search_string': request.POST['search_string'],
                })
            messages.error(request, msg)

    return {'is_home': True, 'form': form}
Example #8
0
 def test_invalid_hash(self):
     assert not is_valid_hash(self.invalid_hash), self.invalid_hash
Example #9
0
 def test_valid_hash(self):
     assert is_valid_hash(self.valid_hash), self.valid_hash
 def test_invalid_hash(self):
     assert not is_valid_hash(self.invalid_hash), self.invalid_hash
 def test_valid_hash(self):
     assert is_valid_hash(self.valid_hash), self.valid_hash
Example #12
0
def block_overview(request, coin_symbol, block_representation):

    TXNS_PER_PAGE = 20

    # 1 indexed page
    current_page = request.GET.get('page')
    if current_page:
        current_page = int(current_page)
    else:
        current_page = 1

    # TODO: fail gracefully if the user picks a number of pages that is too large
    # Waiting on @matthieu's change to API first (currently throws 502)

    try:
        if not is_valid_hash(block_representation):
            # it's a block num, we want this as a hash
            block_hash = get_block_hash(
                block_height=block_representation,
                coin_symbol=coin_symbol,
                api_key=BLOCKCYPHER_API_KEY,
            )
            kwargs = {
                'coin_symbol': coin_symbol,
                'block_representation': block_hash,
            }
            redir_url = reverse('block_overview', kwargs=kwargs)
            return HttpResponseRedirect(redir_url)

        block_details = get_block_details(
            block_representation=block_representation,
            coin_symbol=coin_symbol,
            txn_limit=TXNS_PER_PAGE,
            in_out_limit=25,
            txn_offset=(current_page - 1) * TXNS_PER_PAGE,
            api_key=BLOCKCYPHER_API_KEY,
        )
    except AssertionError:
        msg = _('Invalid Block Representation')
        messages.warning(request, msg)
        redir_url = reverse('coin_overview',
                            kwargs={'coin_symbol': coin_symbol})
        return HttpResponseRedirect(redir_url)

    # import pprint; pprint.pprint(block_details, width=1)

    if 'error' in block_details:
        msg = _('Sorry, that block was not found')
        messages.warning(request, msg)
        messages.warning(request, block_details['error'])
        return HttpResponseRedirect(reverse('home'))

    # Technically this is not the only API call used on this page
    api_url = 'https://api.blockcypher.com/v1/%s/%s/blocks/%s' % (
        COIN_SYMBOL_MAPPINGS[coin_symbol]['blockcypher_code'],
        COIN_SYMBOL_MAPPINGS[coin_symbol]['blockcypher_network'],
        block_representation,
    )

    return {
        'coin_symbol':
        coin_symbol,
        'api_url':
        api_url,
        'block_details':
        block_details,
        'current_page':
        current_page,
        'max_pages':
        get_max_pages(num_items=block_details['n_tx'],
                      items_per_page=TXNS_PER_PAGE),
    }
Example #13
0
def home(request):
    form = SearchForm(initial={
        'search_string': '16Fg2yjwrbtC6fZp61EV9mNVKmwCzGasw5',
        'coin_symbol': 'btc',
        })
    if request.method == 'POST':
        form = SearchForm(data=request.POST)
        if form.is_valid():
            redirect_url = None
            search_string = form.cleaned_data['search_string']
            coin_symbol = form.cleaned_data['coin_symbol']
            kwargs = {'coin_symbol': coin_symbol}
            if is_valid_block_num(search_string):
                kwargs['block_representation'] = search_string
                redirect_url = reverse('block_overview', kwargs=kwargs)
            elif is_valid_hash(search_string):
                if coin_symbol in SHA_COINS:
                    if is_valid_sha_block_hash(search_string):
                        kwargs['block_representation'] = search_string
                        redirect_url = reverse('block_overview', kwargs=kwargs)
                    else:
                        kwargs['tx_hash'] = search_string
                        redirect_url = reverse('transaction_overview', kwargs=kwargs)
                elif coin_symbol in SCRYPT_COINS:
                    # Try to see if it's a valid TX hash
                    tx_details = get_transaction_details(
                            tx_hash=search_string,
                            coin_symbol=coin_symbol,
                            limit=1,
                            api_key=BLOCKCYPHER_API_KEY,
                            )
                    if 'error' in tx_details:
                        # Not a valid TX hash, see if it's a block hash by checking blockchain
                        block_details = get_block_overview(
                                block_representation=search_string,
                                coin_symbol=coin_symbol,
                                txn_limit=1,
                                api_key=BLOCKCYPHER_API_KEY,
                                )
                        if 'error' in block_details:
                            msg = _("Sorry, that's not a valid transaction or block hash for %(currency)s" % {'currency': coin_symbol})
                            messages.error(request, msg)
                        else:
                            kwargs['block_representation'] = search_string
                            redirect_url = reverse('block_overview', kwargs=kwargs)
                    else:
                        kwargs['tx_hash'] = search_string
                        redirect_url = reverse('transaction_overview', kwargs=kwargs)

            elif is_valid_address(search_string):
                # It's an address
                kwargs['address'] = search_string
                first_char = search_string[0]
                # Override coin_symbol if we can infer it from the blockchain
                # There is now generic constants in the python library (constants.py)
                # Not migrating because this is custom (those constants have overlap/ambiguity)
                if first_char in ('1', ):
                    # Do not force addresses starting with 3 to be BTC because that's also used by LTC
                    kwargs['coin_symbol'] = 'btc'
                elif first_char in ('m', 'n', '2'):
                    # Note that addresses starting in 2 can be LTC testnet, but since we don't support that it's okay to include
                    kwargs['coin_symbol'] = 'btc-testnet'
                elif first_char in ('9', 'A'):
                    kwargs['coin_symbol'] = 'doge'
                elif first_char in ('L', ):
                    # Do not force addresses starting with 3 to be LTC because that's also used by BTC
                    kwargs['coin_symbol'] = 'ltc'
                elif first_char in ('U', ):
                    kwargs['coin_symbol'] = 'uro'
                elif first_char in ('B', 'C'):
                    kwargs['coin_symbol'] = 'bcy'

                redirect_url = reverse('address_overview', kwargs=kwargs)

            elif is_valid_wallet_name(search_string):
                addr = lookup_wallet_name(search_string, kwargs['coin_symbol'])
                if addr:
                    kwargs['address'] = addr
                    kwargs['wallet_name'] = search_string
                    redirect_url = reverse('address_overview', kwargs=kwargs)
                else:
                    msg = _("Sorry, that's not a valid wallet name")
                    messages.error(request, msg)

            if redirect_url:
                return HttpResponseRedirect(redirect_url)

        else:
            currency = COIN_SYMBOL_MAPPINGS[request.POST['coin_symbol']]['display_shortname']
            msg = _("Sorry, that's not a valid %(currency)s address, wallet name, transaction or block" % {
                'currency': currency})
            messages.error(request, msg)

    return {
        'is_home': True,
        'form': form
    }
Example #14
0
def get_tx_url(tx_hash, coin_symbol):
    assert is_valid_coin_symbol(coin_symbol), coin_symbol
    assert is_valid_hash(tx_hash), tx_hash
    return 'https://live.blockcypher.com/%s/tx/%s/' % (coin_symbol, tx_hash)
Example #15
0
def get_tx_url(tx_hash, coin_symbol):
    assert is_valid_coin_symbol(coin_symbol), coin_symbol
    assert is_valid_hash(tx_hash), tx_hash
    return 'https://live.blockcypher.com/%s/tx/%s/' % (coin_symbol, tx_hash)
Example #16
0
def block_overview(request, coin_symbol, block_representation):

    TXNS_PER_PAGE = 20

    # 1 indexed page
    current_page = request.GET.get('page')
    if current_page:
        current_page = int(current_page)
    else:
        current_page = 1

    # TODO: fail gracefully if the user picks a number of pages that is too large
    # Waiting on @matthieu's change to API first (currently throws 502)

    try:
        if not is_valid_hash(block_representation):
            # it's a block num, we want this as a hash
            block_hash = get_block_hash(
                    block_height=block_representation,
                    coin_symbol=coin_symbol,
                    api_key=BLOCKCYPHER_API_KEY,
                    )
            kwargs = {
                    'coin_symbol': coin_symbol,
                    'block_representation': block_hash,
                    }
            redir_url = reverse('block_overview', kwargs=kwargs)
            return HttpResponseRedirect(redir_url)

        block_details = get_block_details(
                block_representation=block_representation,
                coin_symbol=coin_symbol,
                txn_limit=TXNS_PER_PAGE,
                in_out_limit=25,
                txn_offset=(current_page-1)*TXNS_PER_PAGE,
                api_key=BLOCKCYPHER_API_KEY,
                )
    except AssertionError:
        msg = _('Invalid Block Representation')
        messages.warning(request, msg)
        redir_url = reverse('coin_overview', kwargs={'coin_symbol': coin_symbol})
        return HttpResponseRedirect(redir_url)

    # import pprint; pprint.pprint(block_details, width=1)

    if 'error' in block_details:
        msg = _('Sorry, that block was not found')
        messages.warning(request, msg)
        messages.warning(request, block_details['error'])
        return HttpResponseRedirect(reverse('home'))

    # Technically this is not the only API call used on this page
    api_url = 'https://api.blockcypher.com/v1/%s/%s/blocks/%s' % (
            COIN_SYMBOL_MAPPINGS[coin_symbol]['blockcypher_code'],
            COIN_SYMBOL_MAPPINGS[coin_symbol]['blockcypher_network'],
            block_representation,
            )

    return {
            'coin_symbol': coin_symbol,
            'api_url': api_url,
            'block_details': block_details,
            'current_page': current_page,
            'max_pages': get_max_pages(num_items=block_details['n_tx'], items_per_page=TXNS_PER_PAGE),
            }