Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

trade.gno

2.25 Kb · 86 lines
 1package shop
 2
 3import (
 4	"chain"
 5	"chain/banker"
 6	"chain/runtime/unsafe"
 7
 8	"gno.land/p/nt/grc721/v0"
 9)
10
11// List puts tid on sale for price ugnot. The token stays with the owner.
12// A dead listing (the recorded seller no longer owns it) is replaced.
13func List(cur realm, tid string, price int64) {
14	caller := requireUser(cur)
15	requireReady()
16	if price < 1 {
17		panic("market: price")
18	}
19	id := parseTid(tid)
20	if ownerOf(id) != caller {
21		panic("market: not owner")
22	}
23	listings.Set(string(id), listing{Seller: caller, Price: price})
24	chain.Emit("List", "tid", string(id), "seller", caller.String(), "price", i64(price))
25}
26
27// Cancel removes the caller's listing, or a listing whose seller no longer owns the token.
28func Cancel(cur realm, tid string) {
29	caller := requireUser(cur)
30	requireReady()
31	id := parseTid(tid)
32	lot := mustListing(id)
33	if caller != lot.Seller && caller != ownerOf(id) {
34		panic("market: cancel")
35	}
36	listings.Remove(string(id))
37	chain.Emit("Cancel", "tid", string(id), "caller", caller.String())
38}
39
40// Buy pays the listing price in ugnot and takes the token.
41// The attached send must be exactly the price, one ugnot coin.
42func Buy(cur realm, tid string) {
43	caller := requireUser(cur)
44	requireReady()
45	id := parseTid(tid)
46	lot := mustListing(id)
47	if caller == lot.Seller {
48		panic("market: self")
49	}
50	if ownerOf(id) != lot.Seller {
51		panic("market: stale")
52	}
53	paid := unsafe.OriginSend()
54	if len(paid) != 1 || paid[0].Denom != "ugnot" || paid[0].Amount != lot.Price {
55		panic("market: pay")
56	}
57	if err := ledger.TransferFrom(lot.Seller, lot.Seller, caller, id); err != nil {
58		panic("market: transfer")
59	}
60	coins := chain.NewCoins(chain.NewCoin("ugnot", lot.Price))
61	bank := banker.NewBanker(banker.BankerTypeOriginSend, cur)
62	bank.SendCoins(cur.Address(), lot.Seller, coins)
63	listings.Remove(string(id))
64	name, _ := metaNameImage(id)
65	pushSale(sale{Tid: string(id), Seller: lot.Seller, Buyer: caller, Price: lot.Price, Name: name})
66	chain.Emit(
67		"Buy",
68		"tid", string(id),
69		"seller", lot.Seller.String(),
70		"buyer", caller.String(),
71		"price", i64(lot.Price),
72	)
73}
74
75func mustListing(id grc721.TokenID) listing {
76	got := listings.Get(string(id))
77	if got == nil {
78		panic("market: no listing")
79	}
80	return got.(listing)
81}
82
83func pushSale(s sale) {
84	sales[saleN%saleCap] = s
85	saleN++
86}