| @@ -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") | |||
| @@ -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 | |||
| } | |||
| @@ -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 | |||
| } | |||