The backend for the project formerly known as signet, now known as beignet.
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

139 rader
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. }