def create_transfer(amount, sender_user, recipient_user, token, subtype=None): transfer = CreditTransfer( amount=amount, sender_user=sender_user, recipient_user=recipient_user, token=token, uuid=str(uuid4())) db.session.add(transfer) # Mimics before_request hook g.pending_transactions = [] transfer.resolve_as_completed() # Mimics after_request hook for transaction, queue in g.pending_transactions: transaction.send_blockchain_payload_to_worker(queue=queue) transfer.transfer_type = TransferTypeEnum.PAYMENT transfer.transfer_subtype = subtype # Commit to prevent memory errors with large numbers of txns counts db.session.commit() return transfer
def make_deposit_transfer(transfer_amount, token, receive_account, transfer_mode=None, automatically_resolve_complete=True, uuid=None, fiat_ramp=None): """ This is used for a user depositing funds to their Sempo wallet. Only interacts with Sempo float. :param transfer_amount: :param token: :param receive_account: :param transfer_mode: :param automatically_resolve_complete: :param uuid: :param fiat_ramp: A FiatRamp Object to tie to credit transfer :return: """ transfer = CreditTransfer(amount=transfer_amount, token=token, recipient_user=receive_account, transfer_type=TransferTypeEnum.DEPOSIT, transfer_mode=transfer_mode, uuid=uuid, fiat_ramp=fiat_ramp) if automatically_resolve_complete: transfer.resolve_as_completed() return transfer
def create_transfer(amount, sender_user, recipient_user, token, subtype=None): transfer = CreditTransfer( amount=amount, sender_user=sender_user, recipient_user=recipient_user, token=token, uuid=str(uuid4())) db.session.add(transfer) transfer.resolve_as_completed() transfer.transfer_type = TransferTypeEnum.PAYMENT transfer.transfer_subtype = subtype return transfer
def migrate_balances(self, ge_address_to_user: dict): org = Organisation.query.get(self.sempo_organisation_id) token = org.token ge_address_to_user.pop(None, None) addresses = list(ge_address_to_user.keys()) for user_address in addresses: try: balance_wei = 0 for ge_token in GE_MIGRATION_TOKENS.keys(): contract_address = GE_MIGRATION_TOKENS[ge_token] v = get_token_balance(user_address, contract_address) if v != '': balance_wei += int(v) user = ge_address_to_user[user_address] print(f'transfering {balance_wei} wei to {user}') if balance_wei != 0: migration_transfer = CreditTransfer( amount=balance_wei / 1e16, token=token, sender_transfer_account=org. queried_org_level_transfer_account, recipient_user=user, transfer_type=TransferTypeEnum.PAYMENT, transfer_subtype=TransferSubTypeEnum.DISBURSEMENT) db.session.add(migration_transfer) migration_transfer.resolve_as_completed() except Exception as e: print(e) sentry_sdk.capture_exception(e) pass
def make_withdrawal_transfer(transfer_amount, token, send_account, transfer_mode=None, require_sender_approved=True, require_sufficient_balance=True, automatically_resolve_complete=True, uuid=None): """ This is used for a user withdrawing funds from their Sempo wallet. Only interacts with Sempo float. :param transfer_amount: :param token: :param send_account: :param transfer_mode: :param require_sender_approved: :param require_sufficient_balance: :param automatically_resolve_complete: :param uuid: :return: """ transfer = CreditTransfer(transfer_amount, token, sender_user=send_account, uuid=uuid, transfer_type=TransferTypeEnum.WITHDRAWAL) transfer.transfer_mode = transfer_mode if require_sender_approved and not transfer.check_sender_is_approved(): message = "Sender {} is not approved".format(send_account) transfer.resolve_as_rejected(message) raise AccountNotApprovedError(message, is_sender=True) if require_sufficient_balance and not transfer.check_sender_has_sufficient_balance( ): message = "Sender {} has insufficient balance".format(send_account) transfer.resolve_as_rejected(message) raise InsufficientBalanceError(message) if automatically_resolve_complete: transfer.resolve_as_completed() pusher.push_admin_credit_transfer(transfer) return transfer
def create_transfer(amount, sender_user, recipient_user, token, subtype=None): transfer = CreditTransfer( amount=amount, sender_user=sender_user, recipient_user=recipient_user, token=token, uuid=str(uuid4())) db.session.add(transfer) transfer.resolve_as_completed() transfer.transfer_type = TransferTypeEnum.PAYMENT transfer.transfer_subtype = subtype # Commit to prevent memory errors with large numbers of txns counts db.session.commit() return transfer
def make_payment_transfer( transfer_amount, token=None, send_user=None, send_transfer_account=None, receive_user=None, receive_transfer_account=None, transfer_use=None, transfer_mode=None, require_sender_approved=True, require_recipient_approved=True, require_sufficient_balance=True, automatically_resolve_complete=True, uuid=None, transfer_subtype: TransferSubTypeEnum = TransferSubTypeEnum.STANDARD, is_ghost_transfer=False, queue='high-priority'): """ This is used for internal transfers between Sempo wallets. :param transfer_amount: :param token: :param send_user: :param send_transfer_account: :param receive_user: :param receive_transfer_account: :param transfer_use: :param transfer_mode: TransferModeEnum :param require_sender_approved: :param require_recipient_approved: :param require_sufficient_balance: :param automatically_resolve_complete: :param uuid: :param transfer_subtype: accepts TransferSubType str. :param is_ghost_transfer: if an account is created for recipient just to exchange, it's not real :param enable_pusher: :param queue: :return: """ if transfer_subtype is TransferSubTypeEnum.DISBURSEMENT: require_sender_approved = False require_recipient_approved = False require_sufficient_balance = False # primary NGO wallet to disburse from send_transfer_account = receive_user.default_organisation.queried_org_level_transfer_account if transfer_subtype is TransferSubTypeEnum.RECLAMATION: require_sender_approved = False # primary NGO wallet to reclaim to receive_transfer_account = send_user.default_organisation.queried_org_level_transfer_account if transfer_subtype is TransferSubTypeEnum.INCENTIVE: send_transfer_account = receive_transfer_account.get_float_transfer_account( ) transfer = CreditTransfer( transfer_amount, token=token, sender_user=send_user, sender_transfer_account=send_transfer_account, recipient_user=receive_user, recipient_transfer_account=receive_transfer_account, uuid=uuid, transfer_type=TransferTypeEnum.PAYMENT, transfer_subtype=transfer_subtype, transfer_mode=transfer_mode, is_ghost_transfer=is_ghost_transfer) make_cashout_incentive_transaction = False if transfer_use is not None: usages = [] try: use_ids = transfer_use.split(',') # passed as '3,4' etc. except AttributeError: use_ids = transfer_use for use_id in use_ids: if use_id != 'null': use = TransferUsage.query.get(int(use_id)) if use: usages.append(use.name) if use.is_cashout: make_cashout_incentive_transaction = True else: usages.append('Other') transfer.transfer_use = usages transfer.uuid = uuid if require_sender_approved and not transfer.check_sender_is_approved(): message = "Sender {} is not approved".format(send_transfer_account) transfer.resolve_as_rejected(message) raise AccountNotApprovedError(message, is_sender=True) if require_recipient_approved and not transfer.check_recipient_is_approved( ): message = "Recipient {} is not approved".format(receive_user) transfer.resolve_as_rejected(message) raise AccountNotApprovedError(message, is_sender=False) if require_sufficient_balance and not transfer.check_sender_has_sufficient_balance( ): message = "Sender {} has insufficient balance".format( send_transfer_account) transfer.resolve_as_rejected(message) raise InsufficientBalanceError(message) if automatically_resolve_complete: transfer.resolve_as_completed(queue=queue) if make_cashout_incentive_transaction: try: # todo: check limits apply incentive_amount = round( transfer_amount * current_app.config['CASHOUT_INCENTIVE_PERCENT'] / 100) make_payment_transfer( incentive_amount, receive_user=receive_user, transfer_subtype=TransferSubTypeEnum.INCENTIVE, transfer_mode=TransferModeEnum.INTERNAL) except Exception as e: print(e) sentry_sdk.capture_exception(e) return transfer