package utils import ( "fmt" "math" "github.com/imosed/signet/client" . "github.com/imosed/signet/data" "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" ) func getFraction(price float64) xdr.Price { factor := math.Pow(10, 8) return xdr.Price{N: xdr.Int32(price * factor), D: xdr.Int32(factor)} } func SubmitGroupFund(fundID uint) (bool, error) { var fund RewardFund Db.Preload(clause.Associations).Find(&fund, fundID) var err error 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 := FindOffer(offerReq, &fund); !ok { return false, err } 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", 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: getFraction(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 { tr.Rollback() return false, err } tx, err = tx.Sign(network.TestNetworkPassphrase, source) if err != nil { tr.Rollback() return false, err } _, err = client.SignetClient.SubmitTransaction(tx) if err != nil { tr.Rollback() return false, err } tr.Commit() return true, nil } func sumContributions(contributions []Contribution) float64 { var total float64 = 0 for _, contribution := range contributions { if !contribution.Submitted { total += contribution.Amount } } return total }