Пример #1
0
    async def post(self):
        data = self.request.body.decode('utf-8')
        data = json.loads(data)
        data['block'] = json.loads(data['block'])

        if data['block']['type'] == 'send':
            target = data['block']['destination']
            if subscriptions.get(target):
                print("             Pushing to client %s" % subscriptions[target])
                logging.info('push to client;' + json.dumps(data['block']) + ';' + subscriptions[target])
                clients[subscriptions[target]].write_message(json.dumps(data))
        elif data['block']['type'] == 'state':
            link = data['block']['link_as_account']
            if subscriptions.get(link):
                print("             Pushing to client %s" % subscriptions[link])
                logging.info('push to client;' + json.dumps(data) + ';' + subscriptions[link])
                clients[subscriptions[link]].write_message(json.dumps(data))
            # Push FCM notification if this is a send
            fcm_tokens = get_fcm_tokens(link)
            if fcm_tokens is None or len(fcm_tokens) == 0:
                return
            rpc = tornado.httpclient.AsyncHTTPClient()
            response = await rpc_request(rpc, json.dumps({"action":"block", "hash":data['block']['previous']}))
            if response is None or response.error:
                return
            # See if this block was already pocketed
            cached_hash = rdata.get(f"link_{data['hash']}")
            if cached_hash is not None:
                return
            prev_data = json.loads(response.body.decode('ascii'))
            prev_data = prev_data['contents'] = json.loads(prev_data['contents'])
            prev_balance = int(prev_data['contents']['balance'])
            cur_balance = int(data['block']['balance'])
            send_amount = prev_balance - cur_balance
            if send_amount >= 1000000000000000000000000:
                # This is a send, push notifications
                fcm = aiofcm.FCM(fcm_sender_id, fcm_api_key)
                # Send notification with generic title, send amount as body. App should have localizations and use this information at its discretion
                for t in fcm_tokens:
                    message = aiofcm.Message(
                                device_token=t,
                                data = {
                                    "amount": str(send_amount)
                                }
                    )
                    await fcm.send_message(message)
        elif subscriptions.get(data['account']):
            print("             Pushing to client %s" % subscriptions[data['account']])
            logging.info('push to client;' + json.dumps(data) + ';' + subscriptions[data['account']])
            clients[subscriptions[data['account']]].write_message(json.dumps(data))
Пример #2
0
async def check_and_do_push_notification(redis: Redis, op):
    # Only if configured
    if fcm_client is None:
        return
    # Only do pending operations, and only to the receiver
    if op['maturation'] is not None or 'receivers' not in op or not op[
            'receivers']:
        return
    # Check if we already pushed this op
    op_pushed = await redis.get(f'pncache_{op["ophash"]}')
    if op_pushed is not None:
        return
    else:
        await redis.set(f'pncache_{op["ophash"]}', 'tru', expire=10000)
    # Check tokens
    fcm_tokens = await get_fcm_tokens(op['receivers'][0]['account'], redis)
    notification_title = f"Received {abs(float(op['receivers'][0]['amount']))} PASCAL"
    notification_body = f"Open Blaise to view this transaction."
    for t in fcm_tokens:
        b58_pubkey = await redis.get(f'fcm{t}')
        if b58_pubkey is not None:
            # Verify pubkey
            account = op['receivers'][0]['account']
            acct_resp = await jrpc_client.getaccount(account)
            if acct_resp is None:
                continue
            expected_pubkey_enc = acct_resp['enc_pubkey'].upper()
            if Util.b58_to_enc_pubkey(b58_pubkey) != expected_pubkey_enc:
                continue
        message = aiofcm.Message(device_token=t,
                                 notification={
                                     "title": notification_title,
                                     "body": notification_body,
                                     "sound": "default",
                                     "tag": str(op['receivers'][0]['account'])
                                 },
                                 data={
                                     "click_action":
                                     "FLUTTER_NOTIFICATION_CLICK",
                                     "account":
                                     str(op['receivers'][0]['account'])
                                 },
                                 priority=aiofcm.PRIORITY_HIGH)
        await fcm_client.send_message(message)
Пример #3
0
async def callback(r: web.Request):
    try:
        request_json = await r.json()
        hash = request_json['hash']
        log.server_logger.debug(f"callback received {hash}")
        request_json['block'] = json.loads(request_json['block'])

        link = request_json['block']['link_as_account']

        # Push FCM notification if this is a send
        if fcm_api_key is None:
            return web.HTTPOk()
        fcm_tokens = set(await get_fcm_tokens(link, r))
        fcm_tokens_v2 = set(await get_fcm_tokens(link, r, v2=True))
        if (fcm_tokens is None or len(fcm_tokens)
                == 0) and (fcm_tokens_v2 is None or len(fcm_tokens_v2) == 0):
            return web.HTTPOk()
        message = {
            "action": "block",
            "hash": request_json['block']['previous']
        }
        response = await rpc.json_post(message)
        if response is None:
            return web.HTTPOk()
        # See if this block was already pocketed
        cached_hash = await r.app['rdata'].get(f"link_{hash}")
        if cached_hash is not None:
            return web.HTTPOk()
        prev_data = response
        prev_data = prev_data['contents'] = json.loads(prev_data['contents'])
        prev_balance = int(prev_data['contents']['balance'])
        cur_balance = int(request_json['block']['balance'])
        send_amount = prev_balance - cur_balance
        if send_amount >= 1000000000000000000000000:
            # This is a send, push notifications
            fcm = aiofcm.FCM(fcm_sender_id, fcm_api_key)
            # Send notification with generic title, send amount as body. App should have localizations and use this information at its discretion
            for t in fcm_tokens:
                message = aiofcm.Message(device_token=t,
                                         data={"amount": str(send_amount)},
                                         priority=aiofcm.PRIORITY_HIGH)
                await fcm.send_message(message)
            notification_title = f"Received {util.raw_to_nano(send_amount)} {'NANO' if not banano_mode else 'BANANO'}"
            notification_body = f"Open {'Natrium' if not banano_mode else 'Kalium'} to view this transaction."
            for t2 in fcm_tokens_v2:
                message = aiofcm.Message(device_token=t2,
                                         notification={
                                             "title": notification_title,
                                             "body": notification_body,
                                             "sound": "default",
                                             "tag": link
                                         },
                                         data={
                                             "click_action":
                                             "FLUTTER_NOTIFICATION_CLICK",
                                             "account": link
                                         },
                                         priority=aiofcm.PRIORITY_HIGH)
                await fcm.send_message(message)
        return web.HTTPOk()
    except Exception:
        log.server_logger.exception("received exception in callback")
        return web.HTTPInternalServerError(
            reason=f"Something went wrong {str(sys.exc_info())}")
    async def post(self):
        data = self.request.body.decode('utf-8')
        data = json.loads(data)
        data['block'] = json.loads(data['block'])

        if data['block']['type'] == 'send':
            target = data['block']['destination']
            if subscriptions.get(target):
                print("             Pushing to client %s" % subscriptions[target])
                logging.info('push to client;' + json.dumps(data['block']) + ';' + subscriptions[target])
                clients[subscriptions[target]].write_message(json.dumps(data))
        elif data['block']['type'] == 'state':
            link = data['block']['link_as_account']
            if subscriptions.get(link):
                print("             Pushing to client %s" % subscriptions[link])
                logging.info('push to client;' + json.dumps(data) + ';' + subscriptions[link])
                clients[subscriptions[link]].write_message(json.dumps(data))
            # Push FCM notification if this is a send
            fcm_tokens = set(get_fcm_tokens(link))
            fcm_tokens_v2 = set(get_fcm_tokens(link, v2=True))
            if (fcm_tokens is None or len(fcm_tokens) == 0) and (fcm_tokens_v2 is None or len(fcm_tokens_v2) == 0):
                return
            rpc = tornado.httpclient.AsyncHTTPClient()
            response = await rpc_request(rpc, json.dumps({"action":"block", "hash":data['block']['previous']}))
            if response is None or response.error:
                return
            # See if this block was already pocketed
            cached_hash = rdata.get(f"link_{data['hash']}")
            if cached_hash is not None:
                return
            prev_data = json.loads(response.body.decode('ascii'))
            prev_data = prev_data['contents'] = json.loads(prev_data['contents'])
            prev_balance = int(prev_data['contents']['balance'])
            cur_balance = int(data['block']['balance'])
            send_amount = prev_balance - cur_balance
            if send_amount >= 1000000000000000000000000:
                # This is a send, push notifications
                fcm = aiofcm.FCM(fcm_sender_id, fcm_api_key)
                # Send notification with generic title, send amount as body. App should have localizations and use this information at its discretion
                for t in fcm_tokens:
                    message = aiofcm.Message(
                                device_token=t,
                                data = {
                                    "amount": str(send_amount)
                                },
                                priority=aiofcm.PRIORITY_HIGH
                    )
                    await fcm.send_message(message)
                notification_title = f"Received {NanoConversions.raw_to_nano(send_amount)} NANO"
                notification_body = "Open Natrium to view this transaction."
                for t2 in fcm_tokens_v2:
                    message = aiofcm.Message(
                        device_token = t2,
                        notification = {
                            "title":notification_title,
                            "body":notification_body,
                            "sound":"default",
                            "tag":link
                        },
                        data = {
                            "click_action": "FLUTTER_NOTIFICATION_CLICK",
                            "account": link
                        },
                        priority=aiofcm.PRIORITY_HIGH
                    )
                    await fcm.send_message(message)
        elif subscriptions.get(data['account']):
            print("             Pushing to client %s" % subscriptions[data['account']])
            logging.info('push to client;' + json.dumps(data) + ';' + subscriptions[data['account']])
            clients[subscriptions[data['account']]].write_message(json.dumps(data))
Пример #5
0
async def callback(r : web.Request):
    try:
        request_json = await r.json()
        hash = request_json['hash']
        log.server_logger.debug(f"callback received {hash}")
        request_json['block'] = json.loads(request_json['block'])

        link = request_json['block']['link_as_account']
        if r.app['subscriptions'].get(link):
            log.server_logger.info("Pushing to clients %s", str(r.app['subscriptions'][link]))
            for sub in r.app['subscriptions'][link]:
                if sub in r.app['clients']:
                    await r.app['clients'][sub].send_str(json.dumps(request_json))

        # If natrium account and send, send to web page for donations
        if 'is_send' in request_json and (request_json['is_send'] or request_json['is_send'] == 'true') and link == 'nano_1natrium1o3z5519ifou7xii8crpxpk8y65qmkih8e8bpsjri651oza8imdd':
            log.server_logger.info('Detected send to natrium account')
            if 'amount' in request_json:
                log.server_logger.info(f'emitting donation event for amount: {request_json["amount"]}')
                await sio.emit('donation_event', {'amount':request_json['amount']})

        # Push FCM notification if this is a send
        if fcm_api_key is None:
            return web.HTTPOk()
        fcm_tokens = set(await get_fcm_tokens(link, r))
        fcm_tokens_v2 = set(await get_fcm_tokens(link, r, v2=True))
        if (fcm_tokens is None or len(fcm_tokens) == 0) and (fcm_tokens_v2 is None or len(fcm_tokens_v2) == 0):
            return web.HTTPOk()
        message = {
            "action":"block",
            "hash":request_json['block']['previous']
        }
        response = await rpc.json_post(message)
        if response is None:
            return web.HTTPOk()
        # See if this block was already pocketed
        cached_hash = await r.app['rdata'].get(f"link_{hash}")
        if cached_hash is not None:
            return web.HTTPOk()
        prev_data = response
        prev_data = prev_data['contents'] = json.loads(prev_data['contents'])
        prev_balance = int(prev_data['contents']['balance'])
        cur_balance = int(request_json['block']['balance'])
        send_amount = prev_balance - cur_balance
        if send_amount >= 1000000000000000000000000:
            # This is a send, push notifications
            fcm = aiofcm.FCM(fcm_sender_id, fcm_api_key)
            # Send notification with generic title, send amount as body. App should have localizations and use this information at its discretion
            for t in fcm_tokens:
                message = aiofcm.Message(
                            device_token=t,
                            data = {
                                "amount": str(send_amount)
                            },
                            priority=aiofcm.PRIORITY_HIGH
                )
                await fcm.send_message(message)
            notification_title = f"Received {util.raw_to_nano(send_amount)} {'NANO' if not banano_mode else 'BANANO'}"
            notification_body = f"Open {'Natrium' if not banano_mode else 'Kalium'} to view this transaction."
            for t2 in fcm_tokens_v2:
                message = aiofcm.Message(
                    device_token = t2,
                    notification = {
                        "title":notification_title,
                        "body":notification_body,
                        "sound":"default",
                        "tag":link
                    },
                    data = {
                        "click_action": "FLUTTER_NOTIFICATION_CLICK",
                        "account": link
                    },
                    priority=aiofcm.PRIORITY_HIGH
                )
                await fcm.send_message(message)
        return web.HTTPOk()
    except Exception:
        log.server_logger.exception("received exception in callback")
        return web.HTTPInternalServerError(reason=f"Something went wrong {str(sys.exc_info())}")