electrum-bitcoinprivate/lib/contacts.py

93 lines
2.8 KiB
Python
Raw Normal View History

2015-07-02 03:44:53 -07:00
import sys
import re
import dns
import traceback
import bitcoin
from util import StoreDict, print_error
from i18n import _
class Contacts(StoreDict):
def __init__(self, config):
StoreDict.__init__(self, config, 'contacts')
def resolve(self, k):
if bitcoin.is_address(k):
return {
'address': k,
'type': 'address'
}
if k in self.keys():
_type, addr = self[k]
if _type == 'address':
return {
'address': addr,
'type': 'contact'
}
out = self.resolve_openalias(k)
if out:
address, name = out
2015-07-08 06:14:00 -07:00
validated = False
2015-07-02 03:44:53 -07:00
return {
'address': address,
'name': name,
'type': 'openalias',
'validated': validated
}
raise Exception("Invalid Bitcoin address or alias", k)
def resolve_openalias(self, url):
'''Resolve OpenAlias address using url.'''
print_error('[OA] Attempting to resolve OpenAlias data for ' + url)
url = url.replace('@', '.') # support email-style addresses, per the OA standard
prefix = 'btc'
retries = 3
err = None
for i in range(0, retries):
try:
resolver = dns.resolver.Resolver()
resolver.timeout = 2.0
resolver.lifetime = 4.0
records = resolver.query(url, dns.rdatatype.TXT)
for record in records:
string = record.strings[0]
if string.startswith('oa1:' + prefix):
address = self.find_regex(string, r'recipient_address=([A-Za-z0-9]+)')
name = self.find_regex(string, r'recipient_name=([^;]+)')
if not name:
name = address
if not address:
continue
return (address, name)
err = _('No OpenAlias record found.')
break
except dns.resolver.NXDOMAIN:
err = _('No such domain.')
continue
except dns.resolver.Timeout:
err = _('Timed out while resolving.')
continue
except DNSException:
err = _('Unhandled exception.')
continue
except Exception, e:
err = _('Unexpected error: ' + str(e))
continue
break
if err:
print_error(err)
return 0
def find_regex(self, haystack, needle):
regex = re.compile(needle)
try:
return regex.search(haystack).groups()[0]
except AttributeError:
return None