From 5c0719a5b9d42c60983c03fa066006f9d4b307a7 Mon Sep 17 00:00:00 2001 From: Jared Date: Sun, 29 Jan 2023 22:10:04 -0500 Subject: [PATCH] Allow reward distribution --- endpoints/contribute.go | 60 ++++++----------------------- endpoints/distributerewards.go | 70 ++++++++++++++++++++++++++++++++++ utils/send.go | 56 +++++++++++++++++++++++++++ 3 files changed, 137 insertions(+), 49 deletions(-) create mode 100644 endpoints/distributerewards.go create mode 100644 utils/send.go diff --git a/endpoints/contribute.go b/endpoints/contribute.go index b10e3c4..ef8f229 100644 --- a/endpoints/contribute.go +++ b/endpoints/contribute.go @@ -6,13 +6,10 @@ import ( "net/http" "strings" - "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" ) @@ -42,56 +39,21 @@ func Contribute(resp http.ResponseWriter, req *http.Request) { return } + var result SuccessResponse source := keypair.MustParseFull(cont.PrivateKey) - sourceReq := horizonclient.AccountRequest{AccountID: source.Address()} - var sourceAcct horizon.Account - sourceAcct, err = client.SignetClient.AccountDetail(sourceReq) - if err != nil { - log.Error().Err(err).Msg("Could not get account details from Horizon SignetClient") - return - } - - tx, err := txnbuild.NewTransaction( - txnbuild.TransactionParams{ - SourceAccount: &sourceAcct, - IncrementSequenceNum: true, - Operations: []txnbuild.Operation{ - &txnbuild.Payment{ - Destination: fund.FundWallet, - Amount: fmt.Sprintf("%f", cont.Amount), - Asset: txnbuild.NativeAsset{}, - SourceAccount: source.Address(), - }, - }, - BaseFee: txnbuild.MinBaseFee, - Memo: txnbuild.Memo(txnbuild.MemoText(fund.Memo)), - Preconditions: txnbuild.Preconditions{ - TimeBounds: txnbuild.NewTimeout(15), - }, - }) - if err != nil { - log.Error().Err(err).Msg("Could not create contribution transaction") - return - } - - tx, err = tx.Sign(network.TestNetworkPassphrase, source) - if err != nil { - log.Error().Err(err).Msg("Could not sign contribution transaction") - return - } - - var response horizon.Transaction - response, err = client.SignetClient.SubmitTransaction(tx) + result.Success, err = utils.SendAsset(source, txnbuild.Memo(txnbuild.MemoText(fund.Memo)), []txnbuild.Operation{ + &txnbuild.Payment{ + Destination: fund.FundWallet, + Amount: fmt.Sprintf("%f", cont.Amount), + Asset: txnbuild.NativeAsset{}, + SourceAccount: source.Address(), + }, + }) if err != nil { - log.Error().Err(err).Msg("Could not submit contribution transaction") + log.Error().Err(err).Msg("Could not send asset in contribution") return } - log.Info().Msg(fmt.Sprintf("Successful Transaction: { Ledger: %d, Hash: %s }", response.Ledger, response.Hash)) - - var result SuccessResponse - result.Success = response.Successful && err == nil - err = json.NewEncoder(resp).Encode(&result) if err != nil { log.Error().Err(err).Msg("Could not create response for new contribution") diff --git a/endpoints/distributerewards.go b/endpoints/distributerewards.go new file mode 100644 index 0000000..bc6da61 --- /dev/null +++ b/endpoints/distributerewards.go @@ -0,0 +1,70 @@ +package endpoints + +import ( + "encoding/json" + "fmt" + "net/http" + + . "github.com/imosed/signet/data" + "github.com/imosed/signet/utils" + "github.com/stellar/go/keypair" + "github.com/stellar/go/txnbuild" +) + +type RewardDistributionInfo struct { + Destination string `json:"destination"` + Amount float64 `json:"amount"` +} + +type DistributeRewardsRequest struct { + RewardFundID uint `json:"rewardFundID"` + Payments []RewardDistributionInfo `json:"payments"` + Distribute bool `json:"distribute"` +} + +func DistributeRewards(w http.ResponseWriter, r *http.Request) { + var req DistributeRewardsRequest + err := json.NewDecoder(r.Body).Decode(&req) + if err != nil { + panic("Could not decode body") + } + + var fund RewardFund + Db.Table("reward_funds").Where("id = ?", req.RewardFundID).Scan(&fund) + + var resp SuccessResponse + resp.Success = false + + if req.Distribute { + source := keypair.MustParseFull(fund.FundSecret) + resp.Success, err = utils.SendAsset( + source, + nil, + constructOperations( + source, + txnbuild.CreditAsset{ + Code: fund.Asset, + Issuer: fund.IssuerWallet, + }, + req.Payments), + ) + } + + err = json.NewEncoder(w).Encode(resp) + if err != nil { + panic("Could not deliver response") + } +} + +func constructOperations(sourceAccount *keypair.Full, asset txnbuild.CreditAsset, payments []RewardDistributionInfo) []txnbuild.Operation { + var operations []txnbuild.Operation + for _, payment := range payments { + operations = append(operations, &txnbuild.Payment{ + Destination: payment.Destination, + Amount: fmt.Sprintf("%f", payment.Amount), + Asset: asset, + SourceAccount: sourceAccount.Address(), + }) + } + return operations +} diff --git a/utils/send.go b/utils/send.go new file mode 100644 index 0000000..f43af42 --- /dev/null +++ b/utils/send.go @@ -0,0 +1,56 @@ +package utils + +import ( + "fmt" + + "github.com/imosed/signet/client" + "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" +) + +func SendAsset(from *keypair.Full, memo txnbuild.Memo, operations []txnbuild.Operation) (bool, error) { + var err error + + source := keypair.MustParseFull(from.Seed()) + sourceReq := horizonclient.AccountRequest{AccountID: source.Address()} + var sourceAcct horizon.Account + sourceAcct, err = client.SignetClient.AccountDetail(sourceReq) + if err != nil { + return false, err + } + + tx, err := txnbuild.NewTransaction( + txnbuild.TransactionParams{ + SourceAccount: &sourceAcct, + IncrementSequenceNum: true, + Operations: operations, + BaseFee: txnbuild.MinBaseFee, + Memo: memo, + Preconditions: txnbuild.Preconditions{ + TimeBounds: txnbuild.NewTimeout(15), + }, + }) + if err != nil { + + return false, err + } + + tx, err = tx.Sign(network.TestNetworkPassphrase, source) + if err != nil { + return false, err + } + + var response horizon.Transaction + response, err = client.SignetClient.SubmitTransaction(tx) + if err != nil { + return false, err + } + + log.Info().Msg(fmt.Sprintf("Successful Transaction: { Ledger: %d, Hash: %s }", response.Ledger, response.Hash)) + + return true, nil +}