MarketplaceSEALED
^▒■!%~&^$▫?@▫#▓╱?▓▒■▒*╱^%?■▫▪◇●##■#╲#▪@▫▪░░◆$◆░╳▪◆@□&◇◇╱■#●▫╳@◇▪
Transaction ID
Execution Fee
0.00002974 FLOWTransaction Summary
Marketplace
Called FungibleToken, NonFungibleToken, DapperUtilityCoin +4 more
Script Arguments
Copy:
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.60000000
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 = 38.00000000 - self.commissionAmount
101
102 let nft = collectionRef!.borrowPinNFT(id: 1450032301)!
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: 1450032301
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: 1450032301,
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}