home.gno
10.30 Kb ยท 282 lines
1package home
2
3import (
4 "chain"
5 "chain/banker"
6 "chain/runtime"
7 "strings"
8
9 "gno.land/p/nt/ufmt"
10 "gno.land/r/nemanya/config"
11)
12
13type SocialLink struct {
14 URL string
15 Text string
16}
17
18type Sponsor struct {
19 Address address
20 Amount chain.Coins
21}
22
23type Project struct {
24 Name string
25 Description string
26 URL string
27 ImageURL string
28 Sponsors map[address]Sponsor
29}
30
31var (
32 textArt string
33 aboutMe string
34 sponsorInfo string
35 socialLinks map[string]SocialLink
36 gnoProjects map[string]Project
37 otherProjects map[string]Project
38 totalDonations chain.Coins
39)
40
41func init() {
42 textArt = renderTextArt()
43 aboutMe = "I am a student of IT at Faculty of Sciences in Novi Sad, Serbia. My background is mainly in web and low-level programming, but since Web3 Bootcamp at Petnica this year I've been actively learning about blockchain and adjacent technologies. I am excited about contributing to the gno.land ecosystem and learning from the community.\n\n"
44 sponsorInfo = "You can sponsor a project by sending GNOT to this address. Your sponsorship will be displayed on the project page. Thank you for supporting the development of gno.land!\n\n"
45
46 socialLinks = map[string]SocialLink{
47 "GitHub": {URL: "https://github.com/Nemanya8", Text: "Explore my repositories and open-source contributions."},
48 "LinkedIn": {URL: "https://www.linkedin.com/in/nemanjamatic/", Text: "Connect with me professionally."},
49 "Email Me": {URL: "mailto:matic.nemanya@gmail.com", Text: "Reach out for collaboration or inquiries."},
50 }
51
52 gnoProjects = make(map[string]Project)
53 otherProjects = make(map[string]Project)
54
55 gnoProjects["Liberty Bridge"] = Project{
56 Name: "Liberty Bridge",
57 Description: "Liberty Bridge was my first Web3 project, developed as part of the Web3 Bootcamp at Petnica. This project served as a centralized bridge between Ethereum and gno.land, enabling seamless asset transfers and fostering interoperability between the two ecosystems.\n\n The primary objective of Liberty Bridge was to address the challenges of connecting decentralized networks by implementing a user-friendly solution that simplified the process for users. The project incorporated mechanisms to securely transfer assets between the Ethereum and gno.land blockchains, ensuring efficiency and reliability while maintaining a centralized framework for governance and operations.\n\n Through this project, I gained hands-on knowledge of blockchain interoperability, Web3 protocols, and the intricacies of building solutions that bridge different blockchain ecosystems.\n\n",
58 URL: "https://gno.land",
59 ImageURL: "https://github.com/Milosevic02/LibertyBridge/raw/main/lb_banner.png",
60 Sponsors: make(map[address]Sponsor),
61 }
62
63 otherProjects["Incognito"] = Project{
64 Name: "Incognito",
65 Description: "Incognito is a Web3 platform built for Ethereum-based chains, designed to connect advertisers with users in a privacy-first and mutually beneficial way. Its modular architecture makes it easily expandable to other blockchains. Developed during the ETH Sofia Hackathon, it was recognized as a winning project for its innovation and impact.\n\n The platform allows advertisers to send personalized ads while sharing a portion of the marketing budget with users. It uses machine learning to match users based on wallet activity, ensuring precise targeting. User emails are stored securely on-chain and never shared, prioritizing privacy and transparency.\n\n With all campaign data stored on-chain, Incognito ensures decentralization and accountability. By rewarding users and empowering advertisers, it sets a new standard for fair and transparent blockchain-based advertising.",
66 URL: "https://github.com/Milosevic02/Incognito-ETHSofia",
67 ImageURL: "",
68 Sponsors: make(map[address]Sponsor),
69 }
70}
71
72func Render(_ string) string {
73 var sb strings.Builder
74 sb.WriteString("# Hi, I'm\n")
75 sb.WriteString(textArt)
76 sb.WriteString("---\n")
77 sb.WriteString("## About me\n")
78 sb.WriteString(aboutMe)
79 sb.WriteString(sponsorInfo)
80 sb.WriteString(ufmt.Sprintf("# Total Sponsor Donations: %s\n", totalDonations.String()))
81 sb.WriteString("---\n")
82 sb.WriteString(renderProjects(gnoProjects, "Gno Projects"))
83 sb.WriteString("---\n")
84 sb.WriteString(renderProjects(otherProjects, "Other Projects"))
85 sb.WriteString("---\n")
86 sb.WriteString(renderSocialLinks())
87
88 return sb.String()
89}
90
91func renderTextArt() string {
92 var sb strings.Builder
93 sb.WriteString("```\n")
94 sb.WriteString(" ___ ___ ___ ___ ___ ___ ___ \n")
95 sb.WriteString(" /\\__\\ /\\ \\ /\\__\\ /\\ \\ /\\__\\ |\\__\\ /\\ \\ \n")
96 sb.WriteString(" /::| | /::\\ \\ /::| | /::\\ \\ /::| | |:| | /::\\ \\ \n")
97 sb.WriteString(" /:|:| | /:/\\:\\ \\ /:|:| | /:/\\:\\ \\ /:|:| | |:| | /:/\\:\\ \\ \n")
98 sb.WriteString(" /:/|:| |__ /::\\~\\:\\ \\ /:/|:|__|__ /::\\~\\:\\ \\ /:/|:| |__ |:|__|__ /::\\~\\:\\ \\ \n")
99 sb.WriteString(" /:/ |:| /\\__\\ /:/\\:\\ \\:\\__\\ /:/ |::::\\__\\ /:/\\:\\ \\:\\__\\ /:/ |:| /\\__\\ /::::\\__\\ /:/\\:\\ \\:\\__\\\n")
100 sb.WriteString(" \\/__|:|/:/ / \\:\\~\\:\\ \\/__/ \\/__/~~/:/ / \\/__\\:\\/:/ / \\/__|:|/:/ / /:/~~/~ \\/__\\:\\/:/ / \n")
101 sb.WriteString(" |:/:/ / \\:\\ \\:\\__\\ /:/ / \\::/ / |:/:/ / /:/ / \\::/ / \n")
102 sb.WriteString(" |::/ / \\:\\ \\/__/ /:/ / /:/ / |::/ / \\/__/ /:/ / \n")
103 sb.WriteString(" /:/ / \\:\\__\\ /:/ / /:/ / /:/ / /:/ / \n")
104 sb.WriteString(" \\/__/ \\/__/ \\/__/ \\/__/ \\/__/ \\/__/ \n")
105 sb.WriteString("\n```\n")
106 return sb.String()
107}
108
109func renderSocialLinks() string {
110 var sb strings.Builder
111 sb.WriteString("## Links\n\n")
112 sb.WriteString("You can find me here:\n\n")
113 sb.WriteString(ufmt.Sprintf("- [GitHub](%s) - %s\n", socialLinks["GitHub"].URL, socialLinks["GitHub"].Text))
114 sb.WriteString(ufmt.Sprintf("- [LinkedIn](%s) - %s\n", socialLinks["LinkedIn"].URL, socialLinks["LinkedIn"].Text))
115 sb.WriteString(ufmt.Sprintf("- [Email Me](%s) - %s\n", socialLinks["Email Me"].URL, socialLinks["Email Me"].Text))
116 sb.WriteString("\n")
117 return sb.String()
118}
119
120func renderProjects(projectsMap map[string]Project, title string) string {
121 var sb strings.Builder
122 sb.WriteString(ufmt.Sprintf("## %s\n\n", title))
123 for _, project := range projectsMap {
124 if project.ImageURL != "" {
125 sb.WriteString(ufmt.Sprintf("\n\n", project.Name, project.ImageURL))
126 }
127 sb.WriteString(ufmt.Sprintf("### [%s](%s)\n\n", project.Name, project.URL))
128 sb.WriteString(project.Description + "\n\n")
129
130 if len(project.Sponsors) > 0 {
131 sb.WriteString(ufmt.Sprintf("#### %s Sponsors\n", project.Name))
132 for _, sponsor := range project.Sponsors {
133 sb.WriteString(ufmt.Sprintf("- %s: %s\n", sponsor.Address.String(), sponsor.Amount.String()))
134 }
135 sb.WriteString("\n")
136 }
137 }
138 return sb.String()
139}
140
141func UpdateLink(_ realm, name, newURL string) {
142 if !isAuthorized(runtime.PreviousRealm().Address()) {
143 panic(config.ErrUnauthorized)
144 }
145
146 if _, exists := socialLinks[name]; !exists {
147 panic("Link with the given name does not exist")
148 }
149
150 socialLinks[name] = SocialLink{
151 URL: newURL,
152 Text: socialLinks[name].Text,
153 }
154}
155
156func UpdateAboutMe(_ realm, text string) {
157 if !isAuthorized(runtime.PreviousRealm().Address()) {
158 panic(config.ErrUnauthorized)
159 }
160
161 aboutMe = text
162}
163
164func AddGnoProject(_ realm, name, description, url, imageURL string) {
165 if !isAuthorized(runtime.PreviousRealm().Address()) {
166 panic(config.ErrUnauthorized)
167 }
168 project := Project{
169 Name: name,
170 Description: description,
171 URL: url,
172 ImageURL: imageURL,
173 Sponsors: make(map[address]Sponsor),
174 }
175 gnoProjects[name] = project
176}
177
178func DeleteGnoProject(_ realm, projectName string) {
179 if !isAuthorized(runtime.PreviousRealm().Address()) {
180 panic(config.ErrUnauthorized)
181 }
182
183 if _, exists := gnoProjects[projectName]; !exists {
184 panic("Project not found")
185 }
186
187 delete(gnoProjects, projectName)
188}
189
190func AddOtherProject(_ realm, name, description, url, imageURL string) {
191 if !isAuthorized(runtime.PreviousRealm().Address()) {
192 panic(config.ErrUnauthorized)
193 }
194 project := Project{
195 Name: name,
196 Description: description,
197 URL: url,
198 ImageURL: imageURL,
199 Sponsors: make(map[address]Sponsor),
200 }
201 otherProjects[name] = project
202}
203
204func RemoveOtherProject(_ realm, projectName string) {
205 if !isAuthorized(runtime.PreviousRealm().Address()) {
206 panic(config.ErrUnauthorized)
207 }
208
209 if _, exists := otherProjects[projectName]; !exists {
210 panic("Project not found")
211 }
212
213 delete(otherProjects, projectName)
214}
215
216func isAuthorized(addr address) bool {
217 return addr == config.Address() || addr == config.Backup()
218}
219
220func SponsorGnoProject(_ realm, projectName string) {
221 address_XXX := runtime.OriginCaller()
222 amount := banker.OriginSend()
223
224 if amount.AmountOf("ugnot") == 0 {
225 panic("Donation must include GNOT")
226 }
227
228 project, exists := gnoProjects[projectName]
229 if !exists {
230 panic("Gno project not found")
231 }
232
233 project.Sponsors[address_XXX] = Sponsor{
234 Address: address_XXX,
235 Amount: project.Sponsors[address_XXX].Amount.Add(amount),
236 }
237
238 totalDonations = totalDonations.Add(amount)
239
240 gnoProjects[projectName] = project
241}
242
243func SponsorOtherProject(_ realm, projectName string) {
244 address_XXX := runtime.OriginCaller()
245 amount := banker.OriginSend()
246
247 if amount.AmountOf("ugnot") == 0 {
248 panic("Donation must include GNOT")
249 }
250
251 project, exists := otherProjects[projectName]
252 if !exists {
253 panic("Other project not found")
254 }
255
256 project.Sponsors[address_XXX] = Sponsor{
257 Address: address_XXX,
258 Amount: project.Sponsors[address_XXX].Amount.Add(amount),
259 }
260
261 totalDonations = totalDonations.Add(amount)
262
263 otherProjects[projectName] = project
264}
265
266func Withdraw(_ realm) string {
267 realmAddress := runtime.PreviousRealm().Address()
268 if !isAuthorized(realmAddress) {
269 panic(config.ErrUnauthorized)
270 }
271
272 banker_ := banker.NewBanker(banker.BankerTypeRealmSend)
273 coins := banker_.GetCoins(realmAddress)
274
275 if len(coins) == 0 {
276 return "No coins available to withdraw"
277 }
278
279 banker_.SendCoins(realmAddress, config.Address(), coins)
280
281 return "Successfully withdrew all coins to config address"
282}