The backend for the project formerly known as signet, now known as beignet.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

147 line
3.8 KiB

  1. package endpoints
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net/http"
  6. "strconv"
  7. "github.com/imosed/signet/auth"
  8. . "github.com/imosed/signet/data"
  9. "github.com/stellar/go/clients/horizonclient"
  10. "github.com/stellar/go/protocols/horizon"
  11. )
  12. type CreateRewardFundRequest struct {
  13. Asset string `json:"asset"`
  14. FundWallet string `json:"fundWallet"`
  15. SellingWallet string `json:"sellingWallet"`
  16. IssuerWallet string `json:"issuerWallet"`
  17. Memo string `json:"memo"`
  18. MinContribution float64 `gorm:"type:decimal(19,7)" json:"minContribution"`
  19. Title string `gorm:"type:varchar(50)" json:"title"`
  20. Description string `gorm:"type:text" json:"description"`
  21. QueueID uint `json:"queueID"`
  22. Bonuses []Bonus `json:"bonuses"`
  23. }
  24. type SuccessResponse struct {
  25. Success bool `json:"success"`
  26. }
  27. func CreateRewardFund(resp http.ResponseWriter, req *http.Request) {
  28. var fund CreateRewardFundRequest
  29. dec := json.NewDecoder(req.Body)
  30. err := dec.Decode(&fund)
  31. if err != nil {
  32. panic("Could not read submitted reward fund")
  33. }
  34. var bonuses []Bonus
  35. rewardFund := RewardFund{
  36. Asset: fund.Asset,
  37. FundWallet: fund.FundWallet,
  38. SellingWallet: fund.SellingWallet,
  39. IssuerWallet: fund.IssuerWallet,
  40. Memo: fund.Memo,
  41. Price: 0,
  42. AmountAvailable: 0,
  43. MinContribution: fund.MinContribution,
  44. Title: fund.Title,
  45. Description: fund.Description,
  46. Contributions: nil,
  47. }
  48. var fundsInQueue []RewardFund
  49. Db.Table("queue_reward_funds").Where("queue_id = ?", fund.QueueID).Scan(&fundsInQueue)
  50. next := uint16(len(fundsInQueue))
  51. joinTable := QueueOrder{QueueID: fund.QueueID, RewardFundID: rewardFund.ID, Order: next}
  52. offerReq := horizonclient.OfferRequest{
  53. Seller: rewardFund.SellingWallet,
  54. Selling: fmt.Sprintf("%s:%s", rewardFund.Asset, rewardFund.IssuerWallet),
  55. Order: horizonclient.OrderDesc,
  56. }
  57. url, _ := offerReq.BuildURL()
  58. fmt.Println(url)
  59. op, err := client.Offers(offerReq)
  60. if err != nil {
  61. panic("Could not get offers")
  62. }
  63. offers := op.Embedded.Records
  64. var price float64
  65. var amt float64
  66. if len(offers) == 1 {
  67. price, err = strconv.ParseFloat(op.Embedded.Records[0].Price, 64)
  68. if err != nil {
  69. panic("Could not parse price to float")
  70. }
  71. amt, err = strconv.ParseFloat(op.Embedded.Records[0].Amount, 64)
  72. if err != nil {
  73. panic("Could not parse amount to float")
  74. }
  75. rewardFund.Price = price
  76. rewardFund.AmountAvailable = amt
  77. } else if len(offers) > 1 {
  78. var maxOffers float64 = 0
  79. var correctOffer horizon.Offer
  80. for _, o := range op.Embedded.Records {
  81. parsedAmt, err := strconv.ParseFloat(o.Amount, 64)
  82. if err != nil {
  83. panic("Could not parse amount to float")
  84. }
  85. if parsedAmt > maxOffers {
  86. correctOffer = o
  87. maxOffers = parsedAmt
  88. }
  89. }
  90. price, err = strconv.ParseFloat(correctOffer.Price, 64)
  91. if err != nil {
  92. panic("Could not parse price to float")
  93. }
  94. rewardFund.Price = price
  95. amt, err = strconv.ParseFloat(correctOffer.Amount, 64)
  96. if err != nil {
  97. panic("Could not parse amount to float")
  98. }
  99. rewardFund.AmountAvailable = amt
  100. } else {
  101. err = json.NewEncoder(resp).Encode(&SuccessResponse{Success: false})
  102. return
  103. }
  104. var claims *auth.Claims
  105. claims, err = auth.GetUserClaims(req)
  106. if err != nil {
  107. panic("Could not determine if user is authenticated")
  108. }
  109. if claims.Privileges <= Admin {
  110. Db.Create(&rewardFund)
  111. Db.Create(&joinTable)
  112. for _, cancel := range cancellations {
  113. cancel()
  114. }
  115. go InitializeContributionStreams()
  116. for _, bonus := range fund.Bonuses {
  117. bonus.RewardFundID = rewardFund.ID
  118. bonuses = append(bonuses, bonus)
  119. }
  120. Db.Create(&bonuses)
  121. err = json.NewEncoder(resp).Encode(&SuccessResponse{Success: true})
  122. if err != nil {
  123. panic("Could not create response for created reward fund")
  124. }
  125. } else {
  126. resp.WriteHeader(403)
  127. }
  128. }