Show payment summary for peer (#2160)

* Add endpoint for payment summary for peer

* Got basic payment summary working for peer page

* Improve display of address in peer page

* Show peer address network in peer page

* Add endpoints for get sent payments for peer and get received payments for peer.

* Got sent payments for peer and received payments for peer working in frontend

* Update frontend build
This commit is contained in:
Jonathan Zernik 2022-04-14 20:18:52 -04:00 committed by GitHub
parent 80a484ef3b
commit 6d2eeb856f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 594 additions and 54 deletions

View file

@ -155,6 +155,12 @@ import {
GetSentPaymentsForPubkeyReply,
GetReceivedPaymentsForPubkeyRequest,
GetReceivedPaymentsForPubkeyReply,
GetPaymentSummaryForPeerRequest,
GetPaymentSummaryForPeerReply,
GetSentPaymentsForPeerRequest,
GetSentPaymentsForPeerReply,
GetReceivedPaymentsForPeerRequest,
GetReceivedPaymentsForPeerReply,
} from '../proto/squeak_admin_pb';
import axios from 'axios'
@ -391,6 +397,22 @@ export const getPaymentSummaryForPubkey = (pubkey) => {
});
}
export const getPaymentSummaryForPeer = (network, host, port) => {
console.log('Calling getPaymentSummaryForPeer');
const request = new GetPaymentSummaryForPeerRequest();
const peerAddress = new PeerAddress();
peerAddress.setNetwork(network);
peerAddress.setHost(host);
peerAddress.setPort(port);
request.setPeerAddress(peerAddress);
const deser = GetPaymentSummaryForPeerReply.deserializeBinary;
return baseRequest({
url: '/getpaymentsummaryforpeer',
req: request,
deser: deser,
});
}
export const getSentPayments = (limit, lastSentPayment) => {
console.log('Calling getSentPayments');
const request = new GetSentPaymentsRequest();
@ -438,6 +460,26 @@ export const getSentPaymentsForPubkey = (pubkey, limit, lastSentPayment) => {
});
}
export const getSentPaymentsForPeer = (network, host, port, limit, lastSentPayment) => {
console.log('Calling getSentPaymentsForPubkey');
const request = new GetSentPaymentsForPeerRequest();
const peerAddress = new PeerAddress();
peerAddress.setNetwork(network);
peerAddress.setHost(host);
peerAddress.setPort(port);
request.setPeerAddress(peerAddress);
request.setLimit(limit);
if (lastSentPayment) {
request.setLastSentPayment(lastSentPayment);
}
const deser = GetSentPaymentsForPeerReply.deserializeBinary;
return baseRequest({
url: '/getsentpaymentsforpeer',
req: request,
deser: deser,
});
}
export const getReceivedPayments = (limit, lastReceivedPayment) => {
console.log('Calling getReceivedPayments');
const request = new GetReceivedPaymentsRequest();
@ -485,6 +527,26 @@ export const getReceivedPaymentsForPubkey = (pubkey, limit, lastReceivedPayment)
});
}
export const getReceivedPaymentsForPeer = (network, host, port, limit, lastReceivedPayment) => {
console.log('Calling getReceivedPaymentsForPeer');
const request = new GetReceivedPaymentsForPeerRequest();
const peerAddress = new PeerAddress();
peerAddress.setNetwork(network);
peerAddress.setHost(host);
peerAddress.setPort(port);
request.setPeerAddress(peerAddress);
request.setLimit(limit);
if (lastReceivedPayment) {
request.setLastReceivedPayment(lastReceivedPayment);
}
const deser = GetReceivedPaymentsForPeerReply.deserializeBinary;
return baseRequest({
url: '/getreceivedpaymentsforpeer',
req: request,
deser: deser,
});
}
export const getSearchSqueaks = (searchText, limit, lastSqueak) => {
console.log('Calling getSearchSqueaks');
const request = new GetSearchSqueakDisplaysRequest();

View file

@ -23,6 +23,13 @@ import {
setPeerAutoconnectEnabled,
setPeerAutoconnectDisabled,
} from '../../features/peers/peersSlice'
import {
fetchPaymentSummaryForPeer,
selectPaymentSummaryForPeer,
} from '../../features/payments/paymentsSlice'
import SentPayments from '../../features/payments/SentPayments'
import ReceivedPayments from '../../features/payments/ReceivedPayments'
const Peer = (props) => {
@ -34,6 +41,7 @@ const Peer = (props) => {
const [editModalOpen, setEditModalOpen] = useState(false)
const [deleteModalOpen, setDeleteModalOpen] = useState(false)
const [savePeerModalOpen, setSavePeerModalOpen] = useState(false)
const [spendingModalOpen, setSpendingModalOpen] = useState(false)
const [banner, setBanner] = useState('')
const [saved, setSaved] = useState(false)
const [tab, setTab] = useState('Members')
@ -41,6 +49,7 @@ const Peer = (props) => {
const [styleBody, setStyleBody] = useState(false)
const peer = useSelector(selectCurrentPeer);
const paymentSummary = useSelector(selectPaymentSummaryForPeer)
const dispatch = useDispatch();
@ -51,6 +60,11 @@ const Peer = (props) => {
host: props.match.params.host,
port: props.match.params.port,
}));
dispatch(fetchPaymentSummaryForPeer({
network: props.match.params.network,
host: props.match.params.host,
port: props.match.params.port,
}));
}, [])
const isInitialMount = useRef(true);
@ -140,6 +154,13 @@ const Peer = (props) => {
setTimeout(()=>{ setSavePeerModalOpen(!savePeerModalOpen) },20)
}
const toggleSpendingModal = (param, type) => {
setStyleBody(!styleBody)
if(type){setTab(type)}
if(type){setTab(type)}
setTimeout(()=>{ setSpendingModalOpen(!spendingModalOpen) },20)
}
const handleModalClick = (e) => {
e.stopPropagation()
}
@ -177,40 +198,42 @@ const Peer = (props) => {
</Form>
);
const DeletePeerForm = () => (
<Form onSubmit={deletePeer} className="Squeak-input-side">
<div className="inner-input-links">
<div className="input-links-side">
</div>
<div className="squeak-btn-holder">
<div style={{ fontSize: '13px', color: null }}>
</div>
<button type="submit" className={'squeak-btn-side squeak-btn-active'}>
Delete
</button>
</div>
const DeletePeerForm = () => (
<Form onSubmit={deletePeer} className="Squeak-input-side">
<div className="inner-input-links">
<div className="input-links-side">
</div>
</Form>
);
<div className="squeak-btn-holder">
<div style={{ fontSize: '13px', color: null }}>
</div>
<button type="submit" className={'squeak-btn-side squeak-btn-active'}>
Delete
</button>
</div>
</div>
</Form>
);
const EditPeerForm = () => (
<Form onSubmit={editPeer} className="Squeak-input-side">
<div className="edit-input-wrap">
<Input class="informed-input" name="name" label="Peer Name" />
const EditPeerForm = () => (
<Form onSubmit={editPeer} className="Squeak-input-side">
<div className="edit-input-wrap">
<Input class="informed-input" name="name" label="Peer Name" />
</div>
<div className="inner-input-links">
<div className="input-links-side">
</div>
<div className="inner-input-links">
<div className="input-links-side">
</div>
<div className="squeak-btn-holder">
<div style={{ fontSize: '13px', color: null }}>
</div>
<button type="submit" className={'squeak-btn-side squeak-btn-active'}>
Submit
</button>
<div className="squeak-btn-holder">
<div style={{ fontSize: '13px', color: null }}>
</div>
<button type="submit" className={'squeak-btn-side squeak-btn-active'}>
Submit
</button>
</div>
</Form>
);
</div>
</Form>
);
console.log(paymentSummary);
return(
<div>
@ -268,9 +291,25 @@ const Peer = (props) => {
}
</div>
<div className="profile-details-box">
<div className="profile-name">{peer && peer.getPeerName()}</div>
<div className="profile-username">{props.match.params.host}:{props.match.params.port}</div>
<div className="profile-header-content">
<div className="profile-header-name">
<div className="profile-name">{peer && peer.getPeerName()}</div>
<div className="profile-username">Network: {props.match.params.network}</div>
<div className="profile-username">{props.match.params.host}:{props.match.params.port}</div>
</div>
</div>
<div className="profile-social-box">
{/* TODO: Implement sats spent */}
<div onClick={()=>toggleSpendingModal('members','Sent Payments')}>
<p className="follow-num"> {paymentSummary && paymentSummary.getAmountSpentMsat() / 1000} </p>
<p className="follow-text"> sats spent </p>
</div>
{/* TODO: Implement sats eaned */}
<div onClick={()=>toggleSpendingModal('members', 'Received Payments')}>
<p className="follow-num"> {paymentSummary && paymentSummary.getAmountEarnedMsat() / 1000} </p>
<p className="follow-text"> sats earned </p>
</div>
</div>
<div className="profile-options">
@ -286,14 +325,6 @@ const Peer = (props) => {
<div className="feed-wrapper">
<div className="feed-trending-card">
<div className="feed-card-trend">
<div>Number of downloads</div>
<div>TODO</div>
</div>
<div className="feed-card-trend">
<div>Number of purchases</div>
<div>TODO</div>
</div>
<div className="feed-card-trend">
<div>Last connection time</div>
<div>TODO</div>
@ -358,6 +389,49 @@ const Peer = (props) => {
</div>
{/* Modal for sats spent and earned */}
<div onClick={()=>toggleSpendingModal()} style={{display: spendingModalOpen ? 'block' : 'none'}} className="modal-edit">
<div onClick={(e)=>handleModalClick(e)} className="modal-content">
<div className="modal-header no-b-border">
<div className="modal-closeIcon">
<div onClick={()=>toggleSpendingModal()} className="modal-closeIcon-wrap">
<ICON_CLOSE />
</div>
</div>
<p className="modal-title">{null}</p>
</div>
<div className="modal-body">
<div className="explore-nav-menu">
<div onClick={()=>setTab('Sent Payments')} className={tab =='Sent Payments' ? `explore-nav-item activeTab` : `explore-nav-item`}>
Sent Payments
</div>
<div onClick={()=>setTab('Received Payments')} className={tab =='Received Payments' ? `explore-nav-item activeTab` : `explore-nav-item`}>
Received Payments
</div>
</div>
<div className="modal-scroll">
{tab === 'Sent Payments' ?
<>
<SentPayments network={props.match.params.network} host={props.match.params.host} port={props.match.params.port} />
</>
:
tab === 'Received Payments' ?
<>
<ReceivedPayments network={props.match.params.network} host={props.match.params.host} port={props.match.params.port} />
</>
: <div className="try-searching">
Nothing to see here ..
<div/>
Try searching for people, usernames, or keywords
</div>
}
</div>
</div>
</div>
</div>
</div>
)
}

View file

@ -30,6 +30,9 @@ const ReceivedPayments = (props) => {
dispatch(fetchReceivedPayments({
squeakHash: props.squeakHash,
pubkey: props.pubkey,
network: props.network,
host: props.host,
port: props.port,
limit: 10,
lastReceivedPayment: null,
}));
@ -39,6 +42,9 @@ const ReceivedPayments = (props) => {
dispatch(fetchReceivedPayments({
squeakHash: props.squeakHash,
pubkey: props.pubkey,
network: props.network,
host: props.host,
port: props.port,
limit: 10,
lastReceivedPayment: lastReceivedPayment,
}));

View file

@ -30,6 +30,9 @@ const SentPayments = (props) => {
dispatch(fetchSentPayments({
squeakHash: props.squeakHash,
pubkey: props.pubkey,
network: props.network,
host: props.host,
port: props.port,
limit: 10,
lastSentPayment: null,
}));
@ -39,6 +42,9 @@ const SentPayments = (props) => {
dispatch(fetchSentPayments({
squeakHash: props.squeakHash,
pubkey: props.pubkey,
network: props.network,
host: props.host,
port: props.port,
limit: 10,
lastSentPayment: lastSentPayment,
}));

View file

@ -8,12 +8,15 @@ import {
getSentPayments,
getSentPaymentsForSqueak,
getSentPaymentsForPubkey,
getSentPaymentsForPeer,
getReceivedPayments,
getReceivedPaymentsForSqueak,
getReceivedPaymentsForPubkey,
getReceivedPaymentsForPeer,
getPaymentSummary,
getPaymentSummaryForSqueak,
getPaymentSummaryForPubkey,
getReceivedPaymentsForPubkey,
getPaymentSummaryForPeer,
} from '../../api/client'
const initialState = {
@ -24,6 +27,7 @@ const initialState = {
paymentSummary: null,
paymentSummaryForSqueak: null,
paymentSummaryForPubkey: null,
paymentSummaryForPeer: null,
}
// Thunk functions
@ -40,6 +44,13 @@ export const fetchSentPayments = createAsyncThunk(
values.limit,
values.lastSentPayment,
)
: (values.network && values.host && values.port) ? await getSentPaymentsForPeer(
values.network,
values.host,
values.port,
values.limit,
values.lastSentPayment,
)
: await getSentPayments(
values.limit,
values.lastSentPayment,
@ -61,6 +72,13 @@ export const fetchReceivedPayments = createAsyncThunk(
values.limit,
values.lastReceivedPayment,
)
: (values.network && values.host && values.port) ? await getReceivedPaymentsForPeer(
values.network,
values.host,
values.port,
values.limit,
values.lastReceivedPayment,
)
: await getReceivedPayments(
values.limit,
values.lastReceivedPayment,
@ -96,6 +114,15 @@ export const fetchPaymentSummaryForPubkey = createAsyncThunk(
}
)
export const fetchPaymentSummaryForPeer = createAsyncThunk(
'payments/fetchPaymentSummaryForPeer',
async (values) => {
console.log('Fetching paymentSummary for peer:', values.network, values.host, values.port);
const response = await getPaymentSummaryForPeer(values.network, values.host, values.port);
return response.getPaymentSummary();
}
)
const paymentsSlice = createSlice({
name: 'sentPayments',
@ -140,6 +167,10 @@ const paymentsSlice = createSlice({
const paymentSummaryForPubkey = action.payload;
state.paymentSummaryForPubkey = paymentSummaryForPubkey;
})
.addCase(fetchPaymentSummaryForPeer.fulfilled, (state, action) => {
const paymentSummaryForPeer = action.payload;
state.paymentSummaryForPeer = paymentSummaryForPeer;
})
},
})
@ -173,3 +204,5 @@ export const selectPaymentSummary = state => state.payments.paymentSummary
export const selectPaymentSummaryForSqueak = state => state.payments.paymentSummaryForSqueak
export const selectPaymentSummaryForPubkey = state => state.payments.paymentSummaryForPubkey
export const selectPaymentSummaryForPeer = state => state.payments.paymentSummaryForPeer

View file

@ -236,6 +236,10 @@ service SqueakAdmin {
*/
rpc GetSentPaymentsForPubkey (GetSentPaymentsForPubkeyRequest) returns (GetSentPaymentsForPubkeyReply) {}
/** sqkadmin: `getsentpaymentsforpeer`
*/
rpc GetSentPaymentsForPeer (GetSentPaymentsForPeerRequest) returns (GetSentPaymentsForPeerReply) {}
/** sqkadmin: `getsentpayment`
*/
rpc GetSentPayment (GetSentPaymentRequest) returns (GetSentPaymentReply) {}
@ -256,6 +260,10 @@ service SqueakAdmin {
*/
rpc GetReceivedPaymentsForPubkey (GetReceivedPaymentsForPubkeyRequest) returns (GetReceivedPaymentsForPubkeyReply) {}
/** sqkadmin: `getreceivedpaymentsforpeer`
*/
rpc GetReceivedPaymentsForPeer (GetReceivedPaymentsForPeerRequest) returns (GetReceivedPaymentsForPeerReply) {}
/** sqkadmin: `subscribereceivedpayments`
*/
rpc SubscribeReceivedPayments (SubscribeReceivedPaymentsRequest) returns (stream ReceivedPayment) {}
@ -276,6 +284,10 @@ service SqueakAdmin {
*/
rpc GetPaymentSummaryForPubkey (GetPaymentSummaryForPubkeyRequest) returns (GetPaymentSummaryForPubkeyReply) {}
/** sqkadmin: `getpaymentsummaryforpeer`
*/
rpc GetPaymentSummaryForPeer (GetPaymentSummaryForPeerRequest) returns (GetPaymentSummaryForPeerReply) {}
/** sqkadmin: `reprocessreceivedpayments`
*/
rpc ReprocessReceivedPayments (ReprocessReceivedPaymentsRequest) returns (ReprocessReceivedPaymentsReply) {}
@ -998,6 +1010,22 @@ message GetSentPaymentsForPubkeyReply {
repeated SentPayment sent_payments = 1;
}
message GetSentPaymentsForPeerRequest {
/// Peer address
PeerAddress peer_address = 1;
/// Limit number of results
int32 limit = 2;
/// Last entry
SentPayment last_sent_payment = 3;
}
message GetSentPaymentsForPeerReply {
/// The sent payments
repeated SentPayment sent_payments = 1;
}
message GetSentPaymentRequest {
/// Sent payment id
int32 sent_payment_id = 1;
@ -1144,6 +1172,22 @@ message GetReceivedPaymentsForPubkeyReply {
repeated ReceivedPayment received_payments = 1;
}
message GetReceivedPaymentsForPeerRequest {
/// Peer address
PeerAddress peer_address = 1;
/// Limit number of results
int32 limit = 2;
/// Last entry
ReceivedPayment last_received_payment = 3;
}
message GetReceivedPaymentsForPeerReply {
/// The received payments
repeated ReceivedPayment received_payments = 1;
}
message ReceivedPayment {
/// The received payment id
int32 received_payment_id = 1;
@ -1205,6 +1249,16 @@ message GetPaymentSummaryForPubkeyReply {
PaymentSummary payment_summary = 1;
}
message GetPaymentSummaryForPeerRequest {
/// Peer address
PeerAddress peer_address = 1;
}
message GetPaymentSummaryForPeerReply {
// Payment summary of the node
PaymentSummary payment_summary = 1;
}
message PaymentSummary {
// Number of received payments
int32 num_received_payments = 1;

View file

@ -804,6 +804,38 @@ class SqueakAdminServerHandler(object):
sent_payments=sent_payment_msgs,
)
def handle_get_sent_payments_for_peer(self, request):
peer_address = message_to_peer_address(request.peer_address)
limit = request.limit
last_sent_payment = message_to_sent_payment(request.last_sent_payment) if request.HasField(
"last_sent_payment") else None
logger.info("""Handle get sent payments with
peer_address: {}
limit: {}
last_sent_payment: {}
""".format(
peer_address,
limit,
last_sent_payment,
))
sent_payments = self.squeak_controller.get_sent_payments_for_peer(
peer_address,
limit,
last_sent_payment,
)
logger.info(
"Got number of sent payments: {}".format(
len(sent_payments)
)
)
sent_payment_msgs = [
sent_payment_to_message(sent_payment)
for sent_payment in sent_payments
]
return squeak_admin_pb2.GetSentPaymentsReply(
sent_payments=sent_payment_msgs,
)
def handle_get_sent_payment(self, request):
sent_payment_id = request.sent_payment_id
logger.info(
@ -918,6 +950,38 @@ class SqueakAdminServerHandler(object):
received_payments=received_payment_msgs,
)
def handle_get_received_payments_for_peer(self, request):
peer_address = message_to_peer_address(request.peer_address)
limit = request.limit
last_received_payment = message_to_received_payment(request.last_received_payment) if request.HasField(
"last_received_payment") else None
logger.info("""Handle get received payments with
peer_address: {}
limit: {}
last_received_payment: {}
""".format(
peer_address,
limit,
last_received_payment,
))
received_payments = self.squeak_controller.get_received_payments_for_peer(
peer_address,
limit,
last_received_payment,
)
logger.info(
"Got number of received payments: {}".format(
len(received_payments)
)
)
received_payment_msgs = [
received_payment_to_message(received_payment)
for received_payment in received_payments
]
return squeak_admin_pb2.GetReceivedPaymentsReply(
received_payments=received_payment_msgs,
)
def handle_subscribe_received_payments(self, request, stopped):
payment_index = request.payment_index
logger.info(
@ -980,6 +1044,20 @@ class SqueakAdminServerHandler(object):
payment_summary=payment_summary_msg,
)
def handle_get_payment_summary_for_peer(self, request):
peer_address = message_to_peer_address(request.peer_address)
logger.info("Handle get payment summary for peer address: {}".format(
peer_address,
))
payment_summary = self.squeak_controller.get_payment_summary_for_peer(
peer_address)
payment_summary_msg = payment_summary_to_message(
payment_summary,
)
return squeak_admin_pb2.GetPaymentSummaryForPubkeyReply(
payment_summary=payment_summary_msg,
)
def handle_reprocess_received_payments(self, request):
logger.info("Handle reprocess received payments")
self.squeak_controller.reprocess_received_payments()

View file

@ -221,6 +221,9 @@ class SqueakAdminServerServicer(squeak_admin_pb2_grpc.SqueakAdminServicer):
def GetSentPaymentsForPubkey(self, request, context):
return self.handler.handle_get_sent_payments_for_pubkey(request)
def GetSentPaymentsForPeer(self, request, context):
return self.handler.handle_get_sent_payments_for_peer(request)
def GetSentPayment(self, request, context):
return self.handler.handle_get_sent_payment(request)
@ -236,6 +239,9 @@ class SqueakAdminServerServicer(squeak_admin_pb2_grpc.SqueakAdminServicer):
def GetReceivedPaymentsForPubkey(self, request, context):
return self.handler.handle_get_received_payments_for_pubkey(request)
def GetReceivedPaymentsForPeer(self, request, context):
return self.handler.handle_get_received_payments_for_peer(request)
def SubscribeReceivedPayments(self, request, context):
stopped = threading.Event()
@ -257,6 +263,12 @@ class SqueakAdminServerServicer(squeak_admin_pb2_grpc.SqueakAdminServicer):
def GetPaymentSummaryForSqueak(self, request, context):
return self.handler.handle_get_payment_summary_for_squeak(request)
def GetPaymentSummaryForPubkey(self, request, context):
return self.handler.handle_get_payment_summary_for_pubkey(request)
def GetPaymentSummaryForPeer(self, request, context):
return self.handler.handle_get_payment_summary_for_peer(request)
def ReprocessReceivedPayments(self, request, context):
return self.handler.handle_reprocess_received_payments(request)

View file

@ -433,6 +433,12 @@ def create_app(handler, username, password):
def getsentpaymentsforpubkey(msg):
return handler.handle_get_sent_payments_for_pubkey(msg)
@app.route("/getsentpaymentsforpeer", methods=["POST"])
@login_required
@protobuf_serialized(squeak_admin_pb2.GetSentPaymentsForPeerRequest())
def getsentpaymentsforpeer(msg):
return handler.handle_get_sent_payments_for_peer(msg)
@app.route("/getsentoffers", methods=["POST"])
@login_required
@protobuf_serialized(squeak_admin_pb2.GetSentOffersRequest())
@ -457,6 +463,12 @@ def create_app(handler, username, password):
def getreceivedpaymentsforpubkey(msg):
return handler.handle_get_received_payments_for_pubkey(msg)
@app.route("/getreceivedpaymentsforpeer", methods=["POST"])
@login_required
@protobuf_serialized(squeak_admin_pb2.GetReceivedPaymentsForPeerRequest())
def getreceivedpaymentsforpeer(msg):
return handler.handle_get_received_payments_for_peer(msg)
@app.route("/getnetwork", methods=["POST"])
@login_required
@protobuf_serialized(squeak_admin_pb2.GetNetworkRequest())
@ -487,6 +499,12 @@ def create_app(handler, username, password):
def getpaymentsummaryforpubkey(msg):
return handler.handle_get_payment_summary_for_pubkey(msg)
@app.route("/getpaymentsummaryforpeer", methods=["POST"])
@login_required
@protobuf_serialized(squeak_admin_pb2.GetPaymentSummaryForPeerRequest())
def getpaymentsummaryforpeer(msg):
return handler.handle_get_payment_summary_for_peer(msg)
@app.route("/reprocessreceivedpayments", methods=["POST"])
@login_required
@protobuf_serialized(squeak_admin_pb2.ReprocessReceivedPaymentsRequest())

View file

@ -1,26 +1,26 @@
{
"files": {
"main.css": "/static/css/main.206389cd.css",
"main.js": "/static/js/main.0e504b96.js",
"main.js": "/static/js/main.26267c8e.js",
"static/css/306.7f7715a0.chunk.css": "/static/css/306.7f7715a0.chunk.css",
"static/js/306.90b2a66c.chunk.js": "/static/js/306.90b2a66c.chunk.js",
"static/css/900.b66ac5fb.chunk.css": "/static/css/900.b66ac5fb.chunk.css",
"static/js/900.1b104345.chunk.js": "/static/js/900.1b104345.chunk.js",
"static/css/841.693c3c31.chunk.css": "/static/css/841.693c3c31.chunk.css",
"static/js/841.8faa8984.chunk.js": "/static/js/841.8faa8984.chunk.js",
"static/js/841.9f23f674.chunk.js": "/static/js/841.9f23f674.chunk.js",
"static/media/icon.svg": "/static/media/icon.982210ec9275956e4d3cc77fa90167fd.svg",
"index.html": "/index.html",
"main.206389cd.css.map": "/static/css/main.206389cd.css.map",
"main.0e504b96.js.map": "/static/js/main.0e504b96.js.map",
"main.26267c8e.js.map": "/static/js/main.26267c8e.js.map",
"306.7f7715a0.chunk.css.map": "/static/css/306.7f7715a0.chunk.css.map",
"306.90b2a66c.chunk.js.map": "/static/js/306.90b2a66c.chunk.js.map",
"900.b66ac5fb.chunk.css.map": "/static/css/900.b66ac5fb.chunk.css.map",
"900.1b104345.chunk.js.map": "/static/js/900.1b104345.chunk.js.map",
"841.693c3c31.chunk.css.map": "/static/css/841.693c3c31.chunk.css.map",
"841.8faa8984.chunk.js.map": "/static/js/841.8faa8984.chunk.js.map"
"841.9f23f674.chunk.js.map": "/static/js/841.9f23f674.chunk.js.map"
},
"entrypoints": [
"static/css/main.206389cd.css",
"static/js/main.0e504b96.js"
"static/js/main.26267c8e.js"
]
}

View file

@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#1da1f2"/><meta nam="description" content="Squeaknode!"/><meta name="og:title" content="Squeaknode"/><meta name="og:description" content="check out my the Squeaknode I made"/><link href="https://fonts.googleapis.com/css2?family=Assistant&display=swap" rel="stylesheet"><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>Squeaknode</title><script defer="defer" src="/static/js/main.0e504b96.js"></script><link href="/static/css/main.206389cd.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#1da1f2"/><meta nam="description" content="Squeaknode!"/><meta name="og:title" content="Squeaknode"/><meta name="og:description" content="check out my the Squeaknode I made"/><link href="https://fonts.googleapis.com/css2?family=Assistant&display=swap" rel="stylesheet"><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>Squeaknode</title><script defer="defer" src="/static/js/main.26267c8e.js"></script><link href="/static/css/main.206389cd.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1411,6 +1411,53 @@ class SqueakDb:
self._parse_sent_payment(row) for row in rows]
return sent_payments
def get_sent_payments_for_peer(
self,
peer_address: PeerAddress,
limit: int,
last_sent_payment: Optional[SentPayment],
) -> List[SentPayment]:
""" Get sent payments for a peer. """
last_created_time = last_sent_payment.created_time_ms if last_sent_payment else self.timestamp_now_ms
last_payment_hash = last_sent_payment.payment_hash if last_sent_payment else MAX_HASH
logger.info("""Get sent payments db query with
peer_address: {}
limit: {}
last_created_time: {}
last_payment_hash: {}
""".format(
peer_address,
limit,
last_created_time,
last_payment_hash.hex(),
))
s = (
select([self.sent_payments])
.where(self.received_payments.c.peer_network == peer_address.network.name)
.where(self.received_payments.c.peer_host == peer_address.host)
.where(self.received_payments.c.peer_port == peer_address.port)
.where(
tuple_(
self.sent_payments.c.created_time_ms,
self.sent_payments.c.payment_hash,
) < tuple_(
last_created_time,
last_payment_hash,
)
)
.order_by(
self.sent_payments.c.created_time_ms.desc(),
self.sent_payments.c.payment_hash.desc(),
)
.limit(limit)
)
with self.get_connection() as connection:
result = connection.execute(s)
rows = result.fetchall()
sent_payments = [
self._parse_sent_payment(row) for row in rows]
return sent_payments
def get_sent_payment(self, sent_payment_id: int) -> Optional[SentPayment]:
""" Get sent payment by id. """
s = (
@ -1673,6 +1720,53 @@ class SqueakDb:
self._parse_received_payment(row) for row in rows]
return received_payments
def get_received_payments_for_peer(
self,
peer_address: PeerAddress,
limit: int,
last_received_payment: Optional[ReceivedPayment],
) -> List[ReceivedPayment]:
""" Get received payments for a squeak. """
last_created_time = last_received_payment.created_time_ms if last_received_payment else self.timestamp_now_ms
last_payment_hash = last_received_payment.payment_hash if last_received_payment else MAX_HASH
logger.info("""Get received payments db query with
peer_address: {}
limit: {}
last_created_time: {}
last_payment_hash: {}
""".format(
peer_address,
limit,
last_created_time,
last_payment_hash.hex(),
))
s = (
select([self.received_payments])
.where(self.received_payments.c.peer_network == peer_address.network.name)
.where(self.received_payments.c.peer_host == peer_address.host)
.where(self.received_payments.c.peer_port == peer_address.port)
.where(
tuple_(
self.received_payments.c.created_time_ms,
self.received_payments.c.payment_hash,
) < tuple_(
last_created_time,
last_payment_hash,
)
)
.order_by(
self.received_payments.c.created_time_ms.desc(),
self.received_payments.c.payment_hash.desc(),
)
.limit(limit)
)
with self.get_connection() as connection:
result = connection.execute(s)
rows = result.fetchall()
received_payments = [
self._parse_received_payment(row) for row in rows]
return received_payments
def get_latest_settle_index(self) -> Optional[int]:
""" Get the lnd settled index of the most recent received payment. """
s = select(
@ -1816,6 +1910,45 @@ class SqueakDb:
sent_payment_summary = self._parse_sent_payment_summary(row)
return sent_payment_summary
def get_received_payment_summary_for_peer(self, peer_address: PeerAddress) -> ReceivedPaymentSummary:
""" Get received payment summary for a single peer. """
s = (
select([
func.count().label("num_payments_received"),
func.sum(self.received_payments.c.price_msat).label(
"total_amount_received_msat"),
])
.select_from(self.received_payments)
.where(self.received_payments.c.peer_network == peer_address.network.name)
.where(self.received_payments.c.peer_host == peer_address.host)
.where(self.received_payments.c.peer_port == peer_address.port)
)
with self.get_connection() as connection:
result = connection.execute(s)
row = result.fetchone()
received_payment_summary = self._parse_received_payment_summary(
row)
return received_payment_summary
def get_sent_payment_summary_for_peer(self, peer_address: PeerAddress) -> SentPaymentSummary:
""" Get sent payment summary for a peer. """
s = (
select([
func.count().label("num_payments_sent"),
func.sum(self.sent_payments.c.price_msat).label(
"total_amount_sent_msat"),
])
.select_from(self.sent_payments)
.where(self.received_payments.c.peer_network == peer_address.network.name)
.where(self.received_payments.c.peer_host == peer_address.host)
.where(self.received_payments.c.peer_port == peer_address.port)
)
with self.get_connection() as connection:
result = connection.execute(s)
row = result.fetchone()
sent_payment_summary = self._parse_sent_payment_summary(row)
return sent_payment_summary
def insert_config(self, user_config: UserConfig) -> Optional[str]:
""" Insert a new config.

View file

@ -241,6 +241,18 @@ class SqueakController:
last_sent_payment,
)
def get_sent_payments_for_peer(
self,
peer_address: PeerAddress,
limit: int,
last_sent_payment: Optional[SentPayment],
) -> List[SentPayment]:
return self.squeak_store.get_sent_payments_for_peer(
peer_address,
limit,
last_sent_payment,
)
def get_sent_payment(self, sent_payment_id: int) -> Optional[SentPayment]:
return self.squeak_store.get_sent_payment(sent_payment_id)
@ -281,6 +293,18 @@ class SqueakController:
last_received_payment,
)
def get_received_payments_for_peer(
self,
peer_address: PeerAddress,
limit: int,
last_received_payment: Optional[ReceivedPayment],
) -> List[ReceivedPayment]:
return self.squeak_store.get_received_payments_for_peer(
peer_address,
limit,
last_received_payment,
)
def delete_all_expired_offers(self):
self.squeak_store.delete_all_expired_offers()
@ -397,6 +421,16 @@ class SqueakController:
received_payment_summary=received_payment_summary,
)
def get_payment_summary_for_peer(self, peer_address: PeerAddress) -> PaymentSummary:
received_payment_summary = self.squeak_store.get_received_payment_summary_for_peer(
peer_address)
sent_payment_summary = self.squeak_store.get_sent_payment_summary_for_peer(
peer_address)
return PaymentSummary(
sent_payment_summary=sent_payment_summary,
received_payment_summary=received_payment_summary,
)
# def get_received_payment_summary(self) -> ReceivedPaymentSummary:
# return self.squeak_store.get_received_payment_summary()

View file

@ -430,6 +430,18 @@ class SqueakStore:
last_sent_payment,
)
def get_sent_payments_for_peer(
self,
peer_address: PeerAddress,
limit: int,
last_sent_payment: Optional[SentPayment],
) -> List[SentPayment]:
return self.squeak_db.get_sent_payments_for_peer(
peer_address,
limit,
last_sent_payment,
)
def get_sent_payment(self, sent_payment_id: int) -> Optional[SentPayment]:
return self.squeak_db.get_sent_payment(sent_payment_id)
@ -473,6 +485,18 @@ class SqueakStore:
last_received_payment,
)
def get_received_payments_for_peer(
self,
peer_address: PeerAddress,
limit: int,
last_received_payment: Optional[ReceivedPayment],
) -> List[ReceivedPayment]:
return self.squeak_db.get_received_payments_for_peer(
peer_address,
limit,
last_received_payment,
)
def delete_all_expired_offers(self):
self.delete_all_expired_received_offers()
self.delete_all_expired_sent_offers()
@ -591,6 +615,9 @@ class SqueakStore:
def get_received_payment_summary_for_pubkey(self, pubkey: SqueakPublicKey) -> ReceivedPaymentSummary:
return self.squeak_db.get_received_payment_summary_for_pubkey(pubkey)
def get_received_payment_summary_for_peer(self, peer_address: PeerAddress) -> ReceivedPaymentSummary:
return self.squeak_db.get_received_payment_summary_for_peer(peer_address)
def get_sent_payment_summary(self) -> SentPaymentSummary:
return self.squeak_db.get_sent_payment_summary()
@ -600,6 +627,9 @@ class SqueakStore:
def get_sent_payment_summary_for_pubkey(self, pubkey: SqueakPublicKey) -> SentPaymentSummary:
return self.squeak_db.get_sent_payment_summary_for_pubkey(pubkey)
def get_sent_payment_summary_for_peer(self, peer_address: PeerAddress) -> SentPaymentSummary:
return self.squeak_db.get_sent_payment_summary_for_peer(peer_address)
def clear_received_payment_settle_indices(self) -> None:
self.squeak_db.clear_received_payment_settle_indices()