MarketplaceSEALED
╱^◇~◆?╳●&○*#▓░░▓@?■╳#█^~╲!╱□?▪◆!$$□▫▪╲*!●!!▪%$░&??▒╱$▪■▪#■#◇▓&○○
Transaction ID
Execution Fee
0.00004277 FLOWTransaction Summary
MarketplaceCalled FlowToken, FiatToken, REVV +6 more
Script Arguments
0ownerAddresses[Address]
[]
1collectionIdentifiers[String]
[ "HeroesOfTheFlow", "HeroesOfTheFlow", "HeroesOfTheFlow", "HeroesOfTheFlow", "HeroesOfTheFlow", "HeroesOfTheFlow", "HeroesOfTheFlow", "HeroesOfTheFlow", "HeroesOfTheFlow", "HeroesOfTheFlow", "HeroesOfTheFlow", "HeroesOfTheFlow", "HeroesOfTheFlow", "HeroesOfTheFlow", "HeroesOfTheFlow", "HeroesOfTheFlow", "HeroesOfTheFlow", "HeroesOfTheFlow", "HeroesOfTheFlow", "HeroesOfTheFlow", "HeroesOfTheFlow", "HeroesOfTheFlow", "HeroesOfTheFlow" ]
2saleItemIDs[UInt64]
[ "9410", "9411", "9907", "9908", "9909", "4065", "4532", "6215", "6216", "6709", "6711", "6799", "6801", "7369", "7370", "7371", "7641", "7762", "7763", "7764", "8005", "8007", "8128" ]
3saleItemPrices[UFix64]
[ "0.74000000", "0.74000000", "0.74000000", "0.74000000", "0.74000000", "0.74000000", "0.74000000", "0.74000000", "0.74000000", "0.74000000", "0.74000000", "0.74000000", "0.74000000", "0.74000000", "0.74000000", "0.74000000", "0.74000000", "0.74000000", "0.74000000", "0.74000000", "0.74000000", "0.74000000", "0.74000000" ]
4salePaymentVaultTypeIdentifiers[String]
[ "A.1654653399040a61.FlowToken.Vault", "A.1654653399040a61.FlowToken.Vault", "A.1654653399040a61.FlowToken.Vault", "A.1654653399040a61.FlowToken.Vault", "A.1654653399040a61.FlowToken.Vault", "A.1654653399040a61.FlowToken.Vault", "A.1654653399040a61.FlowToken.Vault", "A.1654653399040a61.FlowToken.Vault", "A.1654653399040a61.FlowToken.Vault", "A.1654653399040a61.FlowToken.Vault", "A.1654653399040a61.FlowToken.Vault", "A.1654653399040a61.FlowToken.Vault", "A.1654653399040a61.FlowToken.Vault", "A.1654653399040a61.FlowToken.Vault", "A.1654653399040a61.FlowToken.Vault", "A.1654653399040a61.FlowToken.Vault", "A.1654653399040a61.FlowToken.Vault", "A.1654653399040a61.FlowToken.Vault", "A.1654653399040a61.FlowToken.Vault", "A.1654653399040a61.FlowToken.Vault", "A.1654653399040a61.FlowToken.Vault", "A.1654653399040a61.FlowToken.Vault", "A.1654653399040a61.FlowToken.Vault" ]
5royaltiesCuts[[UFix64]]
[
[
"0.05000000"
],
[
"0.05000000"
],
[
"0.05000000"
],
[
"0.05000000"
],
[
"0.05000000"
],
[
"0.05000000"
],
[
"0.05000000"
],
[
"0.05000000"
],
[
"0.05000000"
],
[
"0.05000000"
],
[
"0.05000000"
],
[
"0.05000000"
],
[
"0.05000000"
],
[
"0.05000000"
],
[
"0.05000000"
],
[
"0.05000000"
],
[
"0.05000000"
],
[
"0.05000000"
],
[
"0.05000000"
],
[
"0.05000000"
],
[
"0.05000000"
],
[
"0.05000000"
],
[
"0.05000000"
]
]6royaltiesReceivers[[Address]]
[
[
"0xc5857663ca37efbf"
],
[
"0xc5857663ca37efbf"
],
[
"0xc5857663ca37efbf"
],
[
"0xc5857663ca37efbf"
],
[
"0xc5857663ca37efbf"
],
[
"0xc5857663ca37efbf"
],
[
"0xc5857663ca37efbf"
],
[
"0xc5857663ca37efbf"
],
[
"0xc5857663ca37efbf"
],
[
"0xc5857663ca37efbf"
],
[
"0xc5857663ca37efbf"
],
[
"0xc5857663ca37efbf"
],
[
"0xc5857663ca37efbf"
],
[
"0xc5857663ca37efbf"
],
[
"0xc5857663ca37efbf"
],
[
"0xc5857663ca37efbf"
],
[
"0xc5857663ca37efbf"
],
[
"0xc5857663ca37efbf"
],
[
"0xc5857663ca37efbf"
],
[
"0xc5857663ca37efbf"
],
[
"0xc5857663ca37efbf"
],
[
"0xc5857663ca37efbf"
],
[
"0xc5857663ca37efbf"
]
]7privatePathOverrides[String?]
[ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null ]
8customIDString?
flowverse-nft-marketplace
9commissionAmounts[UFix64]
[ "0.00000000", "0.00000000", "0.00000000", "0.00000000", "0.00000000", "0.00000000", "0.00000000", "0.00000000", "0.00000000", "0.00000000", "0.00000000", "0.00000000", "0.00000000", "0.00000000", "0.00000000", "0.00000000", "0.00000000", "0.00000000", "0.00000000", "0.00000000", "0.00000000", "0.00000000", "0.00000000" ]
10expiries[UInt64]
[ "1726770304", "1726770304", "1726770304", "1726770304", "1726770304", "1726770304", "1726770304", "1726770304", "1726770304", "1726770304", "1726770304", "1726770304", "1726770304", "1726770304", "1726770304", "1726770304", "1726770304", "1726770304", "1726770304", "1726770304", "1726770304", "1726770304", "1726770304" ]
Cadence Script
1import FlowToken from 0x1654653399040a61
2import FiatToken from 0xb19436aae4d94622
3import REVV from 0xd01e482eb680ec9f
4import FungibleToken from 0xf233dcee88fe0abe
5import NonFungibleToken from 0x1d7e57aa55817448
6import NFTCatalog from 0x49a7cda3a1eecc29
7import MetadataViews from 0x1d7e57aa55817448
8import NFTStorefrontV2 from 0x4eb8a10cb9f87357
9import HybridCustody from 0xd8a7e05a7ac670c0
10
11transaction(
12 ownerAddresses: [Address],
13 collectionIdentifiers: [String],
14 saleItemIDs: [UInt64],
15 saleItemPrices: [UFix64],
16 salePaymentVaultTypeIdentifiers: [String],
17 royaltiesCuts: [[UFix64]],
18 royaltiesReceivers: [[Address]],
19 privatePathOverrides: [String?],
20 customID: String?,
21 commissionAmounts: [UFix64],
22 expiries: [UInt64]
23) {
24 let collectionCaps: [Capability<&AnyResource{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>]
25 let storefront: &NFTStorefrontV2.Storefront
26 var saleCuts: [[NFTStorefrontV2.SaleCut]]
27 var salePaymentVaultTypes: [Type]
28 let nftTypes: [Type]
29
30 prepare(acct: AuthAccount) {
31 assert(ownerAddresses.length == saleItemIDs.length, message: "ownerAddresses and saleItemIDs must be the same length")
32 assert(saleItemIDs.length == saleItemPrices.length, message: "saleItemIDs and saleItemPrices must be the same length")
33 assert(saleItemIDs.length == salePaymentVaultTypeIdentifiers.length, message: "saleItemIDs and salePaymentVaultTypeIdentifiers must be the same length")
34 assert(saleItemIDs.length == collectionIdentifiers.length, message: "saleItemIDs and collectionIdentifiers must be the same length")
35 assert(saleItemIDs.length == commissionAmounts.length, message: "saleItemIDs and commissionAmounts must be the same length")
36 assert(saleItemIDs.length == expiries.length, message: "saleItemIDs and expiries must be the same length")
37
38 self.collectionCaps = []
39 self.saleCuts = []
40 self.salePaymentVaultTypes = []
41 self.nftTypes = []
42
43 // If the account doesn't already have a storefront, create one and add it to the account
44 if acct.borrow<&NFTStorefrontV2.Storefront>(from: NFTStorefrontV2.StorefrontStoragePath) == nil {
45 let storefront <- NFTStorefrontV2.createStorefront() as! @NFTStorefrontV2.Storefront
46 acct.save(<-storefront, to: NFTStorefrontV2.StorefrontStoragePath)
47 acct.link<&NFTStorefrontV2.Storefront{NFTStorefrontV2.StorefrontPublic}>(NFTStorefrontV2.StorefrontPublicPath, target: NFTStorefrontV2.StorefrontStoragePath)
48 }
49
50 self.storefront = acct.borrow<&NFTStorefrontV2.Storefront>(from: NFTStorefrontV2.StorefrontStoragePath)
51 ?? panic("Missing or mis-typed NFTStorefront Storefront")
52
53 var i = 0
54 while i < saleItemIDs.length {
55 var ftReceiverPath: PublicPath? = nil
56 var ftReceiver: Capability<&AnyResource{FungibleToken.Receiver}>? = nil
57
58 switch salePaymentVaultTypeIdentifiers[i] {
59 case Type<@FlowToken.Vault>().identifier:
60 self.salePaymentVaultTypes.append(Type<@FlowToken.Vault>())
61 ftReceiverPath = PublicPath(identifier: "flowTokenReceiver")!
62 ftReceiver = acct.getCapability<&{FungibleToken.Receiver}>(ftReceiverPath!)!
63 case Type<@FiatToken.Vault>().identifier:
64 self.salePaymentVaultTypes.append(Type<@FiatToken.Vault>())
65
66 // Initialise USDC vault if it doesn't exist
67 if acct.borrow<&FungibleToken.Vault>(from: /storage/USDCVault) == nil {
68 acct.save(<- FiatToken.createEmptyVault(), to: /storage/USDCVault)
69 acct.link<&FiatToken.Vault{FungibleToken.Balance}>(/public/USDCVaultBalance, target: /storage/USDCVault)
70 acct.link<&FiatToken.Vault{FungibleToken.Receiver}>(/public/USDCVaultReceiver, target: /storage/USDCVault)
71 }
72
73 ftReceiverPath = PublicPath(identifier: "USDCVaultReceiver")!
74 ftReceiver = acct.getCapability<&{FungibleToken.Receiver}>(ftReceiverPath!)!
75 case Type<@REVV.Vault>().identifier:
76 self.salePaymentVaultTypes.append(Type<@REVV.Vault>())
77
78 // Initialise REVV vault if it doesn't exist
79 if acct.borrow<&FungibleToken.Vault>(from: REVV.RevvVaultStoragePath) == nil {
80 acct.save(<- REVV.createEmptyVault(), to: REVV.RevvVaultStoragePath)
81 acct.link<&REVV.Vault{FungibleToken.Balance}>(REVV.RevvBalancePublicPath, target: REVV.RevvVaultStoragePath)
82 acct.link<&REVV.Vault{FungibleToken.Receiver}>(REVV.RevvReceiverPublicPath, target: REVV.RevvVaultStoragePath)
83 }
84
85 ftReceiverPath = PublicPath(identifier: "revvReceiver")!
86 ftReceiver = acct.getCapability<&{FungibleToken.Receiver}>(ftReceiverPath!)!
87 default:
88 panic("Unsupported sale payment vault type identifier")
89 }
90
91 assert(ftReceiver!.borrow() != nil, message: "Missing or mis-typed FungibleToken receiver")
92
93 let value = NFTCatalog.getCatalogEntry(collectionIdentifier: collectionIdentifiers[i]) ?? panic("Collection does not exist in the NFT Catalog.")
94
95 // We need a provider capability, but one is not provided by default so we create one if needed.
96 let nftCollectionProviderPrivatePath = PrivatePath(identifier: collectionIdentifiers[i].concat("CollectionProviderForFlowverseNFT"))!
97
98 let ownerAddress = ownerAddresses[i]
99 let privatePathOverride = privatePathOverrides[i]
100
101 // Check if the owner is a child account
102 if ownerAddress != acct.address {
103 let manager = acct.borrow<&HybridCustody.Manager>(from: HybridCustody.ManagerStoragePath)
104 ?? panic("Missing or mis-typed HybridCustody Manager")
105 let child = manager.borrowAccount(addr: ownerAddress) ?? panic("no child account with that address")
106 let catalogPrivatePath = value.collectionData.privatePath
107 let flowverseProviderCap = child.getCapability(path: nftCollectionProviderPrivatePath, type: Type<&{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>())
108 let catalogProviderCap = child.getCapability(path: catalogPrivatePath, type: Type<&{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>())
109 if flowverseProviderCap != nil && (flowverseProviderCap! as! Capability<&{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>).borrow() != nil {
110 let cap = flowverseProviderCap! as! Capability<&{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>
111 self.collectionCaps.append(cap)
112 } else if catalogProviderCap != nil && (catalogProviderCap! as! Capability<&{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>).borrow() != nil {
113 let cap = catalogProviderCap! as! Capability<&{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>
114 self.collectionCaps.append(cap)
115 } else if privatePathOverride != nil {
116 let privatePath = PrivatePath(identifier: privatePathOverride!)!
117 let providerCap = child.getCapability(path: privatePath, type: Type<&{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>())
118 if providerCap != nil && (providerCap! as! Capability<&{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>).borrow() != nil {
119 let cap = providerCap! as! Capability<&{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>
120 self.collectionCaps.append(cap)
121 }
122 } else {
123 panic("The NFT: ".concat(collectionIdentifiers[i]).concat(" cannot be listed by the parent account"))
124 }
125 } else {
126 self.collectionCaps.append(acct.getCapability<&{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>(nftCollectionProviderPrivatePath))
127 if !self.collectionCaps[i].check() {
128 acct.unlink(nftCollectionProviderPrivatePath)
129 acct.link<&{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>(nftCollectionProviderPrivatePath, target: value.collectionData.storagePath)
130 }
131 }
132
133 let collection = self.collectionCaps[i].borrow()
134 ?? panic("Could not borrow a reference to the collection")
135
136 let nft = collection.borrowNFT(id: saleItemIDs[i])
137 self.nftTypes.append(nft.getType())
138
139 let saleCutArr: [NFTStorefrontV2.SaleCut] = []
140 var totalRoyaltyCut: UFix64 = 0.0
141 let saleItemPrice = saleItemPrices[i]
142 let royaltyCuts = royaltiesCuts[i]
143 let royaltyReceivers = royaltiesReceivers[i]
144
145 // Append cuts for the royalties.
146 for index, royaltyCut in royaltyCuts {
147 let receiver = getAccount(royaltyReceivers[index]).getCapability<&AnyResource{FungibleToken.Receiver}>(ftReceiverPath!)
148 let royaltySaleCut = NFTStorefrontV2.SaleCut(receiver: receiver, amount: UFix64(royaltyCut * saleItemPrice))
149 saleCutArr.append(royaltySaleCut)
150 totalRoyaltyCut = totalRoyaltyCut + royaltySaleCut.amount
151 }
152
153 // Append the cut for the seller.
154 saleCutArr.append(NFTStorefrontV2.SaleCut(
155 receiver: ftReceiver!,
156 amount: saleItemPrice - totalRoyaltyCut - commissionAmounts[i]
157 ))
158
159 self.saleCuts.append(saleCutArr)
160
161 i = i + 1
162 }
163 }
164
165 execute {
166 // Create listings
167 var i = 0
168 while i < saleItemIDs.length {
169 self.storefront.createListing(
170 nftProviderCapability: self.collectionCaps[i],
171 nftType: self.nftTypes[i],
172 nftID: saleItemIDs[i],
173 salePaymentVaultType: self.salePaymentVaultTypes[i],
174 saleCuts: self.saleCuts[i],
175 marketplacesCapability: nil,
176 customID: customID,
177 commissionAmount: commissionAmounts[i],
178 expiry: expiries[i]
179 )
180 i = i + 1
181 }
182 }
183}