Esempio n. 1
0
    def create_or_import_account(self, name, get_key_cb, db_session=None):
        if type(name) not in (str, unicode) or len(
                name.encode('utf-8')) > ACCOUNT_NAME_LEN:
            raise InvalidAccountName(name)

        db = db_session if db_session is not None else connectionmanager.database_session(
        )
        existing_account = db.query(Account).filter(
            Account.manager_id == self.manager.id,
            Account.user == name).first()

        if existing_account != None:
            raise AccountExistsException(name)

        account = Account()
        account.manager_id = self.manager.id
        account.user = name

        privkey, pubkeyhash = get_key_cb()
        account.private_key = privkey
        account.pubkeyhash = pubkeyhash

        db.add(account)
        db.flush()

        for coin in COINS:
            try:
                addresses = coin.get_addresses_for_pubkeyhash(pubkeyhash)
                coin_db = connectionmanager.database_session(coin)
                coin_daemon = connectionmanager.coindaemon(coin)

                for address_id in [
                        import_address(address,
                                       dbsession=coin_db,
                                       daemon=coin_daemon)
                        for address in addresses
                ]:
                    account_address = AccountAddress()
                    account_address.account_id = account.id
                    account_address.coin = coin.ticker
                    account_address.address_id = address_id
                    db.add(account_address)

                coin_db.commit()
            except Exception as e:
                print(
                    'Failed to import %s addresses for new account "%s": %s' %
                    (coin.ticker, name, e))
                coin_db.rollback()
                db.rollback()
                raise

        db.flush()
        db.commit()
        return WalletAccount(self, account)
Esempio n. 2
0
    def wrapper(*args, **kwargs):
        auth_header = request.headers.get('Authorization')
        if not auth_header:
            abort(401)
        auth_header = auth_header.split(' ')
        if len(auth_header) != 2 or auth_header[0] != 'Bearer':
            abort(401)
        try:
            token = b64decode(auth_header[1])
        except TypeError:
            abort(401)
        if len(token) != AUTH_TOKEN_SIZE:
            abort(401)

        tokenhash = sha256(sha256(token).digest()).digest()

        dbsession = connectionmanager.database_session()
        manager = dbsession.query(WalletManager).filter(
            WalletManager.tokenhash == tokenhash).first()

        if manager == None:
            abort(401)

        kwargs['manager'] = manager
        return api_func(*args, **kwargs)
Esempio n. 3
0
def send(manager, wallet, account, user):
    requestobj = SendRequest(request.get_json())
    sender = account.addresses[requestobj.coin]
    requestobj.destination.set_context_info(wallet=wallet, coin=sender.coin)

    tx = sender.transaction(requestobj.destination.address, requestobj.amount, spend_unconfirmed=True, subsidized=requestobj.low_priority)
    txid = tx.broadcast()
    txid_raw = unhexlify(txid)
    sent = time()

    db = connectionmanager.database_session(coin=sender.coin)
    tx_internal_id = None

    while time() < sent + 10:
        db.rollback()
        txobj = db.query(Transaction).filter(Transaction.txid == txid_raw).first()
        if txobj != None:
            tx_internal_id = txobj.id
            break

    if tx_internal_id is None:
        raise APIException('Transaction created but not seen on network after 10 seconds')

    with QueryDataPostProcessor() as pp:
        return pp.process_raw({
            'error': None,
            'destination': dict(requestobj.destination),
            'transaction': {
                'txid': txid,
                'href': make_tx_ref(sender.coin, txid)
            }
        }).json()
Esempio n. 4
0
def main():
    STATE = { coin.ticker: CoinState() for coin in COINS }

    while True:
        sleep(10)
        try:
            for coin in COINS:
                state = STATE[coin.ticker]

                session = connectionmanager.database_session(coin=coin)
                lastblock = session.query(Block).order_by(Block.height.desc()).first()
                if lastblock.hash == state.lastblockhash:
                    continue

                log_event('New', 'Blk', hexlify(lastblock.hash), 'chain = ' + coin.ticker)
                should_run = state.update(lastblock.hash)

                if not should_run:
                    log_event('Ign', 'Blk', hexlify(lastblock.hash), 'too soon')
                    continue

                txs_queued = len(connectionmanager.coindaemon(coin).getrawmempool())
                max_work = MAX_QUEUED_TXS - txs_queued

                if max_work <= 0:
                    log_event('Ign', 'Blk', hexlify(lastblock.hash), 'mempool full')
                    continue

                log_event('Check', 'Chn', coin.ticker, '%d entries in mempool, max = %d' % (txs_queued, MAX_QUEUED_TXS))
                run_background_tasks_for_coin(coin, session, max_work=max_work)
                log_event('Finish', 'Chn', coin.ticker)

        except KeyboardInterrupt:
            return
Esempio n. 5
0
    def wait_until_seen_on_network(self, timeout=10, check_interval=0.5):
        start_time = time()
        db = connectionmanager.database_session(coin=self.coin)

        while time() < start_time + timeout:
            sleep(check_interval)
            db.rollback()
            if self.is_seen_on_network(db):
                return

        raise TransactionBroadcastException(
            'Transaction was broadcasted, but not seen on network after %d seconds'
            % timeout)
Esempio n. 6
0
    def get(cls, token, format='raw', dbsession=None):
        token = {
            'raw': lambda x: x,
            'base64': lambda x: b64decode(x),
            'hex': lambda x: unhexlify(x)
        }[format](token)

        if dbsession is None:
            dbsession = connectionmanager.database_session()

        manager = dbsession.query(WalletManager).filter(
            WalletManager.token == token).first()
        if manager != None:
            return cls(manager)
Esempio n. 7
0
def create_account(manager, wallet):
    user = get_value(request.get_json(), 'user')

    try:
        private_key = get_value(request.get_json(), 'privkey')
    except ValueError:
        private_key = None

    db_session = connectionmanager.database_session()

    if private_key is None:
        new_account = wallet.create_account(user, db_session=db_session)
    else:
        new_account = wallet.import_account(user,
                                            private_key,
                                            db_session=db_session)

    with QueryDataPostProcessor() as pp:
        return pp.process(new_account.model).json()
Esempio n. 8
0
 def current_coinbase_confirmation_height(self, dbsession=None):
     if dbsession is None:
         from connections import connectionmanager
         dbsession = connectionmanager.database_session(coin=self)
     return dbsession.query(Block.height).order_by(Block.height.desc()).first()[0] - 100
Esempio n. 9
0
 def _dbsession(self):
     return connectionmanager.database_session(coin=Coin.by_ticker(self.coin))
Esempio n. 10
0
 def __init__(self, account, coin):
     self.account = account
     self.coin = coin
     self.db = connectionmanager.database_session(coin=self.coin)
     self._addresses = None