The backend for the project formerly known as signet, now known as beignet.
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

139 linhas
3.7 KiB

  1. package endpoints
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net/http"
  6. "github.com/imosed/signet/client"
  7. . "github.com/imosed/signet/data"
  8. "github.com/imosed/signet/utils"
  9. "github.com/rs/zerolog/log"
  10. "github.com/stellar/go/clients/horizonclient"
  11. "github.com/stellar/go/keypair"
  12. "github.com/stellar/go/network"
  13. "github.com/stellar/go/protocols/horizon"
  14. "github.com/stellar/go/txnbuild"
  15. "github.com/stellar/go/xdr"
  16. "gorm.io/gorm/clause"
  17. )
  18. type SubmitFundRequest struct {
  19. FundID uint `json:"fundID"`
  20. Submit bool `json:"submit"`
  21. }
  22. func SubmitFund(w http.ResponseWriter, r *http.Request) {
  23. var req SubmitFundRequest
  24. err := json.NewDecoder(r.Body).Decode(&req)
  25. if err != nil {
  26. log.Error().Err(err).Msg("Could not decode body in SubmitFund call")
  27. }
  28. var fund RewardFund
  29. Db.Preload(clause.Associations).Find(&fund, req.FundID)
  30. var resp SuccessResponse
  31. if !req.Submit {
  32. json.NewEncoder(w).Encode(&SuccessResponse{Success: false})
  33. return
  34. }
  35. source := keypair.MustParseFull(fund.FundSecret)
  36. sourceReq := horizonclient.AccountRequest{AccountID: source.Address()}
  37. var sourceAcct horizon.Account
  38. sourceAcct, err = client.SignetClient.AccountDetail(sourceReq)
  39. offerReq := horizonclient.OfferRequest{
  40. Seller: fund.SellingWallet,
  41. Selling: fmt.Sprintf("%s:%s", fund.Asset, fund.IssuerWallet),
  42. Order: horizonclient.OrderDesc,
  43. }
  44. if err, ok := utils.FindOffer(offerReq, &fund); !ok {
  45. err = json.NewEncoder(w).Encode(&SuccessResponse{Success: ok})
  46. if err != nil {
  47. log.Error().Err(err).Msg("Could not deliver response after failing to find issuer offer in submission")
  48. }
  49. return
  50. }
  51. var currentContributions = fund.Contributions
  52. var submissionAmount = SumContributions(currentContributions)
  53. tr := Db.Begin()
  54. tr.Table("contributions").
  55. Where("reward_fund_id = ? and submitted is null or submitted = false", req.FundID).
  56. Updates(Contribution{Submitted: true})
  57. var tx *txnbuild.Transaction
  58. tx, err = txnbuild.NewTransaction(
  59. txnbuild.TransactionParams{
  60. SourceAccount: &sourceAcct,
  61. IncrementSequenceNum: true,
  62. Operations: []txnbuild.Operation{
  63. &txnbuild.ChangeTrust{
  64. Line: txnbuild.CreditAsset{
  65. Code: fund.Asset,
  66. Issuer: fund.IssuerWallet,
  67. }.MustToChangeTrustAsset(),
  68. SourceAccount: fund.FundWallet,
  69. },
  70. &txnbuild.ManageBuyOffer{
  71. Selling: txnbuild.NativeAsset{},
  72. Buying: txnbuild.CreditAsset{
  73. Code: fund.Asset,
  74. Issuer: fund.IssuerWallet,
  75. },
  76. Amount: fmt.Sprintf("%f", submissionAmount),
  77. Price: xdr.Price{N: 1, D: xdr.Int32(fund.Price)},
  78. OfferID: 0,
  79. SourceAccount: fund.FundWallet,
  80. },
  81. },
  82. BaseFee: txnbuild.MinBaseFee,
  83. Memo: txnbuild.Memo(nil),
  84. Preconditions: txnbuild.Preconditions{
  85. TimeBounds: txnbuild.NewInfiniteTimeout(), // TODO: change from infinite
  86. },
  87. })
  88. if err != nil {
  89. log.Error().Err(err).Msg("Could not build submission transaction")
  90. tr.Rollback()
  91. return
  92. }
  93. tx, err = tx.Sign(network.TestNetworkPassphrase, source)
  94. if err != nil {
  95. log.Error().Err(err).Msg("Could not sign submission transaction")
  96. tr.Rollback()
  97. return
  98. }
  99. var response horizon.Transaction
  100. response, err = client.SignetClient.SubmitTransaction(tx)
  101. if err != nil {
  102. log.Error().Err(err).Msg("Could not submit transaction")
  103. tr.Rollback()
  104. return
  105. }
  106. tr.Commit()
  107. resp.Success = response.Successful
  108. err = json.NewEncoder(w).Encode(resp)
  109. if err != nil {
  110. log.Error().Err(err).Msg("Could not deliver response in SubmitFund call")
  111. }
  112. }
  113. func SumContributions(contributions []Contribution) float64 {
  114. var total float64 = 0
  115. for _, contribution := range contributions {
  116. if !contribution.Submitted {
  117. total += contribution.Amount
  118. }
  119. }
  120. return total
  121. }