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