From 634c209f6b24f2e5560b1da9ea8bd2c463605d28 Mon Sep 17 00:00:00 2001
From: joshemb <josh@elixxir.io>
Date: Wed, 7 Sep 2022 12:19:59 -0700
Subject: [PATCH] Add field RoundUrl to all send reporters in bindings

---
 bindings/broadcast.go  | 20 ++++++++++++++------
 bindings/connect.go    |  1 +
 bindings/delivery.go   | 14 +++++++++++++-
 bindings/e2eHandler.go | 17 ++++++++++-------
 bindings/group.go      | 23 ++++++++++++++++++++++-
 bindings/json_test.go  | 40 ----------------------------------------
 bindings/single.go     | 29 +++++++++++++++++++----------
 bindings/ud.go         |  2 ++
 8 files changed, 81 insertions(+), 65 deletions(-)
 delete mode 100644 bindings/json_test.go

diff --git a/bindings/broadcast.go b/bindings/broadcast.go
index 857f6bd98..8d5255fa0 100644
--- a/bindings/broadcast.go
+++ b/bindings/broadcast.go
@@ -44,9 +44,11 @@ type ChannelDef struct {
 
 // BroadcastMessage is the bindings representation of a broadcast message.
 //
-// Example JSON:
-//  {"RoundID":42,
+// BroadcastMessage Example JSON:
+//  {
+// 	 "RoundID":42,
 //   "EphID":[0,0,0,0,0,0,24,61],
+//   "RoundURL":"https://dashboard.xx.network/rounds/25?xxmessenger=true",
 //   "Payload":"SGVsbG8sIGJyb2FkY2FzdCBmcmllbmRzIQ=="
 //  }
 type BroadcastMessage struct {
@@ -57,13 +59,16 @@ type BroadcastMessage struct {
 // BroadcastReport is the bindings representation of the info on how a broadcast
 // message was sent
 //
-// Example JSON:
-//  {"RoundID":42,
-//   "EphID":[0,0,0,0,0,0,24,61]
+// BroadcastReport Example JSON:
+//  {
+//	 "Rounds": [25, 26, 29],
+//   "EphID":[0,0,0,0,0,0,24,61],
+//   "RoundURL":"https://dashboard.xx.network/rounds/25?xxmessenger=true"
 //  }
 type BroadcastReport struct {
 	RoundsList
-	EphID ephemeral.Id
+	RoundURL string
+	EphID    ephemeral.Id
 }
 
 // BroadcastListener is the public function type bindings can use to listen for
@@ -131,6 +136,7 @@ func (c *Channel) Listen(l BroadcastListener, method int) error {
 		l.Callback(json.Marshal(&BroadcastMessage{
 			BroadcastReport: BroadcastReport{
 				RoundsList: makeRoundsList(round.ID),
+				RoundURL:   getRoundURL(round.ID),
 				EphID:      receptionID.EphId,
 			},
 			Payload: payload,
@@ -153,6 +159,7 @@ func (c *Channel) Broadcast(payload []byte) ([]byte, error) {
 	}
 	return json.Marshal(BroadcastReport{
 		RoundsList: makeRoundsList(rid),
+		RoundURL:   getRoundURL(rid),
 		EphID:      eid,
 	})
 }
@@ -174,6 +181,7 @@ func (c *Channel) BroadcastAsymmetric(payload, pk []byte) ([]byte, error) {
 	}
 	return json.Marshal(BroadcastReport{
 		RoundsList: makeRoundsList(rid),
+		RoundURL:   getRoundURL(rid),
 		EphID:      eid,
 	})
 }
diff --git a/bindings/connect.go b/bindings/connect.go
index faaffc195..df3d4ae46 100644
--- a/bindings/connect.go
+++ b/bindings/connect.go
@@ -94,6 +94,7 @@ func (c *Connection) SendE2E(mt int, payload []byte) ([]byte, error) {
 
 	sr := E2ESendReport{
 		RoundsList: makeRoundsList(sendReport.RoundList...),
+		RoundURL:   getRoundURL(sendReport.RoundList[0]),
 		MessageID:  sendReport.MessageId.Marshal(),
 		Timestamp:  sendReport.SentTime.UnixNano(),
 		KeyResidue: sendReport.KeyResidue.Marshal(),
diff --git a/bindings/delivery.go b/bindings/delivery.go
index 89521d887..2cdb16b94 100644
--- a/bindings/delivery.go
+++ b/bindings/delivery.go
@@ -9,6 +9,7 @@ package bindings
 
 import (
 	"encoding/json"
+	"fmt"
 	"time"
 
 	"github.com/pkg/errors"
@@ -17,9 +18,20 @@ import (
 	"gitlab.com/xx_network/primitives/id"
 )
 
+// dashboardBaseURL is the base of the xx network's round dashboard URL.
+// This should be used by any type of send report's GetRoundURL method.
+const dashboardBaseURL = "https://dashboard.xx.network"
+
+// getRoundURL is a helper function which returns the specific round
+// within any type of send report, if they have a round in their RoundsList.
+// This helper function is messenger specific.
+func getRoundURL(round id.Round) string {
+	return fmt.Sprintf("%s/rounds/%d?xxmessenger=true", dashboardBaseURL, round)
+}
+
 // RoundsList contains a list of round IDs.
 //
-// Example marshalled roundList object:
+// JSON Example:
 //  [1001,1003,1006]
 type RoundsList struct {
 	Rounds []uint64
diff --git a/bindings/e2eHandler.go b/bindings/e2eHandler.go
index 8f53305e3..5ed379257 100644
--- a/bindings/e2eHandler.go
+++ b/bindings/e2eHandler.go
@@ -23,15 +23,17 @@ import (
 // E2ESendReport is the bindings' representation of the return values of
 // SendE2E.
 //
-// Example E2ESendReport:
-//{
-//"Rounds": [ 1, 4, 9],
-//"MessageID": "iM34yCIr4Je8ZIzL9iAAG1UWAeDiHybxMTioMAaezvs=",
-//"Timestamp": 1661532254302612000,
-//"KeyResidue": "9q2/A69EAuFM1hFAT7Bzy5uGOQ4T6bPFF72h5PlgCWE="
-//}
+// E2ESendReport Example JSON:
+//  {
+//		"Rounds": [ 1, 4, 9],
+//      "RoundURL":"https://dashboard.xx.network/rounds/25?xxmessenger=true",
+//		"MessageID": "iM34yCIr4Je8ZIzL9iAAG1UWAeDiHybxMTioMAaezvs=",
+//		"Timestamp": 1661532254302612000,
+//		"KeyResidue": "9q2/A69EAuFM1hFAT7Bzy5uGOQ4T6bPFF72h5PlgCWE="
+//  }
 type E2ESendReport struct {
 	RoundsList
+	RoundURL   string
 	MessageID  []byte
 	Timestamp  int64
 	KeyResidue []byte
@@ -147,6 +149,7 @@ func (e *E2e) SendE2E(messageType int, recipientId, payload,
 
 	result := E2ESendReport{
 		RoundsList: makeRoundsList(sendReport.RoundList...),
+		RoundURL:   getRoundURL(sendReport.RoundList[0]),
 		MessageID:  sendReport.MessageId.Marshal(),
 		Timestamp:  sendReport.SentTime.UnixNano(),
 		KeyResidue: sendReport.KeyResidue.Marshal(),
diff --git a/bindings/group.go b/bindings/group.go
index 8e0ddad21..74192f3f7 100644
--- a/bindings/group.go
+++ b/bindings/group.go
@@ -157,6 +157,7 @@ func (g *GroupChat) MakeGroup(
 	report := GroupReport{
 		Id:         grp.ID.Bytes(),
 		RoundsList: makeRoundsList(roundIDs...),
+		RoundURL:   getRoundURL(roundIDs[0]),
 		Status:     int(status),
 	}
 
@@ -199,6 +200,7 @@ func (g *GroupChat) ResendRequest(groupId []byte) ([]byte, error) {
 	report := &GroupReport{
 		Id:         grp.ID.Bytes(),
 		RoundsList: makeRoundsList(rnds...),
+		RoundURL:   getRoundURL(rnds[0]),
 		Status:     int(status),
 	}
 
@@ -270,6 +272,7 @@ func (g *GroupChat) Send(groupId, message []byte, tag string) ([]byte, error) {
 	// Construct send report
 	sendReport := &GroupSendReport{
 		RoundsList: makeRoundsList(round),
+		RoundURL:   getRoundURL(round),
 		Timestamp:  timestamp.UnixNano(),
 		MessageID:  msgID.Bytes(),
 	}
@@ -451,16 +454,34 @@ func (gcp *groupChatProcessor) String() string {
 // GroupReport is returned when creating a new group and contains the ID of
 // the group, a list of rounds that the group requests were sent on, and the
 // status of the send operation.
+//
+// Example GroupReport JSON:
+//		{
+//			"Id": "AAAAAAAAAM0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE",
+//			"Rounds": [25, 64],
+//			"RoundURL": "https://dashboard.xx.network/rounds/25?xxmessenger=true",
+//			"Status": 1
+//		}
 type GroupReport struct {
 	Id []byte
 	RoundsList
-	Status int
+	RoundURL string
+	Status   int
 }
 
 // GroupSendReport is returned when sending a group message. It contains the
 // round ID sent on and the timestamp of the send operation.
+//
+// Example GroupSendReport JSON:
+//      {
+//  	"Rounds": [25,	64],
+//  	"RoundURL": "https://dashboard.xx.network/rounds/25?xxmessenger=true",
+//  	"Timestamp": 1662577352813112000,
+//  	"MessageID": "69ug6FA50UT2q6MWH3hne9PkHQ+H9DnEDsBhc0m0Aww="
+//	    }
 type GroupSendReport struct {
 	RoundsList
+	RoundURL  string
 	Timestamp int64
 	MessageID []byte
 }
diff --git a/bindings/json_test.go b/bindings/json_test.go
deleted file mode 100644
index 4dd6eeadc..000000000
--- a/bindings/json_test.go
+++ /dev/null
@@ -1,40 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// Copyright © 2022 xx foundation                                             //
-//                                                                            //
-// Use of this source code is governed by a license that can be found in the  //
-// LICENSE file.                                                              //
-////////////////////////////////////////////////////////////////////////////////
-
-package bindings
-
-import (
-	"encoding/json"
-	"gitlab.com/elixxir/crypto/e2e"
-	"math/rand"
-	"testing"
-	"time"
-)
-
-func TestName(t *testing.T) {
-	rl := []uint64{1, 4, 9}
-	prng := rand.New(rand.NewSource(42))
-	rfp := make([]byte, 32)
-	prng.Read(rfp)
-	mid := e2e.NewMessageID(rfp, prng.Uint64())
-
-	randData := make([]byte, 32)
-	prng.Read(randData)
-	k := e2e.Key{}
-	copy(k[:], randData)
-	kr := e2e.NewKeyResidue(k)
-
-	report := E2ESendReport{
-		RoundsList: RoundsList{rl},
-		MessageID:  mid.Marshal(),
-		Timestamp:  time.Now().UnixNano(),
-		KeyResidue: kr.Marshal(),
-	}
-
-	marshal, _ := json.Marshal(report)
-	t.Logf("%s", marshal)
-}
diff --git a/bindings/single.go b/bindings/single.go
index 71c442014..d6625cd71 100644
--- a/bindings/single.go
+++ b/bindings/single.go
@@ -64,6 +64,7 @@ func TransmitSingleUse(e2eID int, recipient []byte, tag string, payload,
 		EphID:       eid.EphId.Int64(),
 		ReceptionID: eid.Source,
 		RoundsList:  makeRoundsList(rids...),
+		RoundURL:    getRoundURL(rids[0]),
 	}
 	return json.Marshal(sr)
 }
@@ -99,14 +100,16 @@ func Listen(e2eID int, tag string, cb SingleUseCallback) (Stopper, error) {
 // SingleUseSendReport is the bindings-layer struct used to represent
 // information returned by single.TransmitRequest.
 //
-// JSON example:
+// SingleUseSendReport JSON example:
 //  {
 //   "Rounds":[1,5,9],
+//   "RoundURL": "https://dashboard.xx.network/rounds/25?xxmessenger=true",
 //   "EphID":1655533,
 //   "ReceptionID":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD"}
 //  }
 type SingleUseSendReport struct {
 	RoundsList
+	RoundURL    string
 	ReceptionID *id.ID
 	EphID       int64
 }
@@ -115,9 +118,10 @@ type SingleUseSendReport struct {
 // information passed to the single.Response callback interface in response to
 // single.TransmitRequest.
 //
-// JSON example:
+// SingleUseResponseReport JSON example:
 //  {
 //   "Rounds":[1,5,9],
+//   "RoundURL": "https://dashboard.xx.network/rounds/25?xxmessenger=true",
 //   "Payload":"rSuPD35ELWwm5KTR9ViKIz/r1YGRgXIl5792SF8o8piZzN6sT4Liq4rUU/nfOPvQEjbfWNh/NYxdJ72VctDnWw==",
 //   "EphID":1655533,
 //   "ReceptionID":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD"},
@@ -125,6 +129,7 @@ type SingleUseSendReport struct {
 //  }
 type SingleUseResponseReport struct {
 	RoundsList
+	RoundURL    string
 	Payload     []byte
 	ReceptionID *id.ID
 	EphID       int64
@@ -134,16 +139,18 @@ type SingleUseResponseReport struct {
 // SingleUseCallbackReport is the bindings-layer struct used to represent
 // single -use messages received by a callback passed into single.Listen.
 //
-// JSON example:
-//  {
-//   "Rounds":[1,5,9],
-//   "Payload":"rSuPD35ELWwm5KTR9ViKIz/r1YGRgXIl5792SF8o8piZzN6sT4Liq4rUU/nfOPvQEjbfWNh/NYxdJ72VctDnWw==",
-//   "Partner":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD",
-//   "EphID":1655533,
-//   "ReceptionID":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD"}
-//  }
+// SingleUseCallbackReport JSON example:
+//    {
+//      "Rounds":[1,5,9],
+//      "RoundURL": "https://dashboard.xx.network/rounds/25?xxmessenger=true",
+//      "Payload":"rSuPD35ELWwm5KTR9ViKIz/r1YGRgXIl5792SF8o8piZzN6sT4Liq4rUU/nfOPvQEjbfWNh/NYxdJ72VctDnWw==",
+//      "Partner":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD",
+//      "EphID":1655533,
+//      "ReceptionID":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD"}
+//    }
 type SingleUseCallbackReport struct {
 	RoundsList
+	RoundURL    string
 	Payload     []byte
 	Partner     *id.ID
 	EphID       int64
@@ -208,6 +215,7 @@ func (sl singleUseListener) Callback(
 	scr := SingleUseCallbackReport{
 		Payload:     req.GetPayload(),
 		RoundsList:  makeRoundsList(rids...),
+		RoundURL:    getRoundURL(rids[0]),
 		Partner:     req.GetPartner(),
 		EphID:       eid.EphId.Int64(),
 		ReceptionID: eid.Source,
@@ -246,6 +254,7 @@ func (sr singleUseResponse) Callback(payload []byte,
 	}
 	sendReport := SingleUseResponseReport{
 		RoundsList:  makeRoundsList(rids...),
+		RoundURL:    getRoundURL(rids[0]),
 		ReceptionID: receptionID.Source,
 		EphID:       receptionID.EphId.Int64(),
 		Payload:     payload,
diff --git a/bindings/ud.go b/bindings/ud.go
index a49031ad7..d167e145d 100644
--- a/bindings/ud.go
+++ b/bindings/ud.go
@@ -414,6 +414,7 @@ func LookupUD(e2eID int, udContact []byte, cb UdLookupCallback,
 		EphID:       eid.EphId.Int64(),
 		ReceptionID: eid.Source,
 		RoundsList:  makeRoundsList(rids...),
+		RoundURL:    getRoundURL(rids[0]),
 	}
 
 	return json.Marshal(sr)
@@ -517,6 +518,7 @@ func SearchUD(e2eID int, udContact []byte, cb UdSearchCallback,
 		EphID:       eid.EphId.Int64(),
 		ReceptionID: eid.Source,
 		RoundsList:  makeRoundsList(rids...),
+		RoundURL:    getRoundURL(rids[0]),
 	}
 
 	return json.Marshal(sr)
-- 
GitLab