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("![%s](%s)\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}