Smart Contract

GaiaOrder

A.8b148183c28ff88f.GaiaOrder

Deployed

1d ago
Feb 26, 2026, 09:44:00 PM UTC

Dependents

0 imports
1import GaiaFee from 0x8b148183c28ff88f
2import FungibleToken from 0xf233dcee88fe0abe
3import NFTStorefront from 0x4eb8a10cb9f87357
4import NonFungibleToken from 0x1d7e57aa55817448
5
6pub contract GaiaOrder {
7
8    pub let BUYER_FEE: String
9    pub let SELLER_FEE: String
10    pub let OTHER: String
11    pub let ROYALTY: String
12    pub let REWARD: String
13
14    init() {
15        // market buyer fee (on top of the price)
16        self.BUYER_FEE = "BUYER_FEE"
17
18        // market seller fee
19        self.SELLER_FEE = "SELLER_FEE"
20
21        // additional payments
22        self.OTHER = "OTHER"
23
24        // royalty
25        self.ROYALTY = "ROYALTY"
26
27        // seller reward
28        self.REWARD = "REWARD"
29    }
30
31    // PaymentPart
32    // 
33    pub struct PaymentPart {
34        // receiver address
35        pub let address: Address
36
37        // payment rate
38        pub let rate: UFix64
39
40        init(address: Address, rate: UFix64) {
41            self.address = address
42            self.rate = rate
43        }
44    }
45
46    // Payment
47    // Describes payment in the event OrderAvailable
48    // 
49    pub struct Payment {
50        // type of payment
51        pub let type: String
52
53        // receiver address
54        pub let address: Address
55
56        // payment rate
57        pub let rate: UFix64
58
59        // payment amount
60        pub let amount: UFix64
61
62        init(type: String, address: Address, rate: UFix64, amount: UFix64) {
63            self.type = type
64            self.address = address
65            self.rate = rate
66            self.amount = amount
67        }
68    }
69
70    // OrderAvailable
71    // Order created and available for purchase
72    // 
73    pub event OrderAvailable(
74        orderAddress: Address,
75        orderId: UInt64,
76        nftType: String,
77        nftId: UInt64,
78        vaultType: String,
79        price: UFix64,
80        payments: [Payment]
81    )
82
83    pub event OrderClosed(
84        orderAddress: Address,
85        orderId: UInt64,
86        nftType: String,
87        nftId: UInt64,
88        vaultType: String,
89        price: UFix64,
90        buyerAddress: Address,
91        cuts: [PaymentPart]
92    )
93
94    pub event OrderCancelled(
95        orderAddress: Address,
96        orderId: UInt64,
97        nftType: String,
98        nftId: UInt64,
99        vaultType: String,
100        price: UFix64,
101        cuts: [PaymentPart]
102    )
103
104    // addOrder
105    // Wrapper for NFTStorefront.createListing
106    //
107    pub fun addOrder(
108        storefront: &NFTStorefront.Storefront,
109        nftProvider: Capability<&{NonFungibleToken.Provider,NonFungibleToken.CollectionPublic}>,
110        nftType: Type,
111        nftId: UInt64,
112        vaultPath: PublicPath,
113        vaultType: Type,
114        price: UFix64,
115        extraCuts: [PaymentPart],
116        royalties: [PaymentPart]
117    ): UInt64 {
118        let orderAddress = storefront.owner!.address
119        let payments: [Payment] = []
120        let saleCuts: [NFTStorefront.SaleCut] = []
121        var percentage = 1.0
122
123        let addPayment = fun (type: String, address: Address, rate: UFix64) {
124            assert(rate >= 0.0 && rate < 1.0, message: "Rate must be in range [0..1)")
125            let amount = price * rate
126            let receiver = getAccount(address).getCapability<&{FungibleToken.Receiver}>(vaultPath)
127            assert(receiver.borrow() != nil, message: "Missing or mis-typed fungible token receiver")
128
129            payments.append(Payment(type:type, address:address, rate: rate, amount: amount))
130            saleCuts.append(NFTStorefront.SaleCut(receiver: receiver, amount: amount))
131
132            percentage = percentage - rate
133        }
134
135        if GaiaFee.buyerFee > 0.0 {
136            addPayment(GaiaOrder.BUYER_FEE, GaiaFee.feeAddress(), GaiaFee.buyerFee)
137        }
138        if GaiaFee.sellerFee > 0.0 {
139            addPayment(GaiaOrder.SELLER_FEE, GaiaFee.feeAddress(), GaiaFee.sellerFee)
140        }
141
142        for cut in extraCuts {
143            addPayment(GaiaOrder.OTHER, cut.address, cut.rate)
144        }
145
146        for royalty in royalties {
147            addPayment(GaiaOrder.ROYALTY, royalty.address, royalty.rate)
148        }
149
150        addPayment(GaiaOrder.REWARD, orderAddress, percentage)
151
152        let orderId = storefront.createListing(
153            nftProviderCapability: nftProvider,
154            nftType: nftType,
155            nftID: nftId,
156            salePaymentVaultType: vaultType,
157            saleCuts: saleCuts
158        )
159
160        emit OrderAvailable(
161            orderAddress: orderAddress,
162            orderId: orderId,
163            nftType: nftType.identifier,
164            nftId: nftId,
165            vaultType: vaultType.identifier,
166            price: price,
167            payments: payments
168        )
169
170        return orderId
171    }
172
173    // closeOrder
174    // Purchase nft by o
175    //
176    pub fun closeOrder(
177        storefront: &NFTStorefront.Storefront{NFTStorefront.StorefrontPublic},
178        orderId: UInt64,
179        orderAddress: Address,
180        listing: &NFTStorefront.Listing{NFTStorefront.ListingPublic},
181        paymentVault: @FungibleToken.Vault,
182        buyerAddress: Address
183    ): @NonFungibleToken.NFT {
184        let details = listing.getDetails()
185        let cuts: [PaymentPart] = []
186        for saleCut in details.saleCuts {
187            cuts.append(PaymentPart(address: saleCut.receiver.address, rate: saleCut.amount))
188        }
189
190        emit OrderClosed(
191            orderAddress: orderAddress,
192            orderId: orderId,
193            nftType: details.nftType.identifier,
194            nftId: details.nftID,
195            vaultType: details.salePaymentVaultType.identifier,
196            price: details.salePrice,
197            buyerAddress: buyerAddress,
198            cuts: cuts
199        )
200
201        let item <- listing.purchase(payment: <-paymentVault)
202        storefront.cleanup(listingResourceID: orderId)
203        return <- item
204    }
205
206    // removeOrder
207    // Cancel sale, dismiss order
208    //
209    pub fun removeOrder(
210        storefront: &NFTStorefront.Storefront,
211        orderId: UInt64,
212        orderAddress: Address,
213        listing: &NFTStorefront.Listing{NFTStorefront.ListingPublic},
214    ) {
215        let details = listing.getDetails()
216        let cuts: [PaymentPart] = []
217        for saleCut in details.saleCuts {
218            cuts.append(PaymentPart(address: saleCut.receiver.address, rate: saleCut.amount))
219        }
220
221        emit OrderCancelled(
222            orderAddress: orderAddress,
223            orderId: orderId,
224            nftType: details.nftType.identifier,
225            nftId: details.nftID,
226            vaultType: details.salePaymentVaultType.identifier,
227            price: details.salePrice,
228            cuts: cuts
229        )
230
231        storefront.removeListing(listingResourceID: orderId)
232    }
233}
234