|
- package endpoints
-
- import (
- "encoding/json"
- "fmt"
- "net/http"
-
- "github.com/imosed/signet/client"
- . "github.com/imosed/signet/data"
- "github.com/imosed/signet/utils"
- "github.com/rs/zerolog/log"
- "github.com/stellar/go/clients/horizonclient"
- "github.com/stellar/go/keypair"
- "github.com/stellar/go/network"
- "github.com/stellar/go/protocols/horizon"
- "github.com/stellar/go/txnbuild"
- "github.com/stellar/go/xdr"
- "gorm.io/gorm/clause"
- )
-
- type SubmitFundRequest struct {
- FundID uint `json:"fundID"`
- Submit bool `json:"submit"`
- }
-
- func SubmitFund(w http.ResponseWriter, r *http.Request) {
- var req SubmitFundRequest
- err := json.NewDecoder(r.Body).Decode(&req)
- if err != nil {
- log.Error().Err(err).Msg("Could not decode body in SubmitFund call")
- }
-
- var fund RewardFund
- Db.Preload(clause.Associations).Find(&fund, req.FundID)
-
- var resp SuccessResponse
- if !req.Submit {
- json.NewEncoder(w).Encode(&SuccessResponse{Success: false})
- return
- }
-
- source := keypair.MustParseFull(fund.FundSecret)
- sourceReq := horizonclient.AccountRequest{AccountID: source.Address()}
- var sourceAcct horizon.Account
- sourceAcct, err = client.SignetClient.AccountDetail(sourceReq)
-
- offerReq := horizonclient.OfferRequest{
- Seller: fund.SellingWallet,
- Selling: fmt.Sprintf("%s:%s", fund.Asset, fund.IssuerWallet),
- Order: horizonclient.OrderDesc,
- }
-
- if err, ok := utils.FindOffer(offerReq, &fund); !ok {
- err = json.NewEncoder(w).Encode(&SuccessResponse{Success: ok})
- if err != nil {
- log.Error().Err(err).Msg("Could not deliver response after failing to find issuer offer in submission")
- }
- return
- }
-
- var currentContributions = fund.Contributions
- var submissionAmount = SumContributions(currentContributions)
-
- tr := Db.Begin()
- tr.Table("contributions").
- Where("reward_fund_id = ? and submitted is null or submitted = false", req.FundID).
- Updates(Contribution{Submitted: true})
-
- var tx *txnbuild.Transaction
- tx, err = txnbuild.NewTransaction(
- txnbuild.TransactionParams{
- SourceAccount: &sourceAcct,
- IncrementSequenceNum: true,
- Operations: []txnbuild.Operation{
- &txnbuild.ChangeTrust{
- Line: txnbuild.CreditAsset{
- Code: fund.Asset,
- Issuer: fund.IssuerWallet,
- }.MustToChangeTrustAsset(),
- SourceAccount: fund.FundWallet,
- },
- &txnbuild.ManageBuyOffer{
- Selling: txnbuild.NativeAsset{},
- Buying: txnbuild.CreditAsset{
- Code: fund.Asset,
- Issuer: fund.IssuerWallet,
- },
- Amount: fmt.Sprintf("%f", submissionAmount),
- Price: xdr.Price{N: 1, D: xdr.Int32(fund.Price)},
- OfferID: 0,
- SourceAccount: fund.FundWallet,
- },
- },
- BaseFee: txnbuild.MinBaseFee,
- Memo: txnbuild.Memo(nil),
- Preconditions: txnbuild.Preconditions{
- TimeBounds: txnbuild.NewInfiniteTimeout(), // TODO: change from infinite
- },
- })
- if err != nil {
- log.Error().Err(err).Msg("Could not build submission transaction")
- tr.Rollback()
- return
- }
-
- tx, err = tx.Sign(network.TestNetworkPassphrase, source)
- if err != nil {
- log.Error().Err(err).Msg("Could not sign submission transaction")
- tr.Rollback()
- return
- }
-
- var response horizon.Transaction
- response, err = client.SignetClient.SubmitTransaction(tx)
- if err != nil {
- log.Error().Err(err).Msg("Could not submit transaction")
- tr.Rollback()
- return
- }
-
- tr.Commit()
- resp.Success = response.Successful
-
- err = json.NewEncoder(w).Encode(resp)
- if err != nil {
- log.Error().Err(err).Msg("Could not deliver response in SubmitFund call")
- }
- }
-
- func SumContributions(contributions []Contribution) float64 {
- var total float64 = 0
- for _, contribution := range contributions {
- if !contribution.Submitted {
- total += contribution.Amount
- }
- }
- return total
- }
|