diff --git a/frontend/squeak-node-frontend/src/components/Layout/Layout.js b/frontend/squeak-node-frontend/src/components/Layout/Layout.js
index 6fe0d03a..42e097a0 100644
--- a/frontend/squeak-node-frontend/src/components/Layout/Layout.js
+++ b/frontend/squeak-node-frontend/src/components/Layout/Layout.js
@@ -20,6 +20,7 @@ import Dashboard from "../../pages/dashboard";
import SqueakAddress from "../../pages/squeakaddress";
import Squeak from "../../pages/squeak";
import Buy from "../../pages/buy";
+import Offer from "../../pages/offer";
import Profile from "../../pages/profile";
import Wallet from "../../pages/wallet";
import LightningNode from "../../pages/lightningnode";
@@ -57,6 +58,7 @@ function Layout(props) {
+
diff --git a/frontend/squeak-node-frontend/src/pages/buy/Buy.js b/frontend/squeak-node-frontend/src/pages/buy/Buy.js
index e5f70aab..c38b72a0 100644
--- a/frontend/squeak-node-frontend/src/pages/buy/Buy.js
+++ b/frontend/squeak-node-frontend/src/pages/buy/Buy.js
@@ -53,7 +53,7 @@ export default function BuyPage() {
const goToOfferPage = (offerId) => {
console.log("Go to offer page for id: " + offerId);
- // history.push("/app/offer/" + offerId);
+ history.push("/app/offer/" + offerId);
};
useEffect(()=>{
diff --git a/frontend/squeak-node-frontend/src/pages/offer/Offer.js b/frontend/squeak-node-frontend/src/pages/offer/Offer.js
new file mode 100644
index 00000000..3111fb91
--- /dev/null
+++ b/frontend/squeak-node-frontend/src/pages/offer/Offer.js
@@ -0,0 +1,94 @@
+import React, { useState, useEffect } from 'react';
+import { useParams } from 'react-router-dom';
+import {useHistory} from "react-router-dom";
+import {
+ Grid,
+ Button,
+ Divider,
+ Box,
+ Typography,
+} from "@material-ui/core";
+
+// styles
+import useStyles from "./styles";
+
+// components
+import PageTitle from "../../components/PageTitle";
+import Widget from "../../components/Widget";
+import SqueakDetailItem from "../../components/SqueakDetailItem";
+import BuyOfferItem from "../../components/BuyOfferItem";
+import MakeSqueakDialog from "../../components/MakeSqueakDialog";
+import DeleteSqueakDialog from "../../components/DeleteSqueakDialog";
+
+import {
+ GetSqueakDisplayRequest,
+ GetAncestorSqueakDisplaysRequest,
+ GetBuyOfferRequest,
+} from "../../proto/squeak_admin_pb"
+import { client } from "../../squeakclient/squeakclient"
+
+
+export default function OfferPage() {
+ var classes = useStyles();
+ const history = useHistory();
+ const { id } = useParams();
+ const [offer, setOffer] = useState(null);
+
+ const getOffer = (offerId) => {
+ console.log("Getting offer with offerId: " + offerId);
+ var getBuyOfferRequest = new GetBuyOfferRequest()
+ getBuyOfferRequest.setOfferId(offerId);
+ console.log(getBuyOfferRequest);
+
+ client.getBuyOffer(getBuyOfferRequest, {}, (err, response) => {
+ if (err) {
+ console.log(err.message);
+ alert('Error getting offer: ' + err.message);
+ return;
+ }
+ console.log(response);
+ console.log(response.getOffer());
+ setOffer(response.getOffer())
+ });
+ };
+
+ useEffect(()=>{
+ getOffer(id)
+ },[id]);
+
+ function OfferContent() {
+ return (
+ <>
+
+
+
+
+
+
+ >
+ )
+ }
+
+ function NoOfferContent() {
+ return (
+
+ No offer loaded
+
+ )
+ }
+
+ return (
+ <>
+
+ {offer
+ ? OfferContent()
+ : NoOfferContent()
+ }
+ >
+ );
+}
diff --git a/frontend/squeak-node-frontend/src/pages/offer/package.json b/frontend/squeak-node-frontend/src/pages/offer/package.json
new file mode 100644
index 00000000..ac8286ca
--- /dev/null
+++ b/frontend/squeak-node-frontend/src/pages/offer/package.json
@@ -0,0 +1,6 @@
+{
+ "name": "Offer",
+ "version": "0.0.0",
+ "main": "Offer.js",
+ "private": true
+}
diff --git a/frontend/squeak-node-frontend/src/pages/offer/styles.js b/frontend/squeak-node-frontend/src/pages/offer/styles.js
new file mode 100644
index 00000000..976accde
--- /dev/null
+++ b/frontend/squeak-node-frontend/src/pages/offer/styles.js
@@ -0,0 +1,15 @@
+import { makeStyles } from "@material-ui/styles";
+
+export default makeStyles(theme => ({
+ dashedBorder: {
+ border: "1px dashed",
+ borderColor: theme.palette.primary.main,
+ padding: theme.spacing(2),
+ paddingTop: theme.spacing(4),
+ paddingBottom: theme.spacing(4),
+ marginTop: theme.spacing(1),
+ },
+ text: {
+ marginBottom: theme.spacing(2),
+ },
+}));
diff --git a/proto/squeak_admin.proto b/proto/squeak_admin.proto
index 4f9d31a5..6d6f47ee 100644
--- a/proto/squeak_admin.proto
+++ b/proto/squeak_admin.proto
@@ -124,6 +124,10 @@ service SqueakAdmin {
*/
rpc GetBuyOffers (GetBuyOffersRequest) returns (GetBuyOffersReply) {}
+ /** sqkadmin: `getbuyoffer`
+ */
+ rpc GetBuyOffer (GetBuyOfferRequest) returns (GetBuyOfferReply) {}
+
}
message CreateSigningProfileRequest {
@@ -445,6 +449,16 @@ message GetBuyOffersReply {
repeated OfferDisplayEntry offers = 1;
}
+message GetBuyOfferRequest {
+ /// Offer id
+ int32 offer_id = 1;
+}
+
+message GetBuyOfferReply {
+ /// The offer
+ OfferDisplayEntry offer = 1;
+}
+
message OfferDisplayEntry {
/// The offer id
int32 offer_id = 1;
diff --git a/squeakserver/admin/squeak_admin_server_handler.py b/squeakserver/admin/squeak_admin_server_handler.py
index aa60e0a2..dcb3d21c 100644
--- a/squeakserver/admin/squeak_admin_server_handler.py
+++ b/squeakserver/admin/squeak_admin_server_handler.py
@@ -231,3 +231,7 @@ class SqueakAdminServerHandler(object):
def handle_get_buy_offers(self, squeak_hash_str):
logger.info("Handle get buy offers for hash: {}".format(squeak_hash_str))
return self.squeak_node.get_buy_offers_with_peer(squeak_hash_str)
+
+ def handle_get_buy_offer(self, offer_id):
+ logger.info("Handle get buy offer for hash: {}".format(offer_id))
+ return self.squeak_node.get_buy_offer_with_peer(offer_id)
diff --git a/squeakserver/admin/squeak_admin_server_servicer.py b/squeakserver/admin/squeak_admin_server_servicer.py
index 94f3a3c6..18d5d01c 100644
--- a/squeakserver/admin/squeak_admin_server_servicer.py
+++ b/squeakserver/admin/squeak_admin_server_servicer.py
@@ -249,6 +249,15 @@ class SqueakAdminServerServicer(squeak_admin_pb2_grpc.SqueakAdminServicer):
offers=offer_msgs,
)
+ def GetBuyOffer(self, request, context):
+ offer_id = request.offer_id
+ offer = self.handler.handle_get_buy_offer(offer_id)
+ offer_msg = self._offer_entry_to_message(offer)
+ logger.info("Returning buy offer: {}".format(offer_msg))
+ return squeak_admin_pb2.GetBuyOfferReply(
+ offer=offer_msg,
+ )
+
def _squeak_entry_to_message(self, squeak_entry_with_profile):
if squeak_entry_with_profile is None:
return None
diff --git a/squeakserver/db/squeak_db.py b/squeakserver/db/squeak_db.py
index b8f98cca..3a807bae 100644
--- a/squeakserver/db/squeak_db.py
+++ b/squeakserver/db/squeak_db.py
@@ -936,6 +936,24 @@ class SqueakDb:
# offers_with_peer = [self._parse_offer_with_peer(row) for row in rows]
# return offers_with_peer
+ def get_offer_with_peer(self, offer_id):
+ """ Get offer with peer for an offer id. """
+ s = (
+ select([self.offers, self.peers])
+ .select_from(
+ self.offers.outerjoin(
+ self.peers,
+ self.peers.c.id == self.offers.c.peer_id,
+ )
+ )
+ .where(self.offers.c.offer_id == offer_id)
+ )
+ with self.get_connection() as connection:
+ result = connection.execute(s)
+ row = result.fetchone()
+ offer_with_peer = self._parse_offer_with_peer(row)
+ return offer_with_peer
+
def delete_expired_offers(self):
""" Delete all expired offers. """
s = self.offers.delete().where(
diff --git a/squeakserver/node/squeak_node.py b/squeakserver/node/squeak_node.py
index bced1091..d3ad7fd4 100644
--- a/squeakserver/node/squeak_node.py
+++ b/squeakserver/node/squeak_node.py
@@ -253,3 +253,6 @@ class SqueakNode:
def get_buy_offers_with_peer(self, squeak_hash_str):
squeak_hash = bytes.fromhex(squeak_hash_str)
return self.postgres_db.get_offers_with_peer(squeak_hash_str)
+
+ def get_buy_offer_with_peer(self, offer_id):
+ return self.postgres_db.get_offer_with_peer(offer_id)