@@ -17,11 +17,11 @@ type RewardFund struct { | |||
gorm.Model | |||
Asset string `json:"asset"` | |||
FundWallet string `json:"fundWallet"` | |||
FundSecret string `json:"fundSecret"` | |||
SellingWallet string `json:"sellingWallet"` | |||
IssuerWallet string `json:"issuerWallet"` | |||
Memo string `json:"memo"` | |||
Price float64 `json:"price"` | |||
AmountGoal float64 `gorm:"type:decimal(19,7)" json:"amountGoal"` | |||
AmountAvailable float64 `gorm:"type:decimal(19,7)" json:"amountAvailable"` | |||
MinContribution float64 `gorm:"type:decimal(19,7)" json:"minContribution"` | |||
Contributions []Contribution `json:"contributions"` | |||
Title string `gorm:"type:varchar(50)" json:"title"` | |||
@@ -28,9 +28,9 @@ func Contribute(resp http.ResponseWriter, req *http.Request) { | |||
var fund RewardFund | |||
Db.Table("reward_funds").Select("id", "fund_wallet", "memo", "min_contribution").First(&fund, cont.RewardFund) | |||
Db.Table("reward_funds").Select("id", "deleted_at", "fund_wallet", "memo", "min_contribution").First(&fund, cont.RewardFund) | |||
if cont.Amount < fund.MinContribution || !strings.HasPrefix(cont.PrivateKey, "S") { | |||
if cont.Amount < fund.MinContribution || !strings.HasPrefix(cont.PrivateKey, "S") || !fund.DeletedAt.Time.IsZero() { | |||
err = json.NewEncoder(resp).Encode(&SuccessResponse{Success: false}) | |||
if err != nil { | |||
panic("Could not deliver unsuccessful contribution response") | |||
@@ -40,7 +40,9 @@ func ContributorStream(resp http.ResponseWriter, req *http.Request) { | |||
} | |||
} | |||
func InitializeContributionStream() { | |||
var cancellations []context.CancelFunc | |||
func InitializeContributionStreams() { | |||
var err error | |||
var wallets []struct { | |||
@@ -67,7 +69,9 @@ func InitializeContributionStream() { | |||
if tx.Memo == "" { | |||
return | |||
} | |||
Db.Table("reward_funds").Select("id").Where("memo = ? and fund_wallet = ?", tx.Memo, payment.To).First(&fund) | |||
Db.Table("reward_funds").Where("memo = ? and fund_wallet = ?", tx.Memo, payment.To).First(&fund) | |||
newAmt := fund.AmountAvailable - amt | |||
Db.Model(&RewardFund{}).Where("id = ?", fund.ID).Update("amount_available", newAmt) | |||
contribution := Contribution{ | |||
Model: gorm.Model{ | |||
@@ -97,7 +101,8 @@ func InitializeContributionStream() { | |||
IncludeFailed: false, | |||
} | |||
opReq.SetOperationsEndpoint() | |||
ctx, _ := context.WithCancel(context.Background()) // TODO: what is cancelFunc? | |||
ctx, cancellation := context.WithCancel(context.Background()) | |||
cancellations = append(cancellations, cancellation) | |||
err = client.StreamOperations(ctx, opReq, contributionUpdateHandler) | |||
if err != nil { | |||
panic(err.Error()) | |||
@@ -28,10 +28,11 @@ func CreateRewardFund(resp http.ResponseWriter, req *http.Request) { | |||
rewardFund := RewardFund{ | |||
Asset: fund.Asset, | |||
FundWallet: fund.FundWallet, | |||
SellingWallet: fund.SellingWallet, | |||
IssuerWallet: fund.IssuerWallet, | |||
Memo: fund.Memo, | |||
Price: 0, | |||
AmountGoal: fund.AmountGoal, | |||
AmountAvailable: 0, | |||
MinContribution: fund.MinContribution, | |||
Title: fund.Title, | |||
Description: fund.Description, | |||
@@ -39,24 +40,33 @@ func CreateRewardFund(resp http.ResponseWriter, req *http.Request) { | |||
} | |||
offerReq := horizonclient.OfferRequest{ | |||
Seller: rewardFund.IssuerWallet, | |||
Seller: rewardFund.SellingWallet, | |||
Selling: fmt.Sprintf("%s:%s", rewardFund.Asset, rewardFund.IssuerWallet), | |||
Buying: fmt.Sprintf("XLM:%s", rewardFund.IssuerWallet), | |||
Order: horizonclient.OrderDesc, | |||
} | |||
url, _ := offerReq.BuildURL() | |||
fmt.Println(url) | |||
op, err := client.Offers(offerReq) | |||
if err != nil { | |||
panic("Could not get offers") | |||
} | |||
offers := op.Embedded.Records | |||
var price float64 | |||
var amt float64 | |||
if len(offers) == 1 { | |||
price, err = strconv.ParseFloat(op.Embedded.Records[0].Price, 64) | |||
if err != nil { | |||
panic("Could not parse price to float") | |||
} | |||
amt, err = strconv.ParseFloat(op.Embedded.Records[0].Amount, 64) | |||
if err != nil { | |||
panic("Could not parse amount to float") | |||
} | |||
rewardFund.Price = price | |||
} else { | |||
rewardFund.AmountAvailable = amt | |||
} else if len(offers) > 1 { | |||
var maxOffers float64 = 0 | |||
var correctOffer horizon.Offer | |||
for _, o := range op.Embedded.Records { | |||
@@ -74,6 +84,15 @@ func CreateRewardFund(resp http.ResponseWriter, req *http.Request) { | |||
panic("Could not parse price to float") | |||
} | |||
rewardFund.Price = price | |||
amt, err = strconv.ParseFloat(correctOffer.Amount, 64) | |||
if err != nil { | |||
panic("Could not parse amount to float") | |||
} | |||
rewardFund.AmountAvailable = amt | |||
} else { | |||
err = json.NewEncoder(resp).Encode(&SuccessResponse{Success: false}) | |||
return | |||
} | |||
var claims *auth.Claims | |||
@@ -85,6 +104,11 @@ func CreateRewardFund(resp http.ResponseWriter, req *http.Request) { | |||
if claims.Privileges <= Admin { | |||
Db.Create(&rewardFund) | |||
for _, cancel := range cancellations { | |||
cancel() | |||
} | |||
go InitializeContributionStreams() | |||
for _, bonus := range fund.Bonuses { | |||
bonus.RewardFundID = rewardFund.ID | |||
bonuses = append(bonuses, bonus) | |||
@@ -62,7 +62,7 @@ func GetRewardFund(resp http.ResponseWriter, req *http.Request) { | |||
IssuerWallet: fund.IssuerWallet, | |||
Memo: fund.Memo, | |||
Price: fund.Price, | |||
AmountGoal: fund.AmountGoal, | |||
AmountAvailable: fund.AmountAvailable, | |||
MinContribution: fund.MinContribution, | |||
Title: fund.Title, | |||
Description: fund.Description, | |||
@@ -144,7 +144,7 @@ type FundInfo struct { | |||
IssuerWallet string `json:"issuerWallet"` | |||
Memo string `json:"memo"` | |||
Price float64 `json:"price"` | |||
AmountGoal float64 `json:"amountGoal"` | |||
AmountAvailable float64 `json:"amountAvailable"` | |||
MinContribution float64 `json:"minContribution"` | |||
Title string `json:"title"` | |||
Description string `json:"description"` | |||
@@ -18,7 +18,7 @@ func GetRewardFunds(w http.ResponseWriter, r *http.Request) { | |||
var rewardFunds []RewardFund | |||
Db.Table("reward_funds").Count(&resp.Total) | |||
Db.Preload(clause.Associations).Table("reward_funds"). | |||
Select("id", "created_at", "asset", "fund_wallet", "issuer_wallet", "memo", "amount_goal", "min_contribution", "close_time", "title"). | |||
Select("id", "created_at", "asset", "fund_wallet", "issuer_wallet", "memo", "min_contribution", "amount_available", "title"). | |||
Order("created_at desc"). | |||
Find(&rewardFunds) | |||
@@ -30,7 +30,7 @@ func GetRewardFunds(w http.ResponseWriter, r *http.Request) { | |||
FundWallet: f.FundWallet, | |||
IssuerWallet: f.IssuerWallet, | |||
Memo: f.Memo, | |||
AmountGoal: f.AmountGoal, | |||
AmountAvailable: f.AmountAvailable, | |||
MinContribution: f.MinContribution, | |||
Title: f.Title, | |||
Description: f.Description, | |||
@@ -135,7 +135,7 @@ func Register(w http.ResponseWriter, r *http.Request) { | |||
panic("Could not determine if user is authenticated") | |||
} | |||
if claims.Privileges <= AdminPlus || noUsersRegistered() { | |||
if noUsersRegistered() || claims.Privileges <= AdminPlus { | |||
hash, err := GenerateHash(req.Password, &Params{ | |||
Memory: uint32(viper.GetInt("hashing.memory")), | |||
Iterations: uint32(viper.GetInt("hashing.iterations")), | |||
@@ -0,0 +1,20 @@ | |||
package endpoints | |||
import ( | |||
"encoding/json" | |||
. "github.com/imosed/signet/data" | |||
"net/http" | |||
) | |||
func UsersExist(w http.ResponseWriter, r *http.Request) { | |||
var numUsers int64 | |||
Db.Table("users").Count(&numUsers) | |||
var resp SuccessResponse | |||
resp.Success = numUsers > 0 | |||
err := json.NewEncoder(w).Encode(resp) | |||
if err != nil { | |||
panic("Could not deliver response") | |||
} | |||
} |
@@ -25,7 +25,7 @@ func main() { | |||
data.InitializeDatabase() | |||
go endpoints.InitializeContributionStream() | |||
go endpoints.InitializeContributionStreams() | |||
router := mux.NewRouter() | |||
router.HandleFunc("/GetRewardFunds", endpoints.GetRewardFunds) | |||
@@ -39,6 +39,7 @@ func main() { | |||
router.HandleFunc("/Login", endpoints.Login) | |||
router.HandleFunc("/Register", endpoints.Register) | |||
router.HandleFunc("/EscalatePrivileges", endpoints.EscalatePrivileges) | |||
router.HandleFunc("/UsersExist", endpoints.UsersExist) | |||
port := viper.GetInt("app.port") | |||
fmt.Printf("Running on port %d...\n", port) | |||