home.gno
10.49 Kb · 288 lines
1package home
2
3import (
4 "chain"
5 "chain/banker"
6 "chain/runtime"
7 "strings"
8
9 "gno.land/p/nt/ufmt/v0"
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 if !runtime.PreviousRealm().IsUserCall() {
222 panic("only user-call (maketx call) accepted")
223 }
224 address_XXX := runtime.OriginCaller()
225 amount := banker.OriginSend()
226
227 if amount.AmountOf("ugnot") == 0 {
228 panic("Donation must include GNOT")
229 }
230
231 project, exists := gnoProjects[projectName]
232 if !exists {
233 panic("Gno project not found")
234 }
235
236 project.Sponsors[address_XXX] = Sponsor{
237 Address: address_XXX,
238 Amount: project.Sponsors[address_XXX].Amount.Add(amount),
239 }
240
241 totalDonations = totalDonations.Add(amount)
242
243 gnoProjects[projectName] = project
244}
245
246func SponsorOtherProject(_ realm, projectName string) {
247 if !runtime.PreviousRealm().IsUserCall() {
248 panic("only user-call (maketx call) accepted")
249 }
250 address_XXX := runtime.OriginCaller()
251 amount := banker.OriginSend()
252
253 if amount.AmountOf("ugnot") == 0 {
254 panic("Donation must include GNOT")
255 }
256
257 project, exists := otherProjects[projectName]
258 if !exists {
259 panic("Other project not found")
260 }
261
262 project.Sponsors[address_XXX] = Sponsor{
263 Address: address_XXX,
264 Amount: project.Sponsors[address_XXX].Amount.Add(amount),
265 }
266
267 totalDonations = totalDonations.Add(amount)
268
269 otherProjects[projectName] = project
270}
271
272func Withdraw(_ realm) string {
273 realmAddress := runtime.PreviousRealm().Address()
274 if !isAuthorized(realmAddress) {
275 panic(config.ErrUnauthorized)
276 }
277
278 banker_ := banker.NewBanker(banker.BankerTypeRealmSend)
279 coins := banker_.GetCoins(realmAddress)
280
281 if len(coins) == 0 {
282 return "No coins available to withdraw"
283 }
284
285 banker_.SendCoins(realmAddress, config.Address(), coins)
286
287 return "Successfully withdrew all coins to config address"
288}