From 01520adbc38f6f59a543897e8796c86b1cb4abb9 Mon Sep 17 00:00:00 2001 From: Rene Vergara Date: Tue, 2 Nov 2021 16:13:24 -0500 Subject: [PATCH] Implement database price feed --- backend/app.js | 54 +++++++++++++++++++++++++----- backend/models/price.js | 10 ++++++ src/app/fullnode.service.ts | 16 ++++++--- src/app/login/login.component.html | 1 + src/app/login/login.component.ts | 32 ++++++++++++------ src/app/user.service.ts | 6 ++-- 6 files changed, 93 insertions(+), 26 deletions(-) create mode 100644 backend/models/price.js diff --git a/backend/app.js b/backend/app.js index 1d812ec..163387f 100644 --- a/backend/app.js +++ b/backend/app.js @@ -6,6 +6,7 @@ const usermodel = require('./models/user'); const ownermodel = require('./models/owner'); const itemmodel = require('./models/item'); const ordermodel = require('./models/order'); +const pricemodel = require('./models/price'); const mongoose = require('mongoose'); const stdrpc = require('stdrpc'); const CoinGecko = require('coingecko-api'); @@ -27,6 +28,41 @@ const rpc = stdrpc({ const CoinGeckoClient = new CoinGecko(); +var intervalObject = setInterval( function() { + CoinGeckoClient.simple.price({ + ids: ['zcash'], + vs_currencies: ['usd', 'gbp', 'eur', 'cad', 'aud'] + }).then((data) => { + pricemodel.findOneAndUpdate({currency: 'usd'}, { price: data.data.zcash.usd, timestamp: Date.now()}, {new:true, upsert:true}, function(err,docs) { + if(err) { + console.log(err); + } + }); + pricemodel.findOneAndUpdate({currency: 'gbp'}, { price: data.data.zcash.gbp, timestamp: Date.now()}, {new:true, upsert:true}, function(err,docs) { + if(err) { + console.log(err); + } + }); + pricemodel.findOneAndUpdate({currency: 'eur'}, { price: data.data.zcash.eur, timestamp: Date.now()}, {new:true, upsert:true}, function(err,docs) { + if(err) { + console.log(err); + } + }); + pricemodel.findOneAndUpdate({currency: 'cad'}, { price: data.data.zcash.cad, timestamp: Date.now()}, {new:true, upsert:true}, function(err,docs) { + if(err) { + console.log(err); + } + }); + pricemodel.findOneAndUpdate({currency: 'aud'}, { price: data.data.zcash.aud, timestamp: Date.now()}, {new:true, upsert:true}, function(err,docs) { + if(err) { + console.log(err); + } + }); + }).catch((err) => { + console.log(err); + }); +}, 90000); + app.use(bodyparser.json()); app.use((req, res, next) => { @@ -248,17 +284,19 @@ app.delete('/api/item/:id', (req, res, next) => { app.get('/api/price', (req, res, next) => { console.log('Get /api/price'); - CoinGeckoClient.simple.price({ - ids: ['zcash'], - vs_currencies: ['usd'] - }). - then((data) => { - + const price = pricemodel.findOne({currency: 'usd'}).then((document) => { + if (document != null) { res.status(200).json({ message: 'price found!', - price: data.data.zcash.usd + price: document }); - }); + } else { + res.status(204).json({ + message: 'no price found!', + order: null + }); + } + }); }); app.get('/api/order', (req, res, next) => { diff --git a/backend/models/price.js b/backend/models/price.js new file mode 100644 index 0000000..7d3aaeb --- /dev/null +++ b/backend/models/price.js @@ -0,0 +1,10 @@ +const mongoose = require('mongoose'); + +const priceSchema = mongoose.Schema({ + currency: {type: String, required: true}, + price: {type: Number, required: true}, + timestamp: {type: Date, required: true, default: Date.now} +}); + + +module.exports = mongoose.model('Price', priceSchema); diff --git a/src/app/fullnode.service.ts b/src/app/fullnode.service.ts index 09a711b..d2e8389 100644 --- a/src/app/fullnode.service.ts +++ b/src/app/fullnode.service.ts @@ -36,11 +36,17 @@ export class FullnodeService{ } getPrice(){ - let obs = this.http.get<{message: string, price: number}>('http://localhost:3000/api/price'); + var currency = 'usd'; + const params = new HttpParams().append('currency', currency); + let obs = this.http.get<{message: string, price: any}>('http://localhost:3000/api/price', { headers:{}, params: params, observe: 'response'}); obs.subscribe((PriceData) => { - this.dataStore.price = PriceData.price; - console.log(this.dataStore.price); - this._priceUpdated.next(Object.assign({},this.dataStore).price); + if (PriceData.status == 200) { + this.dataStore.price = PriceData.body!.price.price; + console.log("price", this.dataStore.price); + this._priceUpdated.next(Object.assign({},this.dataStore).price); + } else { + console.log('No price found for currency', currency); + } }); return obs; @@ -59,7 +65,7 @@ export class FullnodeService{ subscribe((TxData) => { var memos: string[] = []; //this.addr = TxData.addr; - var re = /.*S4ZEC::(.*)\sReply-To:\s(z\w+)/; + var re = /.*ZGO::(.*)\sReply-To:\s(z\w+)/; for (var i=0; i < TxData.txs.length; i++) { var memo = this.hexToString(TxData.txs[i].memo); //console.log(TxData.txs[i].blocktime); diff --git a/src/app/login/login.component.html b/src/app/login/login.component.html index 3aa5a7c..2a20d85 100644 --- a/src/app/login/login.component.html +++ b/src/app/login/login.component.html @@ -12,6 +12,7 @@ || +

Last block seen: {{ heightUpdate | async }}

diff --git a/src/app/login/login.component.ts b/src/app/login/login.component.ts index 1255c05..a9942c3 100644 --- a/src/app/login/login.component.ts +++ b/src/app/login/login.component.ts @@ -1,8 +1,8 @@ -import { Component, OnInit, OnDestroy, Injectable } from '@angular/core'; +import { Component, OnInit, OnDestroy, Injectable, ChangeDetectorRef } from '@angular/core'; import { CanActivate, Router, RouterStateSnapshot, ActivatedRouteSnapshot, ActivatedRoute } from '@angular/router'; import { UserService } from '../user.service'; import { FullnodeService } from '../fullnode.service'; -import { Subscription } from 'rxjs'; +import { Subscription, Observable } from 'rxjs'; import { v4 as uuidv4 } from 'uuid'; var QRCode = require('easyqrcodejs'); var URLSafeBase64 = require('urlsafe-base64'); @@ -16,33 +16,39 @@ var Buffer = require('buffer/').Buffer; }) export class LoginComponent implements OnInit { + intervalHolder: any; memos: string[] = []; nodeAddress: string = ''; private FullnodeSub: Subscription = new Subscription(); private UserSub: Subscription = new Subscription(); + public heightUpdate: Observable; + public uZaddrUpdate: Observable; constructor( private activatedRoute: ActivatedRoute, public fullnodeService: FullnodeService, private router: Router, - public userService: UserService + public userService: UserService, + private _changeDetectorRef: ChangeDetectorRef ){ //this.fullnodeService.getAddr(); + this.heightUpdate = fullnodeService.heightUpdate; + this.uZaddrUpdate = userService.uZaddrUpdate; } ngOnInit(){ - console.log('Activated route data in Component:::', this.activatedRoute.data); + //console.log('Activated route data in Component:::', this.activatedRoute.data); this.activatedRoute.data.subscribe((addrData) => { - console.log('FETCH ADDRESS', addrData); + //console.log('FETCH ADDRESS', addrData); this.nodeAddress = addrData.response.addr; - console.log('Node addres ', this.nodeAddress); + //console.log('Node addres ', this.nodeAddress); var localToken = localStorage.getItem('s4z_token'); - console.log(localToken); + //console.log(localToken); if(localToken == null){ var token = uuidv4(); localStorage.setItem('s4z_token', token); console.log('Showing QR code for login'); - console.log(URLSafeBase64.encode(Buffer.from('S4ZEC::'.concat(token)))); - var codeString = `zcash:${this.nodeAddress}?amount=0.001&memo=${URLSafeBase64.encode(Buffer.from('S4ZEC::'.concat(token)))}`; + console.log(URLSafeBase64.encode(Buffer.from('ZGO::'.concat(token)))); + var codeString = `zcash:${this.nodeAddress}?amount=0.001&memo=${URLSafeBase64.encode(Buffer.from('ZGO::'.concat(token)))}`; console.log(codeString); var qrcode = new QRCode(document.getElementById("qrcode"), { text: codeString, @@ -61,7 +67,7 @@ export class LoginComponent implements OnInit { console.log('No login for existing token found'); console.log('Showing QR code for login'); //console.log(URLSafeBase64.encode(Buffer.from('S4ZEC::'.concat(localToken)))); - var codeString = `zcash:${this.nodeAddress}?amount=0.001&memo=${URLSafeBase64.encode(Buffer.from('S4ZEC::'.concat(localToken!)))}`; + var codeString = `zcash:${this.nodeAddress}?amount=0.001&memo=${URLSafeBase64.encode(Buffer.from('ZGO::'.concat(localToken!)))}`; console.log(codeString); var qrcode = new QRCode(document.getElementById("qrcode"), { text: codeString, @@ -73,10 +79,16 @@ export class LoginComponent implements OnInit { }); } }); + this.intervalHolder = setInterval(() => { + this.fullnodeService.getHeight(); + this.fullnodeService.getMemos(); + this._changeDetectorRef.markForCheck(); + }, 1000 * 75); } ngOnDestroy(){ this.FullnodeSub.unsubscribe(); this.UserSub.unsubscribe(); + clearInterval(this.intervalHolder); } } diff --git a/src/app/user.service.ts b/src/app/user.service.ts index 32766c4..0053bf2 100644 --- a/src/app/user.service.ts +++ b/src/app/user.service.ts @@ -33,12 +33,12 @@ export class UserService{ constructor(private http: HttpClient){ this.session = localStorage.getItem('s4z_token'); if (this.session != null) { - this.findUser(this.session); + this.findUser(); } } - findUser(session: string) { - const params = new HttpParams().append('session', session); + findUser() { + const params = new HttpParams().append('session', this.session!); let obs = this.http.get<{message: string, user: any}>('http://localhost:3000/api/getuser', { headers:{}, params: params, observe: 'response'}); obs.subscribe((UserDataResponse) => {