139 lines
4.0 KiB
Go
139 lines
4.0 KiB
Go
|
|
package admin
|
||
|
|
|
||
|
|
import (
|
||
|
|
"net/http"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
"github.com/gin-gonic/gin"
|
||
|
|
"github.com/gothinkster/golang-gin-realworld-example-app/common"
|
||
|
|
"github.com/gothinkster/golang-gin-realworld-example-app/models"
|
||
|
|
)
|
||
|
|
|
||
|
|
// ContractEntry is the contract address entry returned to the frontend.
|
||
|
|
type ContractEntry struct {
|
||
|
|
Name string `json:"name"`
|
||
|
|
ChainID int `json:"chain_id"`
|
||
|
|
Address string `json:"address"`
|
||
|
|
}
|
||
|
|
|
||
|
|
// GetContracts is a public endpoint that returns all active contract addresses.
|
||
|
|
// Merges infrastructure contracts (system_contracts) and token contracts (assets).
|
||
|
|
func GetContracts(c *gin.Context) {
|
||
|
|
db := common.GetDB()
|
||
|
|
|
||
|
|
// Infrastructure contracts from system_contracts
|
||
|
|
var sysContracts []models.SystemContract
|
||
|
|
db.Where("is_active = ?", true).Find(&sysContracts)
|
||
|
|
|
||
|
|
// Token contracts from assets
|
||
|
|
var assets []models.Asset
|
||
|
|
db.Where("is_active = ? AND contract_address != ''", true).Find(&assets)
|
||
|
|
|
||
|
|
entries := make([]ContractEntry, 0, len(sysContracts)+len(assets))
|
||
|
|
for _, sc := range sysContracts {
|
||
|
|
if sc.Address != "" {
|
||
|
|
entries = append(entries, ContractEntry{Name: sc.Name, ChainID: sc.ChainID, Address: sc.Address})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
for _, a := range assets {
|
||
|
|
entries = append(entries, ContractEntry{Name: a.AssetCode, ChainID: a.ChainID, Address: a.ContractAddress})
|
||
|
|
}
|
||
|
|
|
||
|
|
c.JSON(http.StatusOK, gin.H{"contracts": entries})
|
||
|
|
}
|
||
|
|
|
||
|
|
// --- Admin CRUD for system_contracts ---
|
||
|
|
|
||
|
|
func ListSystemContracts(c *gin.Context) {
|
||
|
|
db := common.GetDB()
|
||
|
|
p := ParsePagination(c)
|
||
|
|
|
||
|
|
query := db.Model(&models.SystemContract{})
|
||
|
|
if v := c.Query("name"); v != "" {
|
||
|
|
query = query.Where("name LIKE ?", "%"+v+"%")
|
||
|
|
}
|
||
|
|
if v := c.Query("chain_id"); v != "" {
|
||
|
|
query = query.Where("chain_id = ?", v)
|
||
|
|
}
|
||
|
|
if v := c.Query("is_active"); v != "" {
|
||
|
|
query = query.Where("is_active = ?", v == "true")
|
||
|
|
}
|
||
|
|
|
||
|
|
var total int64
|
||
|
|
query.Count(&total)
|
||
|
|
|
||
|
|
var items []models.SystemContract
|
||
|
|
if err := query.Order("chain_id ASC, name ASC").Offset(p.Offset()).Limit(p.PageSize).Find(&items).Error; err != nil {
|
||
|
|
Fail(c, http.StatusInternalServerError, "Failed to fetch system contracts")
|
||
|
|
return
|
||
|
|
}
|
||
|
|
OKList(c, items, total)
|
||
|
|
}
|
||
|
|
|
||
|
|
func GetSystemContract(c *gin.Context) {
|
||
|
|
db := common.GetDB()
|
||
|
|
var item models.SystemContract
|
||
|
|
if err := db.First(&item, c.Param("id")).Error; err != nil {
|
||
|
|
Fail(c, http.StatusNotFound, "System contract not found")
|
||
|
|
return
|
||
|
|
}
|
||
|
|
OK(c, item)
|
||
|
|
}
|
||
|
|
|
||
|
|
func CreateSystemContract(c *gin.Context) {
|
||
|
|
db := common.GetDB()
|
||
|
|
var item models.SystemContract
|
||
|
|
if err := c.ShouldBindJSON(&item); err != nil {
|
||
|
|
Fail(c, http.StatusBadRequest, err.Error())
|
||
|
|
return
|
||
|
|
}
|
||
|
|
item.ID = 0
|
||
|
|
now := time.Now()
|
||
|
|
item.CreatedAt = now
|
||
|
|
item.UpdatedAt = now
|
||
|
|
if err := db.Create(&item).Error; err != nil {
|
||
|
|
Fail(c, http.StatusInternalServerError, err.Error())
|
||
|
|
return
|
||
|
|
}
|
||
|
|
LogOp(c, "create", "system_contract", "create_system_contract", &item.ID, item)
|
||
|
|
OK(c, item)
|
||
|
|
}
|
||
|
|
|
||
|
|
func UpdateSystemContract(c *gin.Context) {
|
||
|
|
db := common.GetDB()
|
||
|
|
var existing models.SystemContract
|
||
|
|
if err := db.First(&existing, c.Param("id")).Error; err != nil {
|
||
|
|
Fail(c, http.StatusNotFound, "System contract not found")
|
||
|
|
return
|
||
|
|
}
|
||
|
|
var item models.SystemContract
|
||
|
|
if err := c.ShouldBindJSON(&item); err != nil {
|
||
|
|
Fail(c, http.StatusBadRequest, err.Error())
|
||
|
|
return
|
||
|
|
}
|
||
|
|
item.ID = existing.ID
|
||
|
|
item.CreatedAt = existing.CreatedAt
|
||
|
|
item.UpdatedAt = time.Now()
|
||
|
|
if err := db.Save(&item).Error; err != nil {
|
||
|
|
Fail(c, http.StatusInternalServerError, err.Error())
|
||
|
|
return
|
||
|
|
}
|
||
|
|
LogOp(c, "update", "system_contract", "update_system_contract", &item.ID, item)
|
||
|
|
OK(c, item)
|
||
|
|
}
|
||
|
|
|
||
|
|
func DeleteSystemContract(c *gin.Context) {
|
||
|
|
db := common.GetDB()
|
||
|
|
var item models.SystemContract
|
||
|
|
if err := db.First(&item, c.Param("id")).Error; err != nil {
|
||
|
|
Fail(c, http.StatusNotFound, "System contract not found")
|
||
|
|
return
|
||
|
|
}
|
||
|
|
if err := db.Delete(&item).Error; err != nil {
|
||
|
|
Fail(c, http.StatusInternalServerError, err.Error())
|
||
|
|
return
|
||
|
|
}
|
||
|
|
LogOp(c, "delete", "system_contract", "delete_system_contract", &item.ID, nil)
|
||
|
|
OK(c, gin.H{"message": "deleted"})
|
||
|
|
}
|