@@ -6,13 +6,10 @@ import ( | |||||
"net/http" | "net/http" | ||||
"strings" | "strings" | ||||
"github.com/imosed/signet/client" | |||||
. "github.com/imosed/signet/data" | . "github.com/imosed/signet/data" | ||||
"github.com/imosed/signet/utils" | |||||
"github.com/rs/zerolog/log" | "github.com/rs/zerolog/log" | ||||
"github.com/stellar/go/clients/horizonclient" | |||||
"github.com/stellar/go/keypair" | "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/txnbuild" | ||||
) | ) | ||||
@@ -42,56 +39,21 @@ func Contribute(resp http.ResponseWriter, req *http.Request) { | |||||
return | return | ||||
} | } | ||||
var result SuccessResponse | |||||
source := keypair.MustParseFull(cont.PrivateKey) | 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 { | 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 | 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) | err = json.NewEncoder(resp).Encode(&result) | ||||
if err != nil { | if err != nil { | ||||
log.Error().Err(err).Msg("Could not create response for new contribution") | 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 | |||||
} |