TransactionSEALED
▓□▓*^╱▫●▪@●╳□^~%#□▒▓█^○╳&~◆●?▫▪&*▫╲■●█╲╳@○□#▫#◇◆▓■○?■█▓╳░▫^$■╳░▒
Transaction ID
Payer
Proposerseq:0 key:0
Authorizers
2Transaction Summary
Contract CallCalled NonFungibleToken, FungibleToken, OffersV2 +7 more
Script Arguments
0amountUFix64
0.29000000
1royalties{Address
{
"0x6590f8918060ef13": "0.00725000"
}2offerParamsString{String
{
"expiry": "1764198197"
}3nftIdUInt64
49030647
4collectionAddressAddress
5collectionNameString
TopShot
6publicPathIdentifierString
MomentCollection
7storagePathIdentifierString
MomentCollection
8proxyAddressAddress
9expiryUInt64
1764198197
10nftTypeIdentifierString
A.0b2a3299cc857e29.TopShot.NFT
Cadence Script
1import NonFungibleToken from 0x1d7e57aa55817448
2import FungibleToken from 0xf233dcee88fe0abe
3import OffersV2 from 0xb8ea91944fd51c43
4import DapperOffersV2 from 0xb8ea91944fd51c43
5import DapperUtilityCoin from 0xead892083b3e2c6c
6import Resolver from 0xb8ea91944fd51c43
7import FlowtyOffersResolver from 0x322d96c958eb8c46
8import StringUtils from 0xa340dc0a4ec828ab
9import NFTStorefrontV2 from 0x3cdbb3d569211ff3
10import FlowtyUtils from 0x3cdbb3d569211ff3
11
12transaction(
13 amount: UFix64,
14 royalties: {Address: UFix64},
15 offerParamsString: {String: String},
16 nftId: UInt64,
17 collectionAddress: Address,
18 collectionName: String,
19 publicPathIdentifier: String,
20 storagePathIdentifier: String,
21 proxyAddress: Address,
22 expiry: UInt64,
23 nftTypeIdentifier: String
24) {
25 var nftReceiver: Capability<&{NonFungibleToken.CollectionPublic}>
26 let dapperOffer: auth(DapperOffersV2.Manager) &DapperOffersV2.DapperOffer
27 let ducVaultRef: Capability<auth(FungibleToken.Withdraw) &DapperUtilityCoin.Vault>
28 let resolverCapability: Capability<&{Resolver.ResolverPublic}>
29 let tokenAdminCollection: Capability<auth(DapperOffersV2.ProxyManager) &DapperOffersV2.DapperOffer>
30
31 prepare(signer: auth(Storage, Capabilities) &Account, dapper: auth(Storage, Capabilities) &Account) {
32 let contractAcct = getAccount(collectionAddress)
33 let borrowedContract = contractAcct.contracts.borrow<&{NonFungibleToken}>(name: collectionName) ?? panic("collection not found")
34 let nftType = CompositeType(nftTypeIdentifier) ?? panic("invalid nftTypeIdentifier")
35
36 let storagePath = StoragePath(identifier: storagePathIdentifier)!
37 let publicPath = PublicPath(identifier: publicPathIdentifier)!
38 if signer.storage.borrow<&{NonFungibleToken.CollectionPublic}>(from: storagePath) == nil {
39 let c <- borrowedContract.createEmptyCollection(nftType: nftType)
40 signer.storage.save(<-c, to: storagePath)
41 signer.capabilities.unpublish(publicPath)
42 signer.capabilities.publish(
43 signer.capabilities.storage.issue<&{NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic}>(storagePath),
44 at: publicPath
45 )
46 }
47
48 self.nftReceiver = signer.capabilities.get<&{NonFungibleToken.CollectionPublic}>(publicPath)
49 if !self.nftReceiver.check() {
50 signer.capabilities.unpublish(publicPath)
51 signer.capabilities.publish(
52 signer.capabilities.storage.issue<&{NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic}>(storagePath),
53 at: publicPath
54 )
55 self.nftReceiver = signer.capabilities.get<&{NonFungibleToken.CollectionPublic}>(publicPath)
56 }
57
58 let dapperOfferType = Type<@DapperOffersV2.DapperOffer>()
59
60 // Link the DapperOffer resource
61 if signer.storage.borrow<&DapperOffersV2.DapperOffer>(from: DapperOffersV2.DapperOffersStoragePath) == nil {
62 let dapperOffer <- DapperOffersV2.createDapperOffer()
63 signer.storage.save(<-dapperOffer, to: DapperOffersV2.DapperOffersStoragePath)
64 signer.capabilities.publish(
65 signer.capabilities.storage.issue<&{DapperOffersV2.DapperOfferPublic}>(DapperOffersV2.DapperOffersStoragePath),
66 at: DapperOffersV2.DapperOffersPublicPath
67 )
68
69 let managerStoragePath = /storage/flowtyDapperOfferManager
70 let cap = signer.storage.copy<Capability<auth(DapperOffersV2.Manager) &{DapperOffersV2.DapperOfferManager}>>(from: managerStoragePath)
71 if cap?.check() != true {
72 let managerCap = signer.capabilities.storage.issue<auth(DapperOffersV2.Manager) &{DapperOffersV2.DapperOfferManager}>(DapperOffersV2.DapperOffersStoragePath)
73 signer.storage.save(managerCap, to: managerStoragePath)
74 }
75 }
76
77 // DapperOfferProxyManager Setup
78 let proxyStoragePath = /storage/flowtyDapperOfferProxy
79 let copiedProxy = signer.storage.copy<Capability<auth(DapperOffersV2.ProxyManager) &DapperOffersV2.DapperOffer>>(from: proxyStoragePath)
80 if copiedProxy?.check() == true {
81 self.tokenAdminCollection = copiedProxy!
82 } else {
83 self.tokenAdminCollection = signer.capabilities.storage.issue<auth(DapperOffersV2.ProxyManager) &DapperOffersV2.DapperOffer>(DapperOffersV2.DapperOffersStoragePath)
84 signer.storage.load<AnyStruct>(from: proxyStoragePath)
85 signer.storage.save(self.tokenAdminCollection, to: proxyStoragePath)
86 }
87
88 if dapper.storage.borrow<&DapperOffersV2.DapperOffer>(from: DapperOffersV2.DapperOffersStoragePath) == nil {
89 let dapperOffer <- DapperOffersV2.createDapperOffer()
90 dapper.storage.save(<-dapperOffer, to: DapperOffersV2.DapperOffersStoragePath)
91 dapper.capabilities.publish(
92 dapper.capabilities.storage.issue<&{DapperOffersV2.DapperOfferPublic}>(DapperOffersV2.DapperOffersStoragePath),
93 at: DapperOffersV2.DapperOffersPublicPath
94 )
95
96 let proxyManagerStoragePath = /storage/dapperProxyManager
97 let proxyCap = dapper.capabilities.storage.issue<auth(DapperOffersV2.ProxyManager) &{DapperOffersV2.DapperOfferManager, DapperOffersV2.DapperOfferProxyManager}>(DapperOffersV2.DapperOffersStoragePath)
98 dapper.storage.save(proxyCap, to: proxyManagerStoragePath)
99 }
100
101 // Setup Proxy Cancel for Dapper
102 let capabilityReceiver = dapper.capabilities.get<&{DapperOffersV2.DapperOfferPublic}>(/public/DapperOffersV2).borrow()
103 ?? panic("Could not borrow capability receiver reference")
104 capabilityReceiver.addProxyCapability(account: signer.address, cap: self.tokenAdminCollection)
105
106 // Get the capability to the offer creators NFT collection
107 self.nftReceiver = signer.capabilities.get<&{NonFungibleToken.CollectionPublic}>(publicPath)
108 assert(self.nftReceiver.check(), message: "Missing or mis-typed collection receiver")
109
110 self.dapperOffer = signer.storage.borrow<auth(DapperOffersV2.Manager) &DapperOffersV2.DapperOffer>(from: DapperOffersV2.DapperOffersStoragePath)
111 ?? panic("Missing or mis-typed DapperOffersV2.DapperOffer")
112 // Get the capability to the DUC vault
113
114 let ducCapStoragePath = /storage/flowtyDucProvider
115 let copiedDucProvider = dapper.storage.copy<Capability<auth(FungibleToken.Withdraw) &DapperUtilityCoin.Vault>>(from: ducCapStoragePath)
116 if copiedDucProvider?.check() == true {
117 self.ducVaultRef = copiedDucProvider!
118 } else {
119 self.ducVaultRef = dapper.capabilities.storage.issue<auth(FungibleToken.Withdraw) &DapperUtilityCoin.Vault>(/storage/dapperUtilityCoinVault)
120 dapper.storage.save(self.ducVaultRef, to: ducCapStoragePath)
121 }
122
123 assert(self.ducVaultRef.check() != nil, message: "Missing or mis-typed DapperUtilityCoin provider")
124 self.resolverCapability = FlowtyOffersResolver.getResolverCap()
125 }
126
127 execute {
128 var royaltysList: [OffersV2.Royalty] = []
129 for k in royalties.keys {
130 royaltysList.append(OffersV2.Royalty(
131 receiver: getAccount(k).capabilities.get<&{FungibleToken.Receiver}>(/public/dapperUtilityCoinReceiver),
132 amount: royalties[k]!
133 ))
134 }
135
136 let str = collectionAddress.toString()
137 let typeId = StringUtils.join(["A", str.slice(from: 2, upTo: str.length), collectionName, "NFT"], ".")
138
139 offerParamsString.insert(key: "nftId", nftId.toString())
140 offerParamsString.insert(key: "resolver", FlowtyOffersResolver.ResolverType.NFT.rawValue.toString())
141 offerParamsString.insert(key: "_type", "NFT")
142 offerParamsString.insert(key: "typeId", typeId)
143
144 let offerParamsUInt64: {String: UInt64} = { "expiry": expiry }
145
146 self.dapperOffer.createOffer(
147 vaultRefCapability: self.ducVaultRef,
148 nftReceiverCapability: self.nftReceiver,
149 nftType: CompositeType(typeId)!,
150 amount: amount,
151 royalties: royaltysList,
152 offerParamsString: offerParamsString,
153 offerParamsUFix64: {},
154 offerParamsUInt64: offerParamsUInt64,
155 resolverCapability: self.resolverCapability
156 )
157 }
158}