MarketplaceSEALED
○▪□▒~^□▪#●^~□▓▓!%^╱◇●○?▒◇~□^^%#□!□&╳█◆○◇○■%▓■●╲▪╲$■%@$◇◆□%◇@#%╱!
Transaction ID
Execution Fee
0.00002474 FLOWTransaction Summary
MarketplaceCalled FungibleToken, NonFungibleToken, DapperUtilityCoin +4 more
Script Arguments
Cadence Script
1import FungibleToken from 0xf233dcee88fe0abe
2import NonFungibleToken from 0x1d7e57aa55817448
3import DapperUtilityCoin from 0xead892083b3e2c6c
4import Pinnacle from 0xedf9df96c92f4595
5import NFTStorefrontV2 from 0x4eb8a10cb9f87357
6import MetadataViews from 0x1d7e57aa55817448
7import TokenForwarding from 0xe544175ee0461c4b
8
9// This transaction facilitates the listing of an NFT with the StorefrontV2 contract
10//
11// Collection Identifier: Pinnacle
12// Vault Identifier: duc
13//
14// Version: 0.1.1
15transaction() {
16 var ftReceiver: Capability<&{FungibleToken.Receiver}>
17 var nftProvider: Capability<auth(NonFungibleToken.Withdraw) &Pinnacle.Collection>?
18 let storefront: auth(NFTStorefrontV2.CreateListing, NFTStorefrontV2.RemoveListing) &NFTStorefrontV2.Storefront
19 var saleCuts: [NFTStorefrontV2.SaleCut]
20 var marketplacesCapability: [Capability<&{FungibleToken.Receiver}>]
21
22 /// 'customID' - Optional string to represent identifier of the dapp.
23 let customID: String
24 /// 'commissionAmount' - Commission amount that will be taken away by the purchase facilitator i.e marketplacesAddress.
25 let commissionAmount: UFix64
26 /// 'marketplacesAddress' - List of addresses that are allowed to get the commission.
27 let marketplaceAddress: [Address]
28 // we only ever want to use DapperUtilityCoin
29 let universalDucReceiver: Address
30
31 prepare(acct: auth(Storage, Capabilities) &Account) {
32 /// 'customID' - Optional string to represent identifier of the dapp.
33 self.customID = "DAPPER_MARKETPLACE"
34 /// 'commissionAmount' - Commission amount that will be taken away by the purchase facilitator i.e marketplacesAddress.
35 self.commissionAmount = 2.15000000
36 /// 'marketplacesAddress' - List of addresses that are allowed to get the commission.
37 self.marketplaceAddress = [0xedf9df96c92f4595]
38 // we only ever want to use DapperUtilityCoin
39 self.universalDucReceiver = 0xead892083b3e2c6c
40
41 self.saleCuts = []
42 self.marketplacesCapability = []
43 let PinnaclePrivateCollectionPath = /storage/PinnacleNFTCollectionProviderForNFTStorefront
44
45 // ************************* Handling of DUC Recevier *************************** //
46
47 // Fetch the capability of the universal DUC receiver
48 let recipient = getAccount(self.universalDucReceiver).capabilities.get<&{FungibleToken.Receiver}>(/public/dapperUtilityCoinReceiver)!
49 assert(recipient.borrow() != nil, message: "Missing or mis-typed Fungible Token receiver for the DUC recipient")
50
51 // Check whether the receiver has the capability to receive the DUC
52 self.ftReceiver = acct.capabilities.get<&{FungibleToken.Receiver}>(/public/dapperUtilityCoinReceiver)
53 if self.ftReceiver.borrow() == nil || !self.ftReceiver.borrow()!.isInstance(Type<@TokenForwarding.Forwarder>()) {
54 acct.capabilities.unpublish(/public/dapperUtilityCoinReceiver)
55 // Create the forwarder and save it to the account that is doing the forwarding
56 let vault <- TokenForwarding.createNewForwarder(recipient: recipient)
57 acct.storage.save(<-vault, to: /storage/ducTokenForwarder)
58 // Link the new forwarding receiver capability
59 acct.capabilities.publish(
60 acct.capabilities.storage.issue<&{FungibleToken.Receiver}>(/storage/ducTokenForwarder),
61 at: /public/dapperUtilityCoinReceiver
62 )
63 self.ftReceiver = acct.capabilities.get<&{FungibleToken.Receiver}>(/public/dapperUtilityCoinReceiver)
64 }
65
66 // Validate the marketplaces capability before submiting to 'createListing'.
67 for mp in self.marketplaceAddress {
68 let marketplaceReceiver = getAccount(mp).capabilities.get<&{FungibleToken.Receiver}>(/public/dapperUtilityCoinReceiver)
69 assert(marketplaceReceiver.borrow() != nil && marketplaceReceiver.borrow()!.isInstance(Type<@TokenForwarding.Forwarder>()), message: "Marketplaces does not possess the valid receiver type for DUC")
70 self.marketplacesCapability.append(marketplaceReceiver)
71 }
72
73 // *************************** Seller account interactions *************************** //
74 // This checks for the public capability
75 if !acct.capabilities.get<&Pinnacle.Collection>(Pinnacle.CollectionPublicPath)!.check() {
76 acct.capabilities.unpublish(Pinnacle.CollectionPublicPath)
77 acct.capabilities.publish(
78 acct.capabilities.storage.issue<auth(NonFungibleToken.Withdraw) &Pinnacle.Collection>(Pinnacle.CollectionStoragePath),
79 at: Pinnacle.CollectionPublicPath
80 )
81 }
82
83 var provider: Capability<auth(NonFungibleToken.Withdraw) &Pinnacle.Collection>? =
84 acct.storage.copy<Capability<auth(NonFungibleToken.Withdraw) &Pinnacle.Collection>>(from: PinnaclePrivateCollectionPath)
85
86 if provider == nil {
87 provider = acct.capabilities.storage.issue<auth(NonFungibleToken.Withdraw) &Pinnacle.Collection>(Pinnacle.CollectionStoragePath)
88 acct.capabilities.storage.getController(byCapabilityID: provider!.id)!.setTag("PinnacleNFTCollectionProviderForNFTStorefront")
89 // Save the capability to the account storage
90 acct.storage.save(provider!, to: PinnaclePrivateCollectionPath)
91 }
92
93 self.nftProvider = provider
94 assert(self.nftProvider?.borrow() != nil, message: "Missing or mis-typed Pinnacle.Collection provider")
95
96 let collectionRef = acct.capabilities.borrow<&Pinnacle.Collection>(Pinnacle.CollectionPublicPath)
97 ?? panic("Could not borrow a reference to the collection")
98
99 var totalRoyaltyCut = 0.0
100 let effectiveSaleItemPrice = 32.00000000 - self.commissionAmount
101
102 let nft = collectionRef!.borrowPinNFT(id: 206708187115208)!
103
104 // Append the cut for the seller.
105 self.saleCuts.append(NFTStorefrontV2.SaleCut(
106 receiver: self.ftReceiver,
107 amount: effectiveSaleItemPrice - totalRoyaltyCut
108 ))
109
110 if acct.storage.borrow<&NFTStorefrontV2.Storefront>(from: NFTStorefrontV2.StorefrontStoragePath) == nil {
111 // Create a new empty Storefront
112 let storefront <- NFTStorefrontV2.createStorefront() as! @NFTStorefrontV2.Storefront
113 // save it to the account
114 acct.storage.save(<-storefront, to: NFTStorefrontV2.StorefrontStoragePath)
115 // create a public capability for the Storefront
116 acct.capabilities.publish(
117 acct.capabilities.storage.issue<&NFTStorefrontV2.Storefront>(NFTStorefrontV2.StorefrontStoragePath),
118 at: NFTStorefrontV2.StorefrontPublicPath
119 )
120 }
121 self.storefront = acct.storage.borrow<auth(NFTStorefrontV2.CreateListing, NFTStorefrontV2.RemoveListing) &NFTStorefrontV2.Storefront>(from: NFTStorefrontV2.StorefrontStoragePath)!
122 }
123
124 execute {
125 // check for existing listings of the NFT
126 var existingListingIDs = self.storefront.getExistingListingIDs(
127 nftType: Type<@Pinnacle.NFT>(),
128 nftID: 206708187115208
129 )
130 // remove existing listings
131 for listingID in existingListingIDs {
132 self.storefront.removeListing(listingResourceID: listingID)
133 }
134
135 // Create listing
136 self.storefront.createListing(
137 nftProviderCapability: self.nftProvider!,
138 nftType: Type<@Pinnacle.NFT>(),
139 nftID: 206708187115208,
140 salePaymentVaultType: Type<@DapperUtilityCoin.Vault>(),
141 saleCuts: self.saleCuts,
142 marketplacesCapability: self.marketplacesCapability.length == 0 ? nil : self.marketplacesCapability,
143 customID: self.customID,
144 commissionAmount: self.commissionAmount,
145 expiry: 32503708800
146 )
147 }
148}