Skip to content

Commit

Permalink
Merge pull request #1864 from stakwork/feat/integrate_v2_payments
Browse files Browse the repository at this point in the history
PR: v2 bounty payouts
  • Loading branch information
elraphty authored Sep 12, 2024
2 parents 6668612 + 09596cd commit 94e3b4a
Show file tree
Hide file tree
Showing 21 changed files with 2,935 additions and 304 deletions.
19 changes: 14 additions & 5 deletions .github/workflows/frontend-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ jobs:

- name: Clone Stack
run: |
git clone https://github.com/stakwork/sphinx-stack.git stack
git clone --single-branch --branch change_v2_ports https://github.com/stakwork/sphinx-stack.git stack
- name: Clone Sphinx Tribes Frontend
run: |
git clone https://github.com/stakwork/sphinx-tribes-frontend.git tribes-frontend
git clone --single-branch --branch feat/v2_payments_cypress_test https://github.com/stakwork/sphinx-tribes-frontend.git tribes-frontend
- name: Give Permissions to Stack
working-directory: ./stack
Expand All @@ -46,20 +46,29 @@ jobs:
timeout_minutes: 10
max_attempts: 3
command: |
GITACTION_ENV=gitactionenv docker compose -f ./stack/alts/proxy.yml --project-directory ./stack up -d;
GITACTION_ENV=gitactionenv docker compose -f ./stack/alts/v1v2.yml --project-directory ./stack up -d;
sleep 240;
docker ps
docker logs meme.sphinx
docker logs dave.sphinx
docker wait stack_relaysetup_1
docker logs db.sphinx
docker logs tribes.sphinx
docker wait stack-relaysetup-1
cat stack/relay/NODES.json;
cat stack/relay/V2NODES.json;
- name: Copy Node.json
uses: canastro/copy-file-action@master
with:
source: "stack/relay/NODES.json"
target: "tribes-frontend/cypress/fixtures/nodes.json"

- name: Copy V2Node.json
uses: canastro/copy-file-action@master
with:
source: "stack/relay/V2NODES.json"
target: "tribes-frontend/cypress/fixtures/v2nodes.json"

- name: Install Frontend Dependencies
working-directory: ./tribes-frontend
run: yarn install
Expand All @@ -79,7 +88,7 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: cypress-logs
path: tribes-frontend/cypress/videos
path: tribes-frontend/cypress/screenshots

- name: Stop Stack
working-directory: ./stack
Expand Down
25 changes: 23 additions & 2 deletions .github/workflows/prjob_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,35 @@ jobs:
- uses: actions/checkout@v2

- name: Clone Stack
run: |
git clone --single-branch --branch change_v2_ports https://github.com/stakwork/sphinx-stack.git stackv2;
- name: Run Stack V2
uses: nick-fields/retry@v2
with:
timeout_minutes: 10
max_attempts: 3
command: |
GITACTION_ENV=gitactionenv docker compose -f ./stackv2/alts/v2.yml --project-directory ./stackv2 up -d;
sleep 240;
docker ps
docker logs alice.sphinx
docker logs bob.sphinx
docker wait stackv2-v2setup-1
- name: Starting DB
run: docker compose -f ./docker/testdb-docker-compose.yml -p test_db up -d

- name: Install cover
run: go get golang.org/x/tools/cmd/cover

- name: Tests
run: RELAY_AUTH_KEY=TEST go test ./... -race -v -coverprofile=coverage.out && ./cover-check.sh coverage.out 8.4
run: sudo V2_BOT_URL=http://localhost:3005 V2_BOT_TOKEN=xyzxyzxyz go test ./... -race -v -coverprofile=coverage.out && ./cover-check.sh coverage.out 8.4

- name: Droping with docker compose
- name: Droping DB with docker compose
run: docker compose -f ./docker/testdb-docker-compose.yml -p test_db down

- name: Stop Stack
working-directory: ./stackv2
run: docker compose down
59 changes: 57 additions & 2 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ var AdminStrings string
var S3Client *s3.Client
var PresignClient *s3.PresignClient

var V2BotUrl string
var V2BotToken string
var IsV2Payment bool = false

func InitConfig() {
Host = os.Getenv("LN_SERVER_BASE_URL")
JwtKey = os.Getenv("LN_JWT_KEY")
Expand All @@ -54,6 +58,8 @@ func InitConfig() {
S3Url = os.Getenv("S3_URL")
AdminCheck = os.Getenv("ADMIN_CHECK")
Connection_Auth = os.Getenv("CONNECTION_AUTH")
V2BotUrl = os.Getenv("V2_BOT_URL")
V2BotToken = os.Getenv("V2_BOT_TOKEN")

// Add to super admins
SuperAdmins = StripSuperAdmins(AdminStrings)
Expand All @@ -74,8 +80,12 @@ func InitConfig() {
// only make this call if there is a Relay auth key
if RelayAuthKey != "" {
RelayNodeKey = GetNodePubKey()
} else {
panic("No relay auth key set")
}

if V2BotUrl != "" && V2BotToken != "" {
// contact_key := GetV2ContactKey()
fmt.Println("DEBUG == IT IS V2")
IsV2Payment = true
}

if Host == "" {
Expand Down Expand Up @@ -172,6 +182,13 @@ type NodeGetInfo struct {
Response NodeGetInfoResponse `json:"response"`
}

type V2AccountInfo struct {
ContactInfo string `json:"contact_info"`
Alias string `json:"alias"`
Img string `json:"img"`
Network string `json:"network"`
}

type Contact struct {
Id uint `json:"id"`
RouteHint string `json:"route_hint"`
Expand Down Expand Up @@ -259,6 +276,44 @@ type ProxyContacts struct {
Response ContactResponse `json:"response"`
}

func GetV2ContactKey() string {
url := fmt.Sprintf("%s/account", V2BotUrl)

client := &http.Client{}
req, err := http.NewRequest(http.MethodGet, url, nil)

if err != nil {
log.Printf("Get Contact Request Failed: %s", err)
}

req.Header.Set("x-admin-token", V2BotToken)
req.Header.Set("Content-Type", "application/json")
res, err := client.Do(req)

if err != nil {
log.Printf("Get Contact Request Failed: %s", err)
return ""
}

defer res.Body.Close()
body, err := io.ReadAll(res.Body)

if err != nil {
log.Printf("Get Contact Body Read Failed: %s", err)
}

accountInfo := V2AccountInfo{}

// Unmarshal result
err = json.Unmarshal(body, &accountInfo)
if err != nil {
log.Printf("Reading Relay Node Info body failed: %s", err)
}

contact_key := accountInfo.ContactInfo
return contact_key
}

func GetNodePubKey() string {
var pubkey string
var url string
Expand Down
4 changes: 2 additions & 2 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import (
func TestInitConfig(t *testing.T) {
InitConfig()

if Host != "https://people.sphinx.chat" {
if Host == "" {
t.Error("Could not load default host")
}

if MemeUrl != "https://memes.sphinx.chat" {
if MemeUrl == "" {
t.Error("Could not load default meme url")
}

Expand Down
2 changes: 2 additions & 0 deletions db/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ func (db database) MigrateTablesWithOrgUuid() {
} else {
db.db.AutoMigrate(&NewPaymentHistory{})
}
} else {
db.db.AutoMigrate(&NewPaymentHistory{})
}
if !db.db.Migrator().HasTable("invoice_list") {
if !db.db.Migrator().HasColumn(InvoiceList{}, "workspace_uuid") {
Expand Down
4 changes: 4 additions & 0 deletions db/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,8 @@ type PaymentHistory struct {
OrgUuid string `json:"org_uuid"`
SenderPubKey string `json:"sender_pubkey"`
ReceiverPubKey string `json:"receiver_pubkey"`
Tag string `json:"tag,omitempty"`
PaymentStatus string `json:"payment_status,omitempty"`
Created *time.Time `json:"created"`
Updated *time.Time `json:"updated"`
Status bool `json:"status"`
Expand All @@ -730,6 +732,8 @@ type NewPaymentHistory struct {
WorkspaceUuid string `json:"workspace_uuid,omitempty"`
SenderPubKey string `json:"sender_pubkey"`
ReceiverPubKey string `json:"receiver_pubkey"`
Tag string `json:"tag,omitempty"`
PaymentStatus string `json:"payment_status,omitempty"`
Created *time.Time `json:"created"`
Updated *time.Time `json:"updated"`
Status bool `json:"status"`
Expand Down
58 changes: 58 additions & 0 deletions db/structsv2.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package db

const (
InvoicePaid = "paid"
InvoiceExpired = "expired"
InvoicePending = "pending"
)

const (
PaymentComplete = "COMPLETE"
PaymentFailed = "FAILED"
PaymentPending = "PENDING"
)

type V2InvoiceResponse struct {
Status string `json:"status"`
Timestamp string `json:"timestamp"`
AmtMsat string `json:"amt_msat"`
}

type V2InvoiceBody struct {
PaymentHash string `json:"payment_hash"`
Bolt11 string `json:"bolt11"`
}

type V2SendOnionRes struct {
Status string `json:"status"` // "COMPLETE", "PENDING", or "FAILED"
Tag string `json:"tag"`
Preimage string `json:"preimage"`
PaymentHash string `json:"payment_hash"`
}

type V2PayInvoiceBody struct {
Bolt11 string `json:"bolt11"`
}

type V2CreateInvoiceBody struct {
AmtMsat uint `json:"amt_msat"`
}

type V2CreateInvoiceResponse struct {
Bolt11 string `json:"bolt11"`
PaymentHash string `json:"payment_hash"`
}

type V2PayInvoiceResponse struct {
Tag string `json:"tag"`
Msat string `json:"msat"`
Timestamp string `json:"timestamp"`
PaymentHash string `json:"payment_hash"`
}

type V2TagRes struct {
Tag string `json:"tag"`
Ts uint64 `json:"ts"`
Status string `json:"status"` // "COMPLETE", "PENDING", or "FAILED"
Error string `json:"error"`
}
2 changes: 1 addition & 1 deletion db/test_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
var TestDB database

func InitTestDB() {
rdsHost := "172.17.0.1"
rdsHost := "localhost"
rdsPort := fmt.Sprintf("%d", 5532)
rdsDbName := "test_db"
rdsUsername := "test_user"
Expand Down
46 changes: 31 additions & 15 deletions db/workspaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -442,23 +442,25 @@ func (db database) ProcessBountyPayment(payment NewPaymentHistory, bounty NewBou
return err
}

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

// update budget
WorkspaceBudget.TotalBudget = totalBudget - payment.Amount
if err = tx.Model(&NewBountyBudget{}).Where("workspace_uuid = ?", payment.WorkspaceUuid).Updates(map[string]interface{}{
"total_budget": WorkspaceBudget.TotalBudget,
}).Error; err != nil {
tx.Rollback()
return err
}
// update budget
WorkspaceBudget.TotalBudget = totalBudget - payment.Amount
if err = tx.Model(&NewBountyBudget{}).Where("workspace_uuid = ?", payment.WorkspaceUuid).Updates(map[string]interface{}{
"total_budget": WorkspaceBudget.TotalBudget,
}).Error; err != nil {
tx.Rollback()
return err
}

// updatge bounty status
if err = tx.Where("created", bounty.Created).Updates(&bounty).Error; err != nil {
tx.Rollback()
return err
// updatge bounty status
if err = tx.Where("created", bounty.Created).Updates(&bounty).Error; err != nil {
tx.Rollback()
return err
}
}

return tx.Commit().Error
Expand All @@ -478,6 +480,20 @@ func (db database) GetPaymentHistory(workspace_uuid string, r *http.Request) []N
return payment
}

func (db database) GetPendingPaymentHistory() []NewPaymentHistory {
paymentHistories := []NewPaymentHistory{}

query := `SELECT * FROM payment_histories WHERE payment_status = '` + PaymentPending + `' AND status = true ORDER BY created DESC`

db.db.Raw(query).Find(&paymentHistories)
return paymentHistories
}

func (db database) SetPaymentAsComplete(tag string) bool {
db.db.Model(NewPaymentHistory{}).Where("tag = ?", tag).Update("payment_status", PaymentComplete)
return true
}

func (db database) GetWorkspaceInvoices(workspace_uuid string) []NewInvoiceList {
ms := []NewInvoiceList{}
db.db.Where("workspace_uuid = ?", workspace_uuid).Where("status", false).Find(&ms)
Expand Down
1 change: 1 addition & 0 deletions feeds/podcastindex.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ func PodcastIndexHeaders() map[string]string {

func ParsePodcastFeed(url string, fulltext bool) (*Feed, error) {
pod, err := PodcastFeed(url, fulltext)
fmt.Println("Feed ME ===", pod)
if err != nil || pod == nil {
return nil, err
}
Expand Down
Loading

0 comments on commit 94e3b4a

Please sign in to comment.