def search_debit(): """ Get one to ten debit(s) for a single User. --- parameters: - name: searchcd in: body description: The Debit(s) you'd like to get. required: false schema: $ref: '#/definitions/SearchCD' responses: '200': description: the User's debit(s) schema: items: $ref: '#/definitions/Debit' type: array default: description: unexpected error schema: $ref: '#/definitions/errorModel' security: - kid: [] - typ: [] - alg: [] operationId: searchDebits """ sid = request.jws_payload['data'].get('id') address = request.jws_payload['data'].get('address') currency = request.jws_payload['data'].get('currency') network = request.jws_payload['data'].get('network') #reference = request.jws_payload['data'].get('reference') ref_id = request.jws_payload['data'].get('ref_id') page = request.jws_payload['data'].get('page') or 0 debsq = ses.query(wm.Debit).filter(wm.Debit.user_id == current_user.id) if not debsq: return None if sid: debsq = debsq.filter(wm.Debit.id == sid) if address: debsq = debsq.filter(wm.Debit.address == address) if currency: debsq = debsq.filter(wm.Debit.currency == currency) if network: debsq = debsq.filter(wm.Debit.network == network) #if reference: # debsq = debsq.filter(wm.Debit.reference == reference) if ref_id: debsq = debsq.filter(wm.Debit.ref_id == ref_id) debsq = debsq.order_by(wm.Debit.time.desc()).limit(10) if page and isinstance(page, int): debsq = debsq.offset(page * 10) debits = [json.loads(jsonify2(d, 'Debit')) for d in debsq] response = current_app.bitjws.create_response(debits) ses.close() return response
def get_balance(): """ Get the latest balance(s) for a single User. Currently no search parameters are supported. All balances returned. --- responses: '200': description: the User's balance(s) schema: items: $ref: '#/definitions/Balance' type: array default: description: unexpected error schema: $ref: '#/definitions/errorModel' security: - kid: [] - typ: [] - alg: [] operationId: getBalance """ balsq = ses.query(wm.Balance).filter(wm.Balance.user_id == current_user.id) if not balsq: return None bals = [json.loads(jsonify2(b, 'Balance')) for b in balsq] print "returning bals %s" % bals response = current_app.bitjws.create_response(bals) ses.close() return response
def test_User(self): address = ''.join([random.choice(string.ascii_letters) for n in xrange(19)]) userdict = {'username': address[0:8]} user_key = {'key': address, 'keytype': 'public'} user = um.User(**userdict) self.ses.add(user) self.ses.commit() user_schema = SCHEMAS['User'] udict = json.loads(jsonify2(user, 'User')) assert validate(udict, user_schema) is None user_key['user_id'] = user.id ukey = um.UserKey(**user_key) self.ses.add(ukey) self.ses.commit() ukey_schema = SCHEMAS['UserKey'] ukey_dict = json.loads(jsonify2(ukey, 'UserKey')) del ukey_dict['user'] assert validate(ukey_dict, ukey_schema) is None
def create_debit(): """ Create a new debit, sending tokens out of your User's account. --- parameters: - name: debit in: body description: The debit you would like to create. required: true schema: $ref: '#/definitions/Debit' responses: '200': description: The Debit record schema: $ref: '#/definitions/Debit' default: description: unexpected error schema: $ref: '#/definitions/errorModel' security: - kid: [] - typ: [] - alg: [] operationId: sendMoney """ currency = request.jws_payload['data'].get('currency') amount = Amount("%s %s" % (request.jws_payload['data'].get('amount'), currency)) address = request.jws_payload['data'].get('address') network = request.jws_payload['data'].get('network') reference = request.jws_payload['data'].get('reference') state = 'unconfirmed' try: debit = plugin.create_debit(current_user, amount, currency, address, network, reference, state='unconfirmed', plugins=ps, session=ses) plugin.process_debit(debit, plugins=ps, session=ses) except (IOError, ValueError) as e: current_app.logger.exception(e) ses.rollback() ses.flush() return "Unable to send money", 400 except Exception as e: current_app.logger.exception(e) ses.rollback() ses.flush() return "Unable to send money", 500 result = json.loads(jsonify2(debit, 'Debit')) current_app.logger.info("created new debit %s" % result) ses.close() return current_app.bitjws.create_response(result)
def create_address(): """ Create a new address owned by your user. --- parameters: - name: address in: body description: The pseudo-address you would like to create. i.e. currency and network required: true schema: $ref: '#/definitions/Address' responses: '200': description: Your new address schema: $ref: '#/definitions/Address' default: description: unexpected error schema: $ref: '#/definitions/errorModel' security: - kid: [] - typ: [] - alg: [] operationId: createAddress """ currency = request.jws_payload['data'].get('currency') network = request.jws_payload['data'].get('network') state = 'active' if network.lower() in ps: try: addy = ps[network.lower()].get_new_address() except Exception as e: print type(e) print e current_app.logger.error(e) return 'wallet temporarily unavailable', 500 else: return 'Invalid network', 400 address = wm.Address(addy, currency, network, state, current_user.id) ses.add(address) try: ses.commit() except Exception as ie: ses.rollback() ses.flush() return 'Could not save address', 500 newaddy = json.loads(jsonify2(address, 'Address')) current_app.logger.info("created new address %s" % newaddy) ses.close() return current_app.bitjws.create_response(newaddy)
def sync_ticker(self, market='BTC_USD'): pair = self.unformat_market(market) full_ticker = self.submit_public_request('Ticker', {'pair': pair}) ticker = full_ticker['result'][pair] tick = em.Ticker(float(ticker['b'][0]), float(ticker['a'][0]), float(ticker['h'][1]), float(ticker['l'][1]), float(ticker['v'][1]), float(ticker['c'][0]), market, 'kraken') jtick = jsonify2(tick, 'Ticker') self.red.set('kraken_%s_ticker' % market, jtick) return tick
def sync_ticker(self, market=None): """ Return the current ticker for this exchange. :param market: If the exchange supports multiple markets, then the "market" param can be used to specify a given orderbook. In case the exchange does not support that, then the "market" param is ignored. :return: a Ticker with at minimum bid, ask and last. :rtype: Ticker """ tick = em.Ticker(99, 101, 110, 90, 1000, 100, market, 'helper') jtick = jsonify2(tick, 'Ticker') self.red.set('%s_%s_ticker' % (self.NAME.lower(), market), jtick)
def get_address(): """ Get one or more existing address(es) owned by your user. --- parameters: - name: address in: body description: The address you'd like to get info about. required: false schema: $ref: '#/definitions/Address' responses: '200': description: Your new address schema: items: $ref: '#/definitions/Address' type: array default: description: unexpected error schema: $ref: '#/definitions/errorModel' security: - kid: [] - typ: [] - alg: [] operationId: getAddress """ address = request.jws_payload['data'].get('address') currency = request.jws_payload['data'].get('currency') network = request.jws_payload['data'].get('network') addysq = ses.query(wm.Address).filter(wm.Address.user_id == current_user.id) if address: addysq = addysq.filter(wm.Address.address == address) elif currency: addysq = addysq.filter(wm.Address.currency == currency) elif network: addysq = addysq.filter(wm.Address.network == network) if addysq.count() == 0: return "Invalid Request", 400 addys = [json.loads(jsonify2(a, 'Address')) for a in addysq] response = current_app.bitjws.create_response(addys) ses.close() return response
def create_debit(user, amount, currency, address, network, reference, state='unconfirmed', plugins=None, session=ses): if plugins is None: plugins = load_plugins() if network.lower() not in plugins: raise ValueError("Plugin %s not active" % network) dbaddy = session.query(wm.Address)\ .filter(wm.Address.address == address)\ .filter(wm.Address.currency == currency).first() if dbaddy is not None and dbaddy.address == address: network = 'internal' elif network == 'internal' and dbaddy is None: raise ValueError("internal address %s not found" % address) fee = Amount("%s %s" % (CFG.get(network.lower(), 'FEE'), currency)) txid = 'TBD' debit = wm.Debit(amount, fee, address, currency, network, state, reference, txid, user.id, datetime.datetime.utcnow()) session.add(debit) bal = session.query(wm.Balance)\ .filter(wm.Balance.user_id == user.id)\ .filter(wm.Balance.currency == currency)\ .order_by(wm.Balance.time.desc()).first() if not bal or bal.available < amount + fee: session.rollback() session.flush() raise ValueError("not enough funds") else: bal.total = bal.total - (amount + fee) bal.available = bal.available - (amount + fee) bal.time = datetime.datetime.utcnow() bal.reference = "debit: %s" % txid session.add(bal) logger.info("updating balance %s" % jsonify2(bal, 'Balance')) try: session.commit() except Exception as ie: logger.exception(ie) session.rollback() session.flush() raise IOError("unable to send funds") return debit
def add_user(): """ Register a new User. Create a User and a UserKey based on the JWS header and payload. --- operationId: addUser parameters: - name: user in: body description: A new User to add required: true schema: $ref: '#/definitions/User' responses: '200': description: "user's new key" schema: $ref: '#/definitions/UserKey' default: description: unexpected error schema: $ref: '#/definitions/errorModel' security: - kid: [] - typ: [] - alg: [] """ load_jws_from_request(request) if not hasattr(request, 'jws_header') or request.jws_header is None: return "Invalid Payload", 401 username = request.jws_payload['data'].get('username') address = request.jws_header['kid'] last_nonce = request.jws_payload['iat']*1000 try: user, userkey = create_user_and_key(username=username, address=address, last_nonce=last_nonce, session=ses) except IOError: ses.rollback() ses.flush() return 'username or key taken', 400 jresult = json.loads(jsonify2(userkey, 'UserKey')) current_app.logger.info("registered user %s with key %s" % (user.id, userkey.key)) ses.close() return current_app.bitjws.create_response(jresult)
def test_ticker_encoding(): ticker = em.Ticker(769, 771, 800, 700, 10000.1, 770, 'BTC_USD', 'helper') jticker = jsonify2(ticker, 'Ticker') ticker.load_commodities() dticker = json.loads(jticker) from_jticker = em.Ticker.from_json(jticker) assert ticker.bid == from_jticker.bid assert ticker.ask == from_jticker.ask assert ticker.high == from_jticker.high assert ticker.low == from_jticker.low assert ticker.volume == from_jticker.volume assert ticker.time == from_jticker.time from_dticker = em.Ticker.from_dict(dticker) assert ticker.bid == from_dticker.bid assert ticker.ask == from_dticker.ask assert ticker.high == from_dticker.high assert ticker.low == from_dticker.low assert ticker.volume == from_dticker.volume assert ticker.time == from_dticker.time
def sync_ticker(self, market='BTC_USD'): exch_pair = self.unformat_market(market) try: rawtick = requests.get(BASE_URL + '/v1/pubticker/%s' % exch_pair, timeout=REQ_TIMEOUT).json() except (ConnectionError, Timeout, ValueError) as e: self.logger.exception(e) return tick = em.Ticker(float(rawtick['bid']), float(rawtick['ask']), float(rawtick['high']), float(rawtick['low']), float(rawtick['volume']), float(rawtick['last_price']), market, 'bitfinex') self.logger.debug("bitfinex %s tick %s" % (market, tick)) jtick = jsonify2(tick, 'Ticker') self.logger.debug("bitfinex %s json ticker %s" % (market, jtick)) self.red.set('bitfinex_%s_ticker' % market, jtick) return tick
def get_user(): """ Get your user object. Users may only get their own info, not others'. --- responses: '200': description: user response schema: $ref: '#/definitions/User' default: description: unexpected error schema: $ref: '#/definitions/errorModel' description: get your user record security: - kid: [] - typ: [] - alg: [] operationId: getUserList """ userdict = json.loads(jsonify2(current_user.dbuser, 'User')) return current_app.bitjws.create_response(userdict)