The backend for the project formerly known as signet, now known as beignet.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

155 Zeilen
5.0 KiB

  1. package endpoints
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "time"
  6. . "github.com/imosed/signet/data"
  7. "github.com/rs/zerolog/log"
  8. "gorm.io/gorm/clause"
  9. )
  10. type Total struct {
  11. AmountHeld float64 `json:"amountHeld"`
  12. }
  13. type GetRewardFundRequest struct {
  14. ID uint `json:"id"`
  15. ConsolidateContributions bool `json:"consolidateContributions"`
  16. }
  17. type GetRewardFundResponse struct {
  18. FundInfo FundInfo `json:"fundInfo"`
  19. Contributions Contributions `json:"contributions"`
  20. Total Total `json:"total"`
  21. }
  22. func GetRewardFund(resp http.ResponseWriter, req *http.Request) {
  23. var fund RewardFund
  24. var contribs Contributions
  25. var amountHeld Total
  26. var requestedFund GetRewardFundRequest
  27. dec := json.NewDecoder(req.Body)
  28. err := dec.Decode(&requestedFund)
  29. if err != nil {
  30. log.Error().Err(err).Msg("Could not read requested fund")
  31. }
  32. found := Db.Preload(clause.Associations).Find(&fund, requestedFund.ID).RowsAffected
  33. if found == 0 {
  34. resp.WriteHeader(404)
  35. return
  36. }
  37. Db.Table("contributions").Select("distinct on (created_at::TIMESTAMP::DATE) created_at").Where("reward_fund_id = ?", fund.ID).Scan(&contribs.Dates)
  38. baseQuery := Db.Table("contributions").Where("reward_fund_id = ?", fund.ID).Limit(30)
  39. baseCount := Db.Table("contributions").Where("reward_fund_id = ?", fund.ID)
  40. Db.Table("contributions").Select("sum(amount) amount_held").Where("reward_fund_id = ?", fund.ID).Scan(&amountHeld)
  41. if requestedFund.ConsolidateContributions {
  42. baseQuery.Select("wallet, sum(amount) amount").Group("wallet").Order("wallet").Scan(&contribs.List)
  43. baseCount.Group("wallet").Count(&contribs.Total)
  44. } else {
  45. baseQuery.Select("wallet, amount, created_at").Order("created_at desc").Scan(&contribs.List)
  46. baseCount.Count(&contribs.Total)
  47. }
  48. r := GetRewardFundResponse{
  49. FundInfo: FundInfo{
  50. ID: fund.ID,
  51. CreatedAt: fund.CreatedAt,
  52. Asset: fund.Asset,
  53. FundWallet: fund.FundWallet,
  54. IssuerWallet: fund.IssuerWallet,
  55. Memo: fund.Memo,
  56. Price: fund.Price,
  57. AmountAvailable: fund.AmountAvailable,
  58. MinContribution: fund.MinContribution,
  59. TelegramLink: fund.TelegramLink,
  60. Bonuses: fund.Bonuses,
  61. },
  62. Contributions: contribs,
  63. Total: amountHeld,
  64. }
  65. err = json.NewEncoder(resp).Encode(r)
  66. if err != nil {
  67. log.Error().Err(err).Msg("Could not deliver requested fund")
  68. }
  69. }
  70. type GetContributionsRequest struct {
  71. ID uint `json:"id"`
  72. Offset int `json:"offset"`
  73. ForDate string `json:"forDate"`
  74. ConsolidateContributions bool `json:"consolidateContributions"`
  75. }
  76. type Contributions struct {
  77. List []Contribution `json:"list"`
  78. Dates []string `json:"dates"`
  79. Total int64 `json:"total"`
  80. }
  81. type GetContributionsResponse = Contributions
  82. func GetContributions(w http.ResponseWriter, r *http.Request) {
  83. var req GetContributionsRequest
  84. err := json.NewDecoder(r.Body).Decode(&req)
  85. if err != nil {
  86. log.Error().Err(err).Msg("Could not decode body in GetContributions call")
  87. return
  88. }
  89. var resp GetContributionsResponse
  90. baseQuery := Db.Table("contributions").Where("reward_fund_id = ?", req.ID).Offset(req.Offset).Limit(30)
  91. baseCount := Db.Table("contributions").Where("reward_fund_id = ?", req.ID)
  92. Db.Table("contributions").Select("distinct on (created_at::TIMESTAMP::DATE) created_at").Where("reward_fund_id = ?", req.ID).Scan(&resp.Dates)
  93. if req.ForDate == "" {
  94. if req.ConsolidateContributions {
  95. baseQuery.Select("wallet, sum(amount) amount").Group("wallet").Scan(&resp.List)
  96. baseCount.Group("wallet").Count(&resp.Total)
  97. } else {
  98. baseQuery.Select("wallet, amount, created_at").Order("created_at desc").Scan(&resp.List)
  99. baseCount.Count(&resp.Total)
  100. }
  101. } else {
  102. var t time.Time
  103. t, err = time.Parse("2006-Jan-02", req.ForDate)
  104. t = t.Add(time.Hour * 24)
  105. if err != nil {
  106. log.Error().Err(err).Msg("Could not interpret time")
  107. return
  108. }
  109. if req.ConsolidateContributions {
  110. baseQuery.Select("wallet, sum(amount) amount").Where("created_at < ?", t).Group("wallet").Scan(&resp.List)
  111. baseCount.Where("created_at < ?", t).Group("wallet").Count(&resp.Total)
  112. } else {
  113. baseQuery.Select("wallet, amount, created_at").Where("created_at < ?", t).Order("created_at desc").Scan(&resp.List)
  114. baseCount.Where("created_at < ?", t).Count(&resp.Total)
  115. }
  116. }
  117. err = json.NewEncoder(w).Encode(resp)
  118. if err != nil {
  119. log.Error().Err(err).Msg("Could not deliver response in GetContributions call")
  120. }
  121. }
  122. type FundInfo struct {
  123. ID uint `json:"id"`
  124. CreatedAt time.Time `json:"createdAt"`
  125. Asset string `json:"asset"`
  126. FundWallet string `json:"fundWallet"`
  127. IssuerWallet string `json:"issuerWallet"`
  128. Memo string `json:"memo"`
  129. Price float64 `json:"price"`
  130. AmountAvailable float64 `json:"amountAvailable"`
  131. MinContribution float64 `json:"minContribution"`
  132. TelegramLink string `json:"telegramLink"`
  133. Bonuses []Bonus `json:"bonuses"`
  134. }