def onOpen(self):
    def sendTestRequest():
      self.sendJSON( MessageBuilder.testRequestMessage() )
      self.factory.reactor.callLater(60, sendTestRequest)

    sendTestRequest()

    self.sendJSON( MessageBuilder.login(  self.factory.blintrade_user, self.factory.blintrade_password ) )
  def initiateTransfer(self, process_req_id):
    withdraw_record = Withdraw.get_withdraw_by_process_req_id(self.factory.db_session, process_req_id)
    if withdraw_record.status != '2':
      return

    dest_pay = {}
    dest_pay[json.loads(withdraw_record.data)['Wallet']] = withdraw_record.amount

    try:
      tx_hash = self.factory.blocktrail_wallet.pay(dest_pay,
                                                   change_address=self.factory.blocktrail_change_address,
                                                   allow_zero_conf=True,
                                                   randomize_change_idx=True)

      withdraw_record.response = tx_hash
      self.factory.db_session.add(withdraw_record)
      self.factory.db_session.commit()

      withdraw_data = json.loads(withdraw_record.data)
      withdraw_data['TransactionID'] = tx_hash
      withdraw_data['Currency'] = 'BTC'

      process_withdraw_message = MessageBuilder.processWithdraw(action      = 'COMPLETE',
                                                                withdrawId  = withdraw_record.id ,
                                                                data        = withdraw_data )
      self.sendJSON( process_withdraw_message )

    except Exception,e:
      withdraw_record.response = str(e)
      self.factory.db_session.add(withdraw_record)
      self.factory.db_session.commit()

      try:
        # send an email to the system administrator
        template_content = [
          {'name': 'NotificationType',  'content': 'HOT_WALLET_SEND_ERROR'},
          {'name': 'WithdrawalProtocol','content': 'Blocktrail'},
          {'name': 'From',              'content': self.factory.blocktrail_change_address},
          {'name': 'To',                'content': json.loads(withdraw_record.data)['Wallet']},
          {'name': 'Amount',            'content': str(withdraw_record.amount)},
          {'name': 'Currency',          'content': 'BTC'},
          {'name': 'Error',             'content': str(e)}
        ]
        message = {
          'from_email': '*****@*****.**',
          'from_name': 'No reply',
          'to': [{'email': '*****@*****.**',
                  'name': 'BlinkTrade system notifications',
                  'type': 'to' }],
          'metadata': {'website':  'https://blinktrade.com/'},
          'global_merge_vars': template_content
        }
        result = self.mandrill_api.messages.send_template(
          template_name='system-notification',
          template_content=template_content,
          message=message)
      except Exception,e:
        print "Error sending the system notification email ", str(e)
Example #3
0
    def onOpen(self):
        def sendTestRequest():
            self.sendJSON(MessageBuilder.testRequestMessage())
            self.factory.reactor.callLater(60, sendTestRequest)

        sendTestRequest()

        self.sendJSON(
            MessageBuilder.login(self.factory.blintrade_user,
                                 self.factory.blintrade_password))
Example #4
0
  def getBrokerList(self, status_list):
    page = 0
    page_size = 100

    broker_list = []
    columns = []
    while True:
      res = self.sendJSON(MessageBuilder.getBrokerList( status_list, None, page, page_size ))
      columns = res.get('Columns')
      broker_list.extend(res.get('BrokerListGrp'))
      if len(res.get('BrokerListGrp')) < page_size:
        break
      page += 1

    return broker_list, columns
Example #5
0
  def getBrokerList(self, status_list):
    page = 0
    page_size = 100

    broker_list = []
    columns = []
    while True:
      res = self.sendJSON(MessageBuilder.getBrokerList( status_list, None, page, page_size ))
      columns = res.get('Columns')
      broker_list.extend(res.get('BrokerListGrp'))
      if len(res.get('BrokerListGrp')) < page_size:
        break
      page += 1

    return broker_list, columns
  def onBlockchainApiSuccessCallback(self, process_req_id, result):
    withdraw_record = Withdraw.get_withdraw_by_process_req_id(self.factory.db_session, process_req_id)

    result =  json.loads(result)
    if "error" in result:
      withdraw_record.response = result["error"]
      self.factory.db_session.add(withdraw_record)
      self.factory.db_session.commit()

      if result["error"] == "Error Decrypting Wallet":
        reactor.stop()
        raise RuntimeError(result["error"])
      if result["error"] == "pad block corrupted":
        reactor.stop()
        raise RuntimeError(result["error"])
      elif result["error"] == "Second Password Incorrect":
        reactor.stop()
        raise RuntimeError(result["error"])
      elif result["error"] == "Wallet Checksum did not validate. Serious error: Restore a backup if necessary.":
        reactor.stop()
        raise RuntimeError(result["error"])

    elif "tx_hash" in result:
      tx_hash = result["tx_hash"]
      withdraw_data = json.loads(withdraw_record.data)
      withdraw_data['TransactionID'] = tx_hash
      withdraw_data['Currency'] = 'BTC'


      withdraw_record.response = json.dumps(result)
      self.factory.db_session.add(withdraw_record)
      self.factory.db_session.commit()


      process_withdraw_message = MessageBuilder.processWithdraw(action      = 'COMPLETE',
                                                                withdrawId  = withdraw_record.id ,
                                                                data        = withdraw_data )


      self.sendJSON( process_withdraw_message )

    print result
Example #7
0
    def onBlockchainApiSuccessCallback(self, process_req_id, result):
        withdraw_record = Withdraw.get_withdraw_by_process_req_id(
            self.factory.db_session, process_req_id)

        result = json.loads(result)
        if "error" in result:
            withdraw_record.response = result["error"]
            self.factory.db_session.add(withdraw_record)
            self.factory.db_session.commit()

            if result["error"] == "Error Decrypting Wallet":
                reactor.stop()
                raise RuntimeError(result["error"])
            if result["error"] == "pad block corrupted":
                reactor.stop()
                raise RuntimeError(result["error"])
            elif result["error"] == "Second Password Incorrect":
                reactor.stop()
                raise RuntimeError(result["error"])
            elif result[
                    "error"] == "Wallet Checksum did not validate. Serious error: Restore a backup if necessary.":
                reactor.stop()
                raise RuntimeError(result["error"])

        elif "tx_hash" in result:
            tx_hash = result["tx_hash"]
            withdraw_data = json.loads(withdraw_record.data)
            withdraw_data['TransactionID'] = tx_hash
            withdraw_data['Currency'] = 'BTC'

            withdraw_record.response = json.dumps(result)
            self.factory.db_session.add(withdraw_record)
            self.factory.db_session.commit()

            process_withdraw_message = MessageBuilder.processWithdraw(
                action='COMPLETE',
                withdrawId=withdraw_record.id,
                data=withdraw_data)

            self.sendJSON(process_withdraw_message)

        print result
Example #8
0
def run_application(options, instance_name):
  input_log_file_handler = logging.handlers.TimedRotatingFileHandler(
    os.path.expanduser(options.mailer_log), when='MIDNIGHT')
  input_log_file_handler.setFormatter(logging.Formatter(u"%(asctime)s - %(message)s"))

  app_logger = logging.getLogger(instance_name)
  app_logger.setLevel(logging.INFO)
  app_logger.addHandler(input_log_file_handler)

  ch = logging.StreamHandler(sys.stdout)
  ch.setLevel(logging.DEBUG)
  ch.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
  app_logger.addHandler(ch)

  app_logger.info('START')
  def log(command, key, value=None):
    log_msg = u'%s, %s, %s' %(command, key, value if value else None)
    app_logger.info(unicode(log_msg))


  log('PARAM', 'BEGIN')
  log('PARAM', 'trade_in',                      options.trade_in)
  log('PARAM', 'trade_pub',                     options.trade_pub)
  log('PARAM', 'app_log',                       options.app_log)
  log('PARAM', 'maxmind_license_key',           options.maxmind_license_key)
  log('PARAM', 'END')

  context = zmq.Context()
  socket = context.socket(zmq.SUB)
  socket.connect(options.trade_pub)
  socket.setsockopt(zmq.SUBSCRIBE, "^FRAUDER$")

  trade_in_socket = context.socket(zmq.REQ)
  trade_in_socket.connect(options.trade_in)

  application_trade_client = TradeClient( context, trade_in_socket)
  application_trade_client.connect()

  login_response = application_trade_client.sendJSON( MessageBuilder.login( 8999999,
                                                                            options.frauder_username,
                                                                            options.frauder_password))
  if login_response.get('UserStatus') != 1:
    raise RuntimeError("Invalid user id")

  brokers = {}
  broker_list, broker_list_columns = application_trade_client.getBrokerList(['1'])
  for b in  broker_list:
    brokers[b[0]] = { "params": b }


  while True:
    try:
      raw_email_message = socket.recv()
      log('IN', 'TRADE_IN_PUB', raw_email_message)

      msg = JsonMessage(raw_email_message)

      if not msg.isAccessLog():
        continue

      try:
        broker_id = msg.get('BrokerID')

      except Exception as ex:
        traceback.print_exc()
        log('ERROR', 'EXCEPTION', str(ex))
        time.sleep(1)

    except KeyboardInterrupt:
      app_logger.info('END')
      break

    except Exception as ex:
      time.sleep(1)
    def onMessage(self, payload, isBinary):
        if isBinary:
            print("Binary message received: {0} bytes".format(len(payload)))
            reactor.stop()
            return

        if self.factory.verbose:
            print 'rx:', payload

        msg = JsonMessage(payload.decode('utf8'))
        if msg.isHeartbeat():
            return

        if msg.isUserResponse():  # login response
            if msg.get('UserStatus') != 1:
                reactor.stop()
                raise RuntimeError('Wrong login')

            profile = msg.get('Profile')
            if profile['Type'] != 'BROKER':
                reactor.stop()
                raise RuntimeError('It is not a brokerage account')

            self.factory.broker_username = msg.get('Username')
            self.factory.broker_id = msg.get('UserID')
            self.factory.profile = profile
            return

        if msg.isWithdrawRefresh():
            if msg.get('BrokerID') != self.factory.broker_id:
                return  # received a message from a different broker

            msg.set('BrokerUsername', self.factory.broker_username)

            if msg.get('Status') == '1'\
              and (self.factory.methods[0] == '*' or msg.get('Method') in self.factory.methods) \
              and (self.factory.currencies[0] == '*' or  msg.get('Currency') in self.factory.currencies):
                withdraw_record = Withdraw.process_withdrawal_refresh_message(
                    self.factory.db_session, msg)
                if withdraw_record:
                    process_withdraw_message = MessageBuilder.processWithdraw(
                        action='PROGRESS',
                        withdrawId=msg.get('WithdrawID'),
                        data=msg.get('Data'),
                        percent_fee=msg.get('PercentFee'),
                        fixed_fee=msg.get('FixedFee'))

                    withdraw_record.process_req_id = process_withdraw_message[
                        'ProcessWithdrawReqID']

                    # sent a B6
                    self.sendJSON(process_withdraw_message)
                    self.factory.db_session.commit()

        if msg.isProcessWithdrawResponse():
            if not msg.get('Result'):
                return

            process_req_id = msg.get('ProcessWithdrawReqID')
            withdraw_record = Withdraw.get_withdraw_by_process_req_id(
                self.factory.db_session, process_req_id)

            should_transfer = False
            if withdraw_record:
                if withdraw_record.status == '1' and msg.get('Status') == '2'\
                  and (self.factory.methods[0] == '*' or withdraw_record.method  in self.factory.methods)\
                  and (self.factory.currencies[0] == '*' or  withdraw_record.currency in self.factory.currencies):

                    if withdraw_record.account_id not in self.factory.blocked_accounts:
                        should_transfer = True

                withdraw_record.status = msg.get('Status')
                withdraw_record.reason = msg.get('Reason')
                withdraw_record.reason_id = msg.get('ReasonID')

                self.factory.db_session.add(withdraw_record)
                self.factory.db_session.commit()

                if should_transfer:
                    self.factory.reactor.callLater(
                        0, partial(self.initiateTransfer, process_req_id))
 def sendTestRequest():
     self.sendJSON(MessageBuilder.testRequestMessage())
     self.factory.reactor.callLater(60, sendTestRequest)
def run_application(options, instance_name):
  input_log_file_handler = logging.handlers.TimedRotatingFileHandler(
    os.path.expanduser(options.mailer_log), when='MIDNIGHT')
  input_log_file_handler.setFormatter(logging.Formatter(u"%(asctime)s - %(message)s"))

  mail_logger = logging.getLogger(instance_name)
  mail_logger.setLevel(logging.INFO)
  mail_logger.addHandler(input_log_file_handler)

  ch = logging.StreamHandler(sys.stdout)
  ch.setLevel(logging.DEBUG)
  ch.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
  mail_logger.addHandler(ch)

  mail_logger.info('START')
  def log(command, key, value=None):
    log_msg = u'%s, %s, %s' %(command, key, value if value else None)
    mail_logger.info(unicode(log_msg))


  log('PARAM', 'BEGIN')
  log('PARAM', 'trade_in',                      options.trade_in)
  log('PARAM', 'trade_pub',                     options.trade_pub)
  log('PARAM', 'mailer_log',                    options.mailer_log)
  log('PARAM', 'mailchimp_apikey',              options.mailchimp_apikey)
  log('PARAM', 'mandrill_apikey',               options.mandrill_apikey)
  log('PARAM', 'mailer_username',               options.mailer_username)
  log('PARAM', 'mailchimp_newsletter_list_id',  options.mailchimp_newsletter_list_id)
  log('PARAM', 'END')

  context = zmq.Context()
  socket = context.socket(zmq.SUB)
  socket.connect(options.trade_pub)
  socket.setsockopt(zmq.SUBSCRIBE, "^EMAIL$")

  trade_in_socket = context.socket(zmq.REQ)
  trade_in_socket.connect(options.trade_in)

  application_trade_client = TradeClient( context, trade_in_socket)
  application_trade_client.connect()

  login_response = application_trade_client.sendJSON( MessageBuilder.login( 8999999,
                                                                            options.mailer_username,
                                                                            options.mailer_password))
  if login_response.get('UserStatus') != 1:
    raise RuntimeError("Invalid user id")

  brokers = {}
  broker_list, broker_list_columns = application_trade_client.getBrokerList(['1'])
  for b in  broker_list:
    brokers[b[0]] = { "params": b }

  broker_mandrill_column_index = None
  try:
    broker_mandrill_column_index = broker_list_columns.index('MandrillApiKey')
  except ValueError:
    pass


  for broker_id, broker_data  in brokers.iteritems():
    if broker_mandrill_column_index and broker_data['params'][ broker_mandrill_column_index ]:
      broker_data['MandrillApiKey'] =  broker_data['params'][ broker_mandrill_column_index ]
    else:
      broker_data['MandrillApiKey'] = options.mandrill_apikey

  for broker_id, broker_data  in brokers.iteritems():
    print broker_id, broker_data['MandrillApiKey']

  # [u'BrokerID', u'ShortName', u'BusinessName', u'Address', u'City', u'State',
  #  u'ZipCode', u'Country', u'PhoneNumber1', u'PhoneNumber2', u'Skype', u'Currencies',
  #  u'TosUrl', u'FeeStructure', u'TransactionFeeBuy', u'TransactionFeeSell', u'Status',
  #  u'ranking', u'Email', u'CountryCode', u'CryptoCurrencies', u'WithdrawStructure',
  #  u'SupportURL', u'SignupLabel', u'AcceptCustomersFrom', u'IsBrokerHub']

  mailchimp_api =  mailchimp.Mailchimp(options.mailchimp_apikey)
  try:
    mailchimp_api.helper.ping()
  except mailchimp.Error:
    raise RuntimeError("Invalid MailChimp API key")

  mandrill_api = mandrill.Mandrill(options.mandrill_apikey)
  try:
    mandrill_api.users.ping()
  except mandrill.Error:
    raise RuntimeError("Invalid Mandrill API key")

  while True:
    try:
      raw_email_message = socket.recv()
      log('IN', 'TRADE_IN_PUB', raw_email_message)

      msg = JsonMessage(raw_email_message)

      if not msg.isEmail():
        log('ERROR',
            'EXCEPTION',
            'Received message is not an email message')
        continue

      try:
        broker_id = msg.get('BrokerID')
        sender =  brokers[broker_id]['params'][broker_list_columns.index('MailerFromName')]  + \
                  '<' + brokers[broker_id]['params'][broker_list_columns.index('MailerFromEmail')] + '>'
        body = ""
        msg_to    = msg.get('To')
        subject   = msg.get('Subject')
        language  = msg.get('Language')
        content_type = 'plain'

        if msg.has('Template') and msg.get('Template'):
          params = {}
          if msg.has('Params') and msg.get('Params'):
            params = json.loads(msg.get('Params'))

          template_name = msg.get('Template')


          if template_name  == 'welcome':
            # user signup .... let's register him on mailchimp newsletter
            try:
              mailchimp_api.lists.subscribe(
                id =  brokers[broker_id]['params'][broker_list_columns.index('MailchimpListID')],
                email = {'email': params['email'] },
                merge_vars = {'EMAIL' : params['email'], 'FNAME': params['username'] } )

            except mailchimp.ListAlreadySubscribedError:
              log('ERROR', 'EXCEPTION', params['email'] + ' mailchimp.ListAlreadySubscribedError' )
            except mailchimp.Error, e:
              log('ERROR', 'EXCEPTION', str(e))


          template_content = []
          for k,v in params.iteritems():
            template_content.append( { 'name': k, 'content': v  } )

          for broker_column_key in broker_list_columns:
            broker_column_value  = brokers[broker_id]['params'][broker_list_columns.index(broker_column_key)]
            template_content.append( { 'name': 'broker_' + convertCamelCase2Underscore(broker_column_key),
                                       'content': broker_column_value  } )


          message = {
            'from_email': brokers[broker_id]['params'][broker_list_columns.index('MailerFromEmail')],
            'from_name': brokers[broker_id]['params'][broker_list_columns.index('MailerFromName')],
            'to': [{'email': msg_to, 'name': params['username'],'type': 'to' }],
            'metadata': {'website': 'www.blinktrade.com'},
            'global_merge_vars': template_content
          }

          result = mandrill_api.messages.send_template(
            template_name= (template_name + '-' + language.replace('_','-') ).lower(),
            template_content=template_content,
            message=message)

          log('INFO', 'SUCCESS', str(result))
          continue

        elif msg.has('RawData') and msg.get('RawData'):
          body = msg.get('RawData')

          log('DEBUG', 'EMAIL',
              u'{"Sender":"%s","To":"%s","Subject":"%s", "Body":"%s" }' % (sender,
                                                                           msg_to,
                                                                           subject,
                                                                           body))
          send_email(sender, msg_to, subject, body, content_type)
          log('IN', 'SENT', "")

          log('INFO', 'SUCCESS', msg.get('EmailThreadID'))
      except Exception as ex:
        traceback.print_exc()
        log('ERROR', 'EXCEPTION', str(ex))
        time.sleep(1)

    except KeyboardInterrupt:
      mail_logger.info('END')
      break
Example #12
0
  def onMessage(self, payload, isBinary):
    if isBinary:
      print("Binary message received: {0} bytes".format(len(payload)))
      reactor.stop()
      return

    if self.factory.verbose:
      print 'rx:',payload

    msg = JsonMessage(payload.decode('utf8'))
    if msg.isHeartbeat():
      return

    if msg.isUserResponse(): # login response
      if msg.get('UserStatus') != 1:
        reactor.stop()
        raise RuntimeError('Wrong login')

      profile = msg.get('Profile')
      if profile['Type'] != 'BROKER':
        reactor.stop()
        raise RuntimeError('It is not a brokerage account')

      self.factory.broker_username = msg.get('Username')
      self.factory.broker_id = msg.get('UserID')
      self.factory.profile = profile
      return


    if msg.isVerifyCustomerRefresh():
      broker_id         = msg.get('BrokerID')
      if broker_id != self.factory.broker_id:
        return # received a message from a different broker

      verified          = msg.get('Verified')
      if verified != 1:
        return

      user_id           = msg.get('ClientID')
      username          = msg.get('Username')
      verification_data = msg.get('VerificationData')
      if verification_data:
        verification_data = json.loads(verification_data)

      edentiti_status = get_verification_data(verification_data, 'edentiti_status')
      if edentiti_status == "IN_PROGRESS":
        return

      street_address = get_verification_data(verification_data, 'address')['street1']
      flat_number = ''
      if '/' in street_address:
        flat_number = street_address[:street_address.find('/') ]
        street_address = street_address[street_address.find('/')+1: ]

      street_address_parts = street_address.split(" ")
      street_type = ""
      if len(street_address_parts) > 1:
        street_type = street_address_parts[-1]
        street_address = ' '.join(street_address_parts[:-1])

      street_address_parts = street_address.split(" ")
      street_number = ""
      if street_address_parts and street_address_parts[0].isdigit():
        street_number = street_address_parts[0]
        street_address = ' '.join(street_address_parts[1:])

      street_name = street_address

      try:
        res = self.factory.wsdl_client.registerUser(
            customerId=self.factory.edentiti_customer_id,
            password=self.factory.edentiti_password,
            ruleId='default',
            name={
              'givenName': get_verification_data(verification_data, 'name')['first'],
              'middleNames': get_verification_data(verification_data, 'name')['middle'],
              'surname': get_verification_data(verification_data, 'name')['last']
            },
            currentResidentialAddress={
              'country':get_verification_data(verification_data, 'address')['country_code'],
              'flatNumber': flat_number,
              'postcode': get_verification_data(verification_data, 'address')['postal_code'],
              'propertyName':'',
              'state':get_verification_data(verification_data, 'address')['state'],
              'streetName':street_name,
              'streetNumber': street_number ,
              'streetType': street_type.upper(),
              'suburb':get_verification_data(verification_data, 'address')['city']
            },
            homePhone=get_verification_data(verification_data, 'phone_number'),
            dob=datetime.datetime.strptime( get_verification_data(verification_data, 'date_of_birth') ,"%Y-%m-%d"))

        dt = datetime.datetime.now()
        createdAt = int(mktime(dt.timetuple()) + dt.microsecond/1000000.0)
        edentiti_verification_data = {
          "service_provider":"edentiti",
          "edentiti_status": res['return']['outcome'],
          "id": res['return']['transactionId'],
          "user_id": res['return']['userId'],
          "status": res['return']['outcome'],
          "created_at": createdAt,
          "updated_at": createdAt
        }
        if res['return']['outcome'] == "IN_PROGRESS":
          edentiti_verification_data["status"] = "progress"
          verified = 2

        if edentiti_verification_data["status"] == "valid":
          verified = 3

        self.sendJSON( MessageBuilder.verifyCustomer(user_id, verified, json.dumps(edentiti_verification_data)))

      except Exception:
        pass
Example #13
0
 def sendTestRequest():
   self.sendJSON( MessageBuilder.testRequestMessage() )
   self.factory.reactor.callLater(60, sendTestRequest)
  def onMessage(self, payload, isBinary):
    if isBinary:
      print("Binary message received: {0} bytes".format(len(payload)))
      reactor.stop()
      return

    if self.factory.verbose:
      print 'rx:',payload

    msg = JsonMessage(payload.decode('utf8'))
    if msg.isHeartbeat():
      return

    if msg.isUserResponse(): # login response
      if msg.get('UserStatus') != 1:
        reactor.stop()
        raise RuntimeError('Wrong login')

      profile = msg.get('Profile')
      if profile['Type'] != 'BROKER':
        reactor.stop()
        raise RuntimeError('It is not a brokerage account')

      self.factory.broker_username = msg.get('Username')
      self.factory.broker_id = msg.get('UserID')
      self.factory.profile = profile
      return

    if msg.isWithdrawRefresh():
      if msg.get('BrokerID') != self.factory.broker_id:
        return # received a message from a different broker

      msg.set('BrokerUsername', self.factory.broker_username )

      if msg.get('Status') == '1'\
        and (self.factory.methods[0] == '*' or msg.get('Method') in self.factory.methods) \
        and (self.factory.currencies[0] == '*' or  msg.get('Currency') in self.factory.currencies):
        withdraw_record = Withdraw.process_withdrawal_refresh_message( self.factory.db_session , msg)
        if withdraw_record:
          process_withdraw_message = MessageBuilder.processWithdraw(action      = 'PROGRESS',
                                                                    withdrawId  = msg.get('WithdrawID'),
                                                                    data        = msg.get('Data') ,
                                                                    percent_fee = msg.get('PercentFee'),
                                                                    fixed_fee   = msg.get('FixedFee') )

          withdraw_record.process_req_id = process_withdraw_message['ProcessWithdrawReqID']

          # sent a B6
          self.sendJSON( process_withdraw_message )
          self.factory.db_session.commit()

    if msg.isProcessWithdrawResponse():
      if not msg.get('Result'):
        return

      process_req_id = msg.get('ProcessWithdrawReqID')
      withdraw_record = Withdraw.get_withdraw_by_process_req_id(self.factory.db_session, process_req_id)



      should_transfer = False
      if withdraw_record:
        if withdraw_record.status == '1' and msg.get('Status') == '2'\
          and (self.factory.methods[0] == '*' or withdraw_record.method  in self.factory.methods)\
          and (self.factory.currencies[0] == '*' or  withdraw_record.currency in self.factory.currencies):

          if withdraw_record.account_id not in self.factory.blocked_accounts:
            should_transfer = True

        withdraw_record.status = msg.get('Status')
        withdraw_record.reason = msg.get('Reason')
        withdraw_record.reason_id = msg.get('ReasonID')

        self.factory.db_session.add(withdraw_record)
        self.factory.db_session.commit()

        if should_transfer:
          self.factory.reactor.callLater(0, partial(self.initiateTransfer, process_req_id) )
    def initiateTransfer(self, process_req_id):
        withdraw_record = Withdraw.get_withdraw_by_process_req_id(
            self.factory.db_session, process_req_id)
        if withdraw_record.status != '2':
            return

        dest_pay = {}
        dest_pay[json.loads(
            withdraw_record.data)['Wallet']] = withdraw_record.amount

        try:
            tx_hash = self.factory.blocktrail_wallet.pay(
                dest_pay,
                change_address=self.factory.blocktrail_change_address,
                allow_zero_conf=False,
                randomize_change_idx=True)

            withdraw_record.response = tx_hash
            self.factory.db_session.add(withdraw_record)
            self.factory.db_session.commit()

            withdraw_data = json.loads(withdraw_record.data)
            withdraw_data['TransactionID'] = tx_hash
            withdraw_data['Currency'] = 'BTC'

            process_withdraw_message = MessageBuilder.processWithdraw(
                action='COMPLETE',
                withdrawId=withdraw_record.id,
                data=withdraw_data)
            self.sendJSON(process_withdraw_message)

        except Exception, e:
            withdraw_record.response = str(e)
            self.factory.db_session.add(withdraw_record)
            self.factory.db_session.commit()

            try:
                # send an email to the system administrator
                template_content = [{
                    'name': 'NotificationType',
                    'content': 'HOT_WALLET_SEND_ERROR'
                }, {
                    'name': 'WithdrawalProtocol',
                    'content': 'Blocktrail'
                }, {
                    'name':
                    'From',
                    'content':
                    self.factory.blocktrail_change_address
                }, {
                    'name':
                    'To',
                    'content':
                    json.loads(withdraw_record.data)['Wallet']
                }, {
                    'name':
                    'Amount',
                    'content':
                    '{:,.8f}'.format(withdraw_record.amount / 1e8)
                }, {
                    'name': 'Currency',
                    'content': 'BTC'
                }, {
                    'name': 'Error',
                    'content': str(e)
                }]
                message = {
                    'from_email':
                    '*****@*****.**',
                    'from_name':
                    'No reply',
                    'to': [{
                        'email': '*****@*****.**',
                        'name': 'BlinkTrade system notifications',
                        'type': 'to'
                    }],
                    'metadata': {
                        'website': 'https://blinktrade.com/'
                    },
                    'global_merge_vars':
                    template_content
                }
                result = self.factory.mandrill_api.messages.send_template(
                    template_name='system-notification',
                    template_content=template_content,
                    message=message)
            except Exception, e:
                print "Error sending the system notification email ", str(e)
    def onMessage(self, payload, isBinary):
        if isBinary:
            print ("Binary message received: {0} bytes".format(len(payload)))
            reactor.stop()
            return

        if self.factory.verbose:
            print "rx:", payload

        msg = JsonMessage(payload.decode("utf8"))
        if msg.isHeartbeat():
            return

        if msg.isUserResponse():  # login response
            if msg.get("UserStatus") != 1:
                reactor.stop()
                raise RuntimeError("Wrong login")

            profile = msg.get("Profile")
            if profile["Type"] != "BROKER":
                reactor.stop()
                raise RuntimeError("It is not a brokerage account")

            self.factory.broker_username = msg.get("Username")
            self.factory.broker_id = msg.get("UserID")
            self.factory.profile = profile
            return

        if msg.isWithdrawRefresh():
            if msg.get("BrokerID") != self.factory.broker_id:
                return  # received a message from a different broker

            msg.set("BrokerUsername", self.factory.broker_username)

            if (
                msg.get("Status") == "1"
                and (self.factory.methods[0] == "*" or msg.get("Method") in self.factory.methods)
                and (self.factory.currencies[0] == "*" or msg.get("Currency") in self.factory.currencies)
            ):
                withdraw_record = Withdraw.process_withdrawal_refresh_message(self.factory.db_session, msg)
                if withdraw_record:
                    process_withdraw_message = MessageBuilder.processWithdraw(
                        action="PROGRESS",
                        withdrawId=msg.get("WithdrawID"),
                        data=msg.get("Data"),
                        percent_fee=msg.get("PercentFee"),
                        fixed_fee=msg.get("FixedFee"),
                    )

                    withdraw_record.process_req_id = process_withdraw_message["ProcessWithdrawReqID"]

                    # sent a B6
                    self.sendJSON(process_withdraw_message)
                    self.factory.db_session.commit()

        if msg.isProcessWithdrawResponse():
            if not msg.get("Result"):
                return

            process_req_id = msg.get("ProcessWithdrawReqID")
            withdraw_record = Withdraw.get_withdraw_by_process_req_id(self.factory.db_session, process_req_id)

            should_transfer = False
            if withdraw_record:
                if (
                    withdraw_record.status == "1"
                    and msg.get("Status") == "2"
                    and (self.factory.methods[0] == "*" or withdraw_record.method in self.factory.methods)
                    and (self.factory.currencies[0] == "*" or withdraw_record.currency in self.factory.currencies)
                ):

                    if withdraw_record.account_id not in self.factory.blocked_accounts:
                        should_transfer = True

                withdraw_record.status = msg.get("Status")
                withdraw_record.reason = msg.get("Reason")
                withdraw_record.reason_id = msg.get("ReasonID")

                self.factory.db_session.add(withdraw_record)
                self.factory.db_session.commit()

                if should_transfer:
                    self.factory.reactor.callLater(0, partial(self.initiateTransfer, process_req_id))
Example #17
0
    def onMessage(self, payload, isBinary):
        if isBinary:
            print("Binary message received: {0} bytes".format(len(payload)))
            reactor.stop()
            return

        if self.factory.verbose:
            print 'rx:', payload

        msg = JsonMessage(payload.decode('utf8'))
        if msg.isHeartbeat():
            return

        if msg.isUserResponse():  # login response
            if msg.get('UserStatus') != 1:
                reactor.stop()
                raise RuntimeError('Wrong login')

            profile = msg.get('Profile')
            if profile['Type'] != 'BROKER':
                reactor.stop()
                raise RuntimeError('It is not a brokerage account')

            self.factory.broker_username = msg.get('Username')
            self.factory.broker_id = msg.get('UserID')
            self.factory.profile = profile
            return

        if msg.isVerifyCustomerRefresh():
            broker_id = msg.get('BrokerID')
            if broker_id != self.factory.broker_id:
                return  # received a message from a different broker

            verified = msg.get('Verified')
            if verified != 1:
                return

            user_id = msg.get('ClientID')
            username = msg.get('Username')
            verification_data = msg.get('VerificationData')
            if verification_data:
                verification_data = json.loads(verification_data)

            edentiti_status = get_verification_data(verification_data,
                                                    'edentiti_status')
            if edentiti_status == "IN_PROGRESS":
                return

            street_address = get_verification_data(verification_data,
                                                   'address')['street1']
            flat_number = ''
            if '/' in street_address:
                flat_number = street_address[:street_address.find('/')]
                street_address = street_address[street_address.find('/') + 1:]

            street_address_parts = street_address.split(" ")
            street_type = ""
            if len(street_address_parts) > 1:
                street_type = street_address_parts[-1]
                street_address = ' '.join(street_address_parts[:-1])

            street_address_parts = street_address.split(" ")
            street_number = ""
            if street_address_parts and street_address_parts[0].isdigit():
                street_number = street_address_parts[0]
                street_address = ' '.join(street_address_parts[1:])

            street_name = street_address

            try:
                res = self.factory.wsdl_client.registerUser(
                    customerId=self.factory.edentiti_customer_id,
                    password=self.factory.edentiti_password,
                    ruleId='default',
                    name={
                        'givenName':
                        get_verification_data(verification_data,
                                              'name')['first'],
                        'middleNames':
                        get_verification_data(verification_data,
                                              'name')['middle'],
                        'surname':
                        get_verification_data(verification_data,
                                              'name')['last']
                    },
                    currentResidentialAddress={
                        'country':
                        get_verification_data(verification_data,
                                              'address')['country_code'],
                        'flatNumber':
                        flat_number,
                        'postcode':
                        get_verification_data(verification_data,
                                              'address')['postal_code'],
                        'propertyName':
                        '',
                        'state':
                        get_verification_data(verification_data,
                                              'address')['state'],
                        'streetName':
                        street_name,
                        'streetNumber':
                        street_number,
                        'streetType':
                        street_type.upper(),
                        'suburb':
                        get_verification_data(verification_data,
                                              'address')['city']
                    },
                    homePhone=get_verification_data(verification_data,
                                                    'phone_number'),
                    dob=datetime.datetime.strptime(
                        get_verification_data(verification_data,
                                              'date_of_birth'), "%Y-%m-%d"))

                dt = datetime.datetime.now()
                createdAt = int(
                    mktime(dt.timetuple()) + dt.microsecond / 1000000.0)
                edentiti_verification_data = {
                    "service_provider": "edentiti",
                    "edentiti_status": res['return']['outcome'],
                    "id": res['return']['transactionId'],
                    "user_id": res['return']['userId'],
                    "status": res['return']['outcome'],
                    "created_at": createdAt,
                    "updated_at": createdAt
                }
                if res['return']['outcome'] == "IN_PROGRESS":
                    edentiti_verification_data["status"] = "progress"
                    verified = 2

                if edentiti_verification_data["status"] == "valid":
                    verified = 3

                self.sendJSON(
                    MessageBuilder.verifyCustomer(
                        user_id, verified,
                        json.dumps(edentiti_verification_data)))

            except Exception:
                pass
def run_application(options, instance_name):
    input_log_file_handler = logging.handlers.TimedRotatingFileHandler(
        os.path.expanduser(options.mailer_log), when='MIDNIGHT')
    input_log_file_handler.setFormatter(
        logging.Formatter(u"%(asctime)s - %(message)s"))

    mail_logger = logging.getLogger(instance_name)
    mail_logger.setLevel(logging.INFO)
    mail_logger.addHandler(input_log_file_handler)

    ch = logging.StreamHandler(sys.stdout)
    ch.setLevel(logging.DEBUG)
    ch.setFormatter(
        logging.Formatter(
            '%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
    mail_logger.addHandler(ch)

    mail_logger.info('START')

    def log(command, key, value=None):
        log_msg = u'%s, %s, %s' % (command, key, value if value else None)
        mail_logger.info(unicode(log_msg))

    log('PARAM', 'BEGIN')
    log('PARAM', 'trade_in', options.trade_in)
    log('PARAM', 'trade_pub', options.trade_pub)
    log('PARAM', 'mailer_log', options.mailer_log)
    log('PARAM', 'mailchimp_apikey', options.mailchimp_apikey)
    log('PARAM', 'mandrill_apikey', options.mandrill_apikey)
    log('PARAM', 'mailer_username', options.mailer_username)
    log('PARAM', 'mailchimp_newsletter_list_id',
        options.mailchimp_newsletter_list_id)
    log('PARAM', 'END')

    context = zmq.Context()
    socket = context.socket(zmq.SUB)
    socket.connect(options.trade_pub)
    socket.setsockopt(zmq.SUBSCRIBE, "^EMAIL$")

    trade_in_socket = context.socket(zmq.REQ)
    trade_in_socket.connect(options.trade_in)

    application_trade_client = TradeClient(context, trade_in_socket)
    application_trade_client.connect()

    login_response = application_trade_client.sendJSON(
        MessageBuilder.login(8999999, options.mailer_username,
                             options.mailer_password))
    if login_response.get('UserStatus') != 1:
        raise RuntimeError("Invalid user id")

    brokers = {}
    broker_list, broker_list_columns = application_trade_client.getBrokerList(
        ['1'])
    for b in broker_list:
        brokers[b[0]] = {"params": b}

    broker_mandrill_column_index = None
    try:
        broker_mandrill_column_index = broker_list_columns.index(
            'MandrillApiKey')
    except ValueError:
        pass

    for broker_id, broker_data in brokers.iteritems():
        if broker_mandrill_column_index and broker_data['params'][
                broker_mandrill_column_index]:
            broker_data['MandrillApiKey'] = broker_data['params'][
                broker_mandrill_column_index]
        else:
            broker_data['MandrillApiKey'] = options.mandrill_apikey

    for broker_id, broker_data in brokers.iteritems():
        print broker_id, broker_data['MandrillApiKey']

    # [u'BrokerID', u'ShortName', u'BusinessName', u'Address', u'City', u'State',
    #  u'ZipCode', u'Country', u'PhoneNumber1', u'PhoneNumber2', u'Skype', u'Currencies',
    #  u'TosUrl', u'FeeStructure', u'TransactionFeeBuy', u'TransactionFeeSell', u'Status',
    #  u'ranking', u'Email', u'CountryCode', u'CryptoCurrencies', u'WithdrawStructure',
    #  u'SupportURL', u'SignupLabel', u'AcceptCustomersFrom', u'IsBrokerHub']

    mailchimp_api = mailchimp.Mailchimp(options.mailchimp_apikey)
    try:
        mailchimp_api.helper.ping()
    except mailchimp.Error:
        raise RuntimeError("Invalid MailChimp API key")

    mandrill_api = mandrill.Mandrill(options.mandrill_apikey)
    try:
        mandrill_api.users.ping()
    except mandrill.Error:
        raise RuntimeError("Invalid Mandrill API key")

    while True:
        try:
            raw_email_message = socket.recv()
            log('IN', 'TRADE_IN_PUB', raw_email_message)

            msg = JsonMessage(raw_email_message)

            if not msg.isEmail():
                log('ERROR', 'EXCEPTION',
                    'Received message is not an email message')
                continue

            try:
                broker_id = msg.get('BrokerID')
                sender =  brokers[broker_id]['params'][broker_list_columns.index('MailerFromName')]  + \
                          '<' + brokers[broker_id]['params'][broker_list_columns.index('MailerFromEmail')] + '>'
                body = ""
                msg_to = msg.get('To')
                subject = msg.get('Subject')
                language = msg.get('Language')
                content_type = 'plain'

                if msg.has('Template') and msg.get('Template'):
                    params = {}
                    if msg.has('Params') and msg.get('Params'):
                        params = json.loads(msg.get('Params'))

                    template_name = msg.get('Template')

                    if template_name == 'welcome':
                        # user signup .... let's register him on mailchimp newsletter
                        try:
                            mailchimp_api.lists.subscribe(
                                id=brokers[broker_id]['params']
                                [broker_list_columns.index('MailchimpListID')],
                                email={'email': params['email']},
                                merge_vars={
                                    'EMAIL': params['email'],
                                    'FNAME': params['username']
                                })

                        except mailchimp.ListAlreadySubscribedError:
                            log(
                                'ERROR', 'EXCEPTION', params['email'] +
                                ' mailchimp.ListAlreadySubscribedError')
                        except mailchimp.Error, e:
                            log('ERROR', 'EXCEPTION', str(e))

                    template_content = []
                    for k, v in params.iteritems():
                        template_content.append({'name': k, 'content': v})

                    for broker_column_key in broker_list_columns:
                        broker_column_value = brokers[broker_id]['params'][
                            broker_list_columns.index(broker_column_key)]
                        template_content.append({
                            'name':
                            'broker_' +
                            convertCamelCase2Underscore(broker_column_key),
                            'content':
                            broker_column_value
                        })

                    message = {
                        'from_email':
                        brokers[broker_id]['params'][broker_list_columns.index(
                            'MailerFromEmail')],
                        'from_name':
                        brokers[broker_id]['params'][broker_list_columns.index(
                            'MailerFromName')],
                        'to': [{
                            'email': msg_to,
                            'name': params['username'],
                            'type': 'to'
                        }],
                        'metadata': {
                            'website': 'www.blinktrade.com'
                        },
                        'global_merge_vars':
                        template_content
                    }

                    result = mandrill_api.messages.send_template(
                        template_name=(template_name + '-' +
                                       language.replace('_', '-')).lower(),
                        template_content=template_content,
                        message=message)

                    log('INFO', 'SUCCESS', str(result))
                    continue

                elif msg.has('RawData') and msg.get('RawData'):
                    body = msg.get('RawData')

                    log(
                        'DEBUG', 'EMAIL',
                        u'{"Sender":"%s","To":"%s","Subject":"%s", "Body":"%s" }'
                        % (sender, msg_to, subject, body))
                    send_email(sender, msg_to, subject, body, content_type)
                    log('IN', 'SENT', "")

                    log('INFO', 'SUCCESS', msg.get('EmailThreadID'))
            except Exception as ex:
                traceback.print_exc()
                log('ERROR', 'EXCEPTION', str(ex))
                time.sleep(1)

        except KeyboardInterrupt:
            mail_logger.info('END')
            break