Skip to content

Commit

Permalink
Start factions onchain full flow & likes integration
Browse files Browse the repository at this point in the history
  • Loading branch information
b-j-roberts committed Jun 22, 2024
1 parent f457eca commit 822d5ae
Show file tree
Hide file tree
Showing 36 changed files with 2,262 additions and 711 deletions.
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,8 @@ init-infra-prod:
@echo "Initializing infra..."
curl https://api.art-peace.net/init-canvas -X POST
curl https://api.art-peace.net/init-quests -X POST -d "@configs/production-quests.config.json"

update-frontend-contracts:
cat onchain/target/dev/art_peace_ArtPeace.contract_class.json| jq -r '.abi' > frontend/src/contracts/art_peace.abi.json
cat onchain/target/dev/art_peace_CanvasNFT.contract_class.json| jq -r '.abi' > frontend/src/contracts/canvas_nft.abi.json
cat onchain/target/dev/art_peace_UsernameStore.contract_class.json| jq -r '.abi' > frontend/src/contracts/username_store.abi.json
4 changes: 4 additions & 0 deletions backend/config/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ type BackendScriptsConfig struct {
AddTemplateDevnet string `json:"add_template_devnet"`
ClaimTodayQuestDevnet string `json:"claim_today_quest_devnet"`
MintNFTDevnet string `json:"mint_nft_devnet"`
LikeNFTDevnet string `json:"like_nft_devnet"`
UnlikeNFTDevnet string `json:"unlike_nft_devnet"`
VoteColorDevnet string `json:"vote_color_devnet"`
NewUsernameDevnet string `json:"new_username_devnet"`
ChangeUsernameDevnet string `json:"change_username_devnet"`
Expand Down Expand Up @@ -48,6 +50,8 @@ var DefaultBackendConfig = BackendConfig{
AddTemplateDevnet: "../scripts/add_template.sh",
ClaimTodayQuestDevnet: "../scripts/claim_today_quest.sh",
MintNFTDevnet: "../scripts/mint_nft.sh",
LikeNFTDevnet: "../scripts/like_nft.sh",
UnlikeNFTDevnet: "../scripts/unlike_nft.sh",
VoteColorDevnet: "../scripts/vote_color.sh",
NewUsernameDevnet: "../scripts/new_username.sh",
ChangeUsernameDevnet: "../scripts/change_username.sh",
Expand Down
20 changes: 9 additions & 11 deletions backend/routes/factions.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,8 @@ func InitFactionRoutes() {

type FactionUserData struct {
FactionId int `json:"factionId"`
MemberId int `json:"memberId"`
Allocation int `json:"allocation"`
Name string `json:"name"`
Pool int `json:"pool"`
Members int `json:"members"`
Icon string `json:"icon"`
Telegram string `json:"telegram"`
Expand All @@ -39,7 +37,6 @@ type FactionUserData struct {
type FactionData struct {
FactionId int `json:"factionId"`
Name string `json:"name"`
Pool int `json:"pool"`
Members int `json:"members"`
IsMember bool `json:"isMember"`
Icon string `json:"icon"`
Expand Down Expand Up @@ -156,9 +153,9 @@ func getMyFactions(w http.ResponseWriter, r *http.Request) {
// TODO: Paginate and accumulate the allocations for each faction

query := `
SELECT m.faction_id, m.member_id, m.allocation, f.name, f.pixel_pool as pool, COALESCE((SELECT COUNT(*) FROM factionmembersinfo WHERE faction_id = m.faction_id), 0) as members, COALESCE(icon, '') as icon, COALESCE(telegram, '') as telegram, COALESCE(twitter, '') as twitter, COALESCE(github, '') as github, COALESCE(site, '') as site
SELECT m.faction_id, f.allocation, f.name, COALESCE((SELECT COUNT(*) FROM factionmembersinfo WHERE faction_id = m.faction_id), 0) as members, COALESCE(icon, '') as icon, COALESCE(telegram, '') as telegram, COALESCE(twitter, '') as twitter, COALESCE(github, '') as github, COALESCE(site, '') as site
FROM factionmembersinfo m
LEFT JOIN factions f ON m.faction_id = f.key - 1
LEFT JOIN factions f ON m.faction_id = f.faction_id
LEFT JOIN FactionLinks l ON m.faction_id = l.faction_id
WHERE m.user_address = $1
ORDER BY m.faction_id
Expand Down Expand Up @@ -191,12 +188,12 @@ func getFactions(w http.ResponseWriter, r *http.Request) {
offset := (page - 1) * pageLength

query := `
SELECT key - 1 as faction_id, name, pixel_pool as pool, COALESCE((SELECT COUNT(*) FROM factionmembersinfo WHERE faction_id = key - 1), 0) as members,
COALESCE((SELECT COUNT(*) FROM factionmembersinfo WHERE faction_id = key - 1 AND user_address = $1), 0) > 0 as is_member,
SELECT faction_id, name, COALESCE((SELECT COUNT(*) FROM factionmembersinfo WHERE faction_id = key - 1), 0) as members,
COALESCE((SELECT COUNT(*) FROM factionmembersinfo fm WHERE f.faction_id = fm.faction_id AND user_address = $1), 0) > 0 as is_member,
COALESCE(icon, '') as icon, COALESCE(telegram, '') as telegram, COALESCE(twitter, '') as twitter, COALESCE(github, '') as github, COALESCE(site, '') as site
FROM factions
LEFT JOIN FactionLinks ON key - 1 = faction_id
ORDER BY key
FROM factions f
LEFT JOIN FactionLinks ON f.faction_id = fm.faction_id
ORDER BY f.faction_id
LIMIT $2 OFFSET $3
`

Expand Down Expand Up @@ -233,10 +230,11 @@ func getFactionMembers(w http.ResponseWriter, r *http.Request) {
SELECT
FMI.user_address AS user_address,
COALESCE(U.name, '') AS username,
SUM(FMI.allocation) AS total_allocation
F.allocation AS total_allocation
FROM FactionMembersInfo FMI
LEFT JOIN Users U ON FMI.user_address = U.address
WHERE FMI.faction_id = $1
LEFT JOIN Factions F ON F.faction_id = FMI.faction_id
GROUP BY FMI.user_address, U.name
ORDER BY total_allocation DESC
LIMIT $2 OFFSET $3;
Expand Down
183 changes: 156 additions & 27 deletions backend/routes/indexer/faction.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,18 @@ func processFactionCreatedEvent(event IndexerEvent) {
factionIdHex := event.Event.Keys[1]
nameHex := event.Event.Data[0][2:] // Remove 0x prefix
leader := event.Event.Data[1][2:] // Remove 0x prefix
poolHex := event.Event.Data[2]
membersCountHex := event.Event.Data[3]
memberAddresses := event.Event.Data[4:]
joinableHex := event.Event.Data[2]
allocationHex := event.Event.Data[3]

factionId, err := strconv.ParseInt(factionIdHex, 0, 64)
if err != nil {
PrintIndexerError("processFactionCreatedEvent", "Failed to parse factionId", factionIdHex, nameHex, leader, poolHex, membersCountHex, memberAddresses)
PrintIndexerError("processFactionCreatedEvent", "Failed to parse factionId", factionIdHex, nameHex, leader, joinableHex, allocationHex)
return
}

decodedName, err := hex.DecodeString(nameHex)
if err != nil {
PrintIndexerError("processFactionCreatedEvent", "Failed to decode name", factionIdHex, nameHex, leader, poolHex, membersCountHex, memberAddresses)
PrintIndexerError("processFactionCreatedEvent", "Failed to decode name", factionIdHex, nameHex, leader, joinableHex, allocationHex)
return
}
// Trim off 0s at the start
Expand All @@ -39,34 +38,24 @@ func processFactionCreatedEvent(event IndexerEvent) {
}
name := string(trimmedName)

pool, err := strconv.ParseInt(poolHex, 0, 64)
joinable, err := strconv.ParseBool(joinableHex)
if err != nil {
PrintIndexerError("processFactionCreatedEvent", "Failed to parse pool", factionIdHex, nameHex, leader, poolHex, membersCountHex, memberAddresses)
PrintIndexerError("processFactionCreatedEvent", "Failed to parse joinable", factionIdHex, nameHex, leader, joinableHex, allocationHex)
return
}

membersCount, err := strconv.ParseInt(membersCountHex, 0, 64)
allocation, err := strconv.ParseInt(allocationHex, 0, 64)
if err != nil {
PrintIndexerError("processFactionCreatedEvent", "Failed to parse membersCount", factionIdHex, nameHex, leader, poolHex, membersCountHex, memberAddresses)
PrintIndexerError("processFactionCreatedEvent", "Failed to parse allocation", factionIdHex, nameHex, leader, joinableHex, allocationHex)
return
}
allocation := pool / membersCount

// Add faction info into postgres
_, err = core.ArtPeaceBackend.Databases.Postgres.Exec(context.Background(), "INSERT INTO Factions (name, leader, pixel_pool) VALUES ($1, $2, $3)", name, leader, pool)
_, err = core.ArtPeaceBackend.Databases.Postgres.Exec(context.Background(), "INSERT INTO Factions (faction_id, name, leader, joinable, allocation) VALUES ($1, $2, $3, $4, $5)", factionId, name, leader, joinable, allocation)
if err != nil {
PrintIndexerError("processFactionCreatedEvent", "Failed to insert faction into postgres", factionIdHex, nameHex, leader, poolHex, membersCountHex, memberAddresses)
PrintIndexerError("processFactionCreatedEvent", "Failed to insert faction into postgres", factionIdHex, nameHex, leader, joinableHex, allocationHex)
return
}

// Add members info into postgres
for i, memberAddress := range memberAddresses {
_, err = core.ArtPeaceBackend.Databases.Postgres.Exec(context.Background(), "INSERT INTO FactionMembersInfo (faction_id, member_id, user_address, allocation, last_placed_time, member_pixels) VALUES ($1, $2, $3, $4, TO_TIMESTAMP($5), $6)", factionId, i, memberAddress[2:], allocation, 0, 0)
if err != nil {
PrintIndexerError("processFactionCreatedEvent", "Failed to insert member into postgres", factionIdHex, nameHex, leader, poolHex, membersCountHex, memberAddresses)
return
}
}
}

func revertFactionCreatedEvent(event IndexerEvent) {
Expand All @@ -83,18 +72,158 @@ func revertFactionCreatedEvent(event IndexerEvent) {
PrintIndexerError("revertFactionCreatedEvent", "Failed to delete faction from postgres", factionIdHex)
return
}
}

func processFactionJoinedEvent(event IndexerEvent) {
factionIdHex := event.Event.Keys[1]
userAddress := event.Event.Keys[2][2:] // Remove 0x prefix

factionId, err := strconv.ParseInt(factionIdHex, 0, 64)
if err != nil {
PrintIndexerError("processFactionJoinedEvent", "Failed to parse factionId", factionIdHex, userAddress)
return
}

_, err = core.ArtPeaceBackend.Databases.Postgres.Exec(context.Background(), "DELETE FROM FactionMembersInfo WHERE faction_id = $1", factionId)
_, err = core.ArtPeaceBackend.Databases.Postgres.Exec(context.Background(), "INSERT INTO FactionMembersInfo (faction_id, user_address, last_placed_time, member_pixels) VALUES ($1, $2, $3, $4)", factionId, userAddress, 0, 0)
if err != nil {
PrintIndexerError("revertFactionCreatedEvent", "Failed to delete members from postgres", factionIdHex)
PrintIndexerError("processFactionJoinedEvent", "Failed to insert faction member into postgres", factionIdHex, userAddress)
return
}
}

func processMemberReplacedEvent(event IndexerEvent) {
// TODO: Implement
func revertFactionJoinedEvent(event IndexerEvent) {
factionIdHex := event.Event.Keys[1]
userAddress := event.Event.Keys[2][2:] // Remove 0x prefix

factionId, err := strconv.ParseInt(factionIdHex, 0, 64)
if err != nil {
PrintIndexerError("revertFactionJoinedEvent", "Failed to parse factionId", factionIdHex, userAddress)
return
}

_, err = core.ArtPeaceBackend.Databases.Postgres.Exec(context.Background(), "DELETE FROM FactionMembersInfo WHERE faction_id = $1 AND user_address = $2", factionId, userAddress)
if err != nil {
PrintIndexerError("revertFactionJoinedEvent", "Failed to delete faction member from postgres", factionIdHex, userAddress)
return
}
}

func revertMemberReplacedEvent(event IndexerEvent) {
// TODO: Implement
func processFactionLeftEvent(event IndexerEvent) {
factionIdHex := event.Event.Keys[1]
userAddress := event.Event.Keys[2][2:] // Remove 0x prefix

factionId, err := strconv.ParseInt(factionIdHex, 0, 64)
if err != nil {
PrintIndexerError("processFactionLeftEvent", "Failed to parse factionId", factionIdHex, userAddress)
return
}

_, err = core.ArtPeaceBackend.Databases.Postgres.Exec(context.Background(), "DELETE FROM FactionMembersInfo WHERE faction_id = $1 AND user_address = $2", factionId, userAddress)
if err != nil {
PrintIndexerError("processFactionLeftEvent", "Failed to delete faction member from postgres", factionIdHex, userAddress)
return
}
}

func revertFactionLeftEvent(event IndexerEvent) {
factionIdHex := event.Event.Keys[1]
userAddress := event.Event.Keys[2][2:] // Remove 0x prefix

factionId, err := strconv.ParseInt(factionIdHex, 0, 64)
if err != nil {
PrintIndexerError("revertFactionLeftEvent", "Failed to parse factionId", factionIdHex, userAddress)
return
}

// TODO: Stash the last_placed_time and member_pixels in the event data
_, err = core.ArtPeaceBackend.Databases.Postgres.Exec(context.Background(), "INSERT INTO FactionMembersInfo (faction_id, user_address, last_placed_time, member_pixels) VALUES ($1, $2, $3, $4)", factionId, userAddress, 0, 0)
if err != nil {
PrintIndexerError("revertFactionLeftEvent", "Failed to insert faction member into postgres", factionIdHex, userAddress)
return
}
}

func processChainFactionCreatedEvent(event IndexerEvent) {
factionIdHex := event.Event.Keys[1]
nameHex := event.Event.Data[0][2:] // Remove 0x prefix

factionId, err := strconv.ParseInt(factionIdHex, 0, 64)
if err != nil {
PrintIndexerError("processChainFactionCreatedEvent", "Failed to parse factionId", factionIdHex, nameHex)
return
}

decodedName, err := hex.DecodeString(nameHex)
if err != nil {
PrintIndexerError("processChainFactionCreatedEvent", "Failed to decode name", factionIdHex, nameHex)
return
}
// Trim off 0s at the start
trimmedName := []byte{}
trimming := true
for _, b := range decodedName {
if b == 0 && trimming {
continue
}
trimming = false
trimmedName = append(trimmedName, b)
}
name := string(trimmedName)

// Add faction info into postgres
_, err = core.ArtPeaceBackend.Databases.Postgres.Exec(context.Background(), "INSERT INTO ChainFactions (faction_id, name) VALUES ($1, $2)", factionId, name)
if err != nil {
PrintIndexerError("processChainFactionCreatedEvent", "Failed to insert faction into postgres", factionIdHex, nameHex)
return
}
}

func revertChainFactionCreatedEvent(event IndexerEvent) {
factionIdHex := event.Event.Keys[1]

factionId, err := strconv.ParseInt(factionIdHex, 0, 64)
if err != nil {
PrintIndexerError("revertChainFactionCreatedEvent", "Failed to parse factionId", factionIdHex)
return
}

_, err = core.ArtPeaceBackend.Databases.Postgres.Exec(context.Background(), "DELETE FROM ChainFactions WHERE faction_id = $1", factionId)
if err != nil {
PrintIndexerError("revertChainFactionCreatedEvent", "Failed to delete faction from postgres", factionIdHex)
return
}
}

func processChainFactionJoinedEvent(event IndexerEvent) {
factionIdHex := event.Event.Keys[1]
userAddress := event.Event.Keys[2][2:] // Remove 0x prefix

factionId, err := strconv.ParseInt(factionIdHex, 0, 64)
if err != nil {
PrintIndexerError("processChainFactionJoinedEvent", "Failed to parse factionId", factionIdHex, userAddress)
return
}

_, err = core.ArtPeaceBackend.Databases.Postgres.Exec(context.Background(), "INSERT INTO ChainFactionMembersInfo (faction_id, user_address, last_placed_time, members_pixels) VALUES ($1, $2, $3, $4)", factionId, userAddress, 0, 0)
if err != nil {
PrintIndexerError("processChainFactionJoinedEvent", "Failed to insert faction member into postgres", factionIdHex, userAddress)
return
}
}

func revertChainFactionJoinedEvent(event IndexerEvent) {
factionIdHex := event.Event.Keys[1]
userAddress := event.Event.Keys[2][2:] // Remove 0x prefix

factionId, err := strconv.ParseInt(factionIdHex, 0, 64)
if err != nil {
PrintIndexerError("revertChainFactionJoinedEvent", "Failed to parse factionId", factionIdHex, userAddress)
return
}

_, err = core.ArtPeaceBackend.Databases.Postgres.Exec(context.Background(), "DELETE FROM ChainFactionMembersInfo WHERE faction_id = $1 AND user_address = $2", factionId, userAddress)
if err != nil {
PrintIndexerError("revertChainFactionJoinedEvent", "Failed to delete faction member from postgres", factionIdHex, userAddress)
return
}
}
Loading

0 comments on commit 822d5ae

Please sign in to comment.