Skip to content

Commit

Permalink
Merge pull request stakwork#1900 from stakwork/fix/v2_payment_history
Browse files Browse the repository at this point in the history
PR: fixed V2 payment history for  failed payments
  • Loading branch information
elraphty authored Oct 22, 2024
2 parents 93cfe2f + f03c576 commit 8c3aee2
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 17 deletions.
6 changes: 6 additions & 0 deletions db/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,8 @@ type Bounty struct {
CodingLanguages pq.StringArray `gorm:"type:text[];not null default:'[]'" json:"coding_languages"`
PhaseUuid *string `json:"phase_uuid"`
PhasePriority *int `json:"phase_priority"`
PaymentPending bool `gorm:"default:false" json:"payment_pending"`
PaymentFailed bool `gorm:"default:false" json:"payment_failed"`
}

// Todo: Change back to Bounty
Expand Down Expand Up @@ -427,6 +429,8 @@ type NewBounty struct {
CodingLanguages pq.StringArray `gorm:"type:text[];not null default:'[]'" json:"coding_languages"`
PhaseUuid string `json:"phase_uuid"`
PhasePriority int `json:"phase_priority"`
PaymentPending bool `gorm:"default:false" json:"payment_pending"`
PaymentFailed bool `gorm:"default:false" json:"payment_failed"`
}

type BountyOwners struct {
Expand Down Expand Up @@ -718,6 +722,7 @@ type PaymentHistory struct {
ReceiverPubKey string `json:"receiver_pubkey"`
Tag string `json:"tag,omitempty"`
PaymentStatus string `json:"payment_status,omitempty"`
Error string `json:"error,omitempty"`
Created *time.Time `json:"created"`
Updated *time.Time `json:"updated"`
Status bool `json:"status"`
Expand All @@ -734,6 +739,7 @@ type NewPaymentHistory struct {
ReceiverPubKey string `json:"receiver_pubkey"`
Tag string `json:"tag,omitempty"`
PaymentStatus string `json:"payment_status,omitempty"`
Error string `json:"error,omitempty"`
Created *time.Time `json:"created"`
Updated *time.Time `json:"updated"`
Status bool `json:"status"`
Expand Down
1 change: 1 addition & 0 deletions db/structsv2.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type V2SendOnionRes struct {
Tag string `json:"tag"`
Preimage string `json:"preimage"`
PaymentHash string `json:"payment_hash"`
Message string `json:"message,omitempty"`
}

type V2PayInvoiceBody struct {
Expand Down
11 changes: 0 additions & 11 deletions db/workspaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -440,17 +440,6 @@ func (db database) WithdrawBudget(sender_pubkey string, workspace_uuid string, a
func (db database) AddPaymentHistory(payment NewPaymentHistory) NewPaymentHistory {
db.db.Create(&payment)

// get Workspace budget and subtract payment from total budget
WorkspaceBudget := db.GetWorkspaceBudget(payment.WorkspaceUuid)
totalBudget := WorkspaceBudget.TotalBudget

// deduct amount if it's a bounty payment
if payment.PaymentType == "payment" {
WorkspaceBudget.TotalBudget = totalBudget - payment.Amount
}

db.UpdateWorkspaceBudget(WorkspaceBudget)

return payment
}

Expand Down
73 changes: 68 additions & 5 deletions handlers/bounty.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,13 +256,22 @@ func (h *bountyHandler) CreateOrEditBounty(w http.ResponseWriter, r *http.Reques
// get bounty from DB
dbBounty := h.db.GetBounty(bounty.ID)

// check if the bounty has a pending payment
if dbBounty.PaymentPending {
msg := "You cannot update a bounty with a pending payment"
fmt.Println("[bounty]", msg)
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode(msg)
return
}

// trying to update
// check if bounty belongs to user
if pubKeyFromAuth != dbBounty.OwnerID {
if bounty.WorkspaceUuid != "" {
hasBountyRoles := h.userHasManageBountyRoles(pubKeyFromAuth, bounty.WorkspaceUuid)
if !hasBountyRoles {
msg := "You don't have a=the right permission ton update bounty"
msg := "You don't have the right permission ton update bounty"
fmt.Println("[bounty]", msg)
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode(msg)
Expand Down Expand Up @@ -360,6 +369,12 @@ func UpdatePaymentStatus(w http.ResponseWriter, r *http.Request) {
created, _ := strconv.ParseUint(createdParam, 10, 32)

bounty, _ := db.DB.GetBountyByCreated(uint(created))
if bounty.PaymentPending {
w.WriteHeader(http.StatusBadGateway)
json.NewEncoder(w).Encode("Cannot update a bounty with a pending payment")
return
}

if bounty.ID != 0 && bounty.Created == int64(created) {
bounty.Paid = !bounty.Paid
now := time.Now()
Expand All @@ -369,6 +384,7 @@ func UpdatePaymentStatus(w http.ResponseWriter, r *http.Request) {
bounty.Completed = true
bounty.CompletionDate = &now
bounty.MarkAsPaidDate = &now

if bounty.PaidDate == nil {
bounty.PaidDate = &now
}
Expand All @@ -382,8 +398,14 @@ func UpdatePaymentStatus(w http.ResponseWriter, r *http.Request) {
func UpdateCompletedStatus(w http.ResponseWriter, r *http.Request) {
createdParam := chi.URLParam(r, "created")
created, _ := strconv.ParseUint(createdParam, 10, 32)

bounty, _ := db.DB.GetBountyByCreated(uint(created))

if bounty.PaymentPending {
w.WriteHeader(http.StatusBadGateway)
json.NewEncoder(w).Encode("Cannot update a bounty with a pending payment")
return
}

if bounty.ID != 0 && bounty.Created == int64(created) {
now := time.Now()
// set bounty as completed
Expand Down Expand Up @@ -436,6 +458,8 @@ func (h *bountyHandler) GenerateBountyResponse(bounties []db.NewBounty) []db.Bou
Updated: bounty.Updated,
CodingLanguages: bounty.CodingLanguages,
Completed: bounty.Completed,
PaymentPending: bounty.PaymentPending,
PaymentFailed: bounty.PaymentFailed,
},
Assignee: db.Person{
ID: assignee.ID,
Expand Down Expand Up @@ -531,6 +555,13 @@ func (h *bountyHandler) MakeBountyPayment(w http.ResponseWriter, r *http.Request
return
}

if bounty.PaymentPending {
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode("Bounty payemnt is pending, cannot retry payment")
h.m.Unlock()
return
}

// check if user is the admin of the workspace
// or has a pay bounty role
hasRole := h.userHasAccess(pubKeyFromAuth, bounty.WorkspaceUuid, db.PayBounty)
Expand Down Expand Up @@ -637,7 +668,7 @@ func (h *bountyHandler) MakeBountyPayment(w http.ResponseWriter, r *http.Request
BountyId: id,
Created: &now,
Updated: &now,
Status: true,
Status: false,
PaymentType: "payment",
Tag: v2KeysendRes.Tag,
PaymentStatus: v2KeysendRes.Status,
Expand All @@ -649,6 +680,7 @@ func (h *bountyHandler) MakeBountyPayment(w http.ResponseWriter, r *http.Request
bounty.PaidDate = &now
bounty.Completed = true
bounty.CompletionDate = &now
paymentHistory.Status = true

h.db.ProcessBountyPayment(paymentHistory, bounty)

Expand All @@ -659,10 +691,42 @@ func (h *bountyHandler) MakeBountyPayment(w http.ResponseWriter, r *http.Request
if err == nil {
socket.Conn.WriteJSON(msg)
}

h.m.Unlock()
return
} else if v2KeysendRes.Status == db.PaymentPending {
// Send payment status
log.Printf("[bounty] V2 Status is pending: %s", v2KeysendRes.Status)
bounty.Paid = false
bounty.PaymentPending = true
bounty.PaidDate = &now
bounty.Completed = true
bounty.CompletionDate = &now
paymentHistory.Status = true

h.db.ProcessBountyPayment(paymentHistory, bounty)

msg["msg"] = "keysend_pending"
msg["invoice"] = ""

socket, err := h.getSocketConnections(request.Websocket_token)
if err == nil {
socket.Conn.WriteJSON(msg)
}

h.m.Unlock()
return
} else {
// Send payment status
log.Printf("[bounty] V2 Status Was not completed: %s", v2KeysendRes.Status)

bounty.Paid = false
bounty.PaymentPending = false
bounty.PaymentFailed = true

// set the error message
paymentHistory.Error = v2KeysendRes.Message

h.db.AddPaymentHistory(paymentHistory)

log.Println("Keysend payment not completed ===")
Expand Down Expand Up @@ -775,8 +839,6 @@ func (h *bountyHandler) MakeBountyPayment(w http.ResponseWriter, r *http.Request
return
}
}

h.m.Unlock()
}

func (h *bountyHandler) GetBountyPaymentStatus(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -878,6 +940,7 @@ func (h *bountyHandler) UpdateBountyPaymentStatus(w http.ResponseWriter, r *http
now := time.Now()

bounty.Paid = true
bounty.PaymentPending = false
bounty.PaidDate = &now
bounty.Completed = true
bounty.CompletionDate = &now
Expand Down
1 change: 0 additions & 1 deletion routes/bounty.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ func BountyRoutes() chi.Router {
r.Post("/pay/{id}", bountyHandler.MakeBountyPayment)
r.Get("/payment/status/{id}", bountyHandler.GetBountyPaymentStatus)
r.Put("/payment/status/{id}", bountyHandler.UpdateBountyPaymentStatus)
r.Get("/payment/status/{id}", bountyHandler.GetBountyPaymentStatus)

r.Post("/", bountyHandler.CreateOrEditBounty)
r.Delete("/assignee", handlers.DeleteBountyAssignee)
Expand Down

0 comments on commit 8c3aee2

Please sign in to comment.