FT TransferSEALED
^▫■╳%╲%●▪●█▓^&╱╳!▫■▫!#●*◇░▒$▒○▒▒■○&$■^%▒╲▫$&@◆*●╳█@○@?&!╲□○▪●▓~@
Transaction ID
Execution Fee
0.00262 FLOWTransaction Summary
FT TransferCalled OffersV2, DapperOffersV2, TopShot +4 more
Script Arguments
0amountUFix64
22.00000000
1royalties{Address
{
"0xfaf0cc52c6e3acaf": "1.10000000"
}2offerParamsString{String
{
"resolver": "0",
"nftId": "26606297"
}Cadence Script
1import OffersV2 from 0xb8ea91944fd51c43
2import DapperOffersV2 from 0xb8ea91944fd51c43
3import TopShot from 0x0b2a3299cc857e29
4import NonFungibleToken from 0x1d7e57aa55817448
5import FungibleToken from 0xf233dcee88fe0abe
6import DapperUtilityCoin from 0xead892083b3e2c6c
7import Resolver from 0xb8ea91944fd51c43
8
9transaction(amount: UFix64, royalties: {Address:UFix64}, offerParamsString: {String:String}) {
10 var nftReceiver: Capability<&{NonFungibleToken.CollectionPublic}>?
11 let dapperOffer: auth(DapperOffersV2.Manager) &DapperOffersV2.DapperOffer
12 var ducVaultRef: Capability<auth(FungibleToken.Withdraw) &{FungibleToken.Vault}>
13 let resolverCapability: Capability<&{Resolver.ResolverPublic}>
14 var proxyManagerCap: Capability<auth(DapperOffersV2.ProxyManager) &DapperOffersV2.DapperOffer>
15 var ROYALITY_ADDRESS: Address
16 var ROYALITY_PERCENT: UFix64
17 prepare(signer: auth(Storage, Capabilities) &Account, dapper: auth(Storage, Capabilities) &Account) {
18 // Link the NFT collection
19 if signer.storage.borrow<&TopShot.Collection>(from: /storage/MomentCollection) == nil {
20 let collection <- TopShot.createEmptyCollection(nftType: Type<@TopShot.NFT>())
21 signer.storage.save(<-collection, to: /storage/MomentCollection)
22 signer.capabilities.unpublish(/public/MomentCollection)
23 signer.capabilities.publish(
24 signer.capabilities.storage.issue<&TopShot.Collection>(/storage/MomentCollection),
25 at: /public/MomentCollection
26 )
27 }
28 self.nftReceiver = signer.capabilities.get<&{NonFungibleToken.CollectionPublic}>(/public/MomentCollection)
29 if self.nftReceiver == nil || !self.nftReceiver!.check() {
30 signer.capabilities.unpublish(/public/MomentCollection)
31 signer.capabilities.publish(
32 signer.capabilities.storage.issue<&{NonFungibleToken.CollectionPublic}>(/storage/MomentCollection),
33 at: /public/MomentCollection
34 )
35 self.nftReceiver = signer.capabilities.get<&{NonFungibleToken.CollectionPublic}>(/public/MomentCollection)
36 }
37 // Link the DapperOffer resource
38 if signer.storage.borrow<&DapperOffersV2.DapperOffer>(from: DapperOffersV2.DapperOffersStoragePath) == nil {
39 let dapperOffer <- DapperOffersV2.createDapperOffer() as! @DapperOffersV2.DapperOffer
40 signer.storage.save(<-dapperOffer, to: DapperOffersV2.DapperOffersStoragePath)
41 signer.capabilities.publish(
42 signer.capabilities.storage.issue<&DapperOffersV2.DapperOffer>(DapperOffersV2.DapperOffersStoragePath),
43 at: DapperOffersV2.DapperOffersPublicPath
44 )
45 }
46 // DapperOfferProxyManager Setup
47 if dapper.storage.borrow<&DapperOffersV2.DapperOffer>(from: DapperOffersV2.DapperOffersStoragePath) == nil {
48 let dapperOffer <- DapperOffersV2.createDapperOffer() as! @DapperOffersV2.DapperOffer
49 dapper.storage.save(<-dapperOffer, to: DapperOffersV2.DapperOffersStoragePath)
50 dapper.capabilities.publish(
51 dapper.capabilities.storage.issue<&DapperOffersV2.DapperOffer>(DapperOffersV2.DapperOffersStoragePath),
52 at: DapperOffersV2.DapperOffersPublicPath
53 )
54 }
55 // Setup Proxy Cancel for Dapper
56 let capabilityReceiver = dapper.capabilities.borrow
57 <&DapperOffersV2.DapperOffer>
58 (DapperOffersV2.DapperOffersPublicPath) ?? panic("Could not borrow capability receiver reference")
59
60
61 let dapperOfferProxyManagerCapPath = /storage/DapperOfferProxyManagerCapability
62 var dapperOfferProxyManagerCap = signer.storage.copy<Capability<auth(DapperOffersV2.ProxyManager) &DapperOffersV2.DapperOffer>>(from: dapperOfferProxyManagerCapPath)
63 if dapperOfferProxyManagerCap == nil || !dapperOfferProxyManagerCap!.check() {
64 self.proxyManagerCap = signer.capabilities.storage.issue<auth(DapperOffersV2.ProxyManager) &DapperOffersV2.DapperOffer>(DapperOffersV2.DapperOffersStoragePath)
65 // save capability to storage
66 signer.capabilities.storage.getController(byCapabilityID: self.proxyManagerCap.id)!.setTag("DapperOfferProxyManagerCap")
67 signer.storage.save(
68 self.proxyManagerCap,
69 to: dapperOfferProxyManagerCapPath
70 )
71 } else {
72 self.proxyManagerCap = dapperOfferProxyManagerCap!
73 }
74
75 capabilityReceiver.addProxyCapability(account: signer.address, cap: self.proxyManagerCap)
76 // Setup Proxy Cancel for Collection Minter
77 let minter = getAccount(0xe1f2a091f7bb5245)
78 let capabilityReceiverCollectionMinter = minter.capabilities.borrow
79 <&DapperOffersV2.DapperOffer>
80 (DapperOffersV2.DapperOffersPublicPath) ?? panic("Could not borrow capability receiver reference")
81 capabilityReceiverCollectionMinter.addProxyCapability(account: signer.address, cap: self.proxyManagerCap)
82 // Get the capability to the offer creators NFT collection
83 self.nftReceiver = signer.capabilities.get<&{NonFungibleToken.CollectionPublic}>(/public/MomentCollection)
84 self.dapperOffer = signer.storage.borrow<auth(DapperOffersV2.Manager) &DapperOffersV2.DapperOffer>(from: DapperOffersV2.DapperOffersStoragePath)
85 ?? panic("Missing or mis-typed DapperOffersV2.DapperOffer")
86
87 // Get the capability to the DUC vault
88 let ducWithdrawCapPath = /storage/DUCWithdrawCapabilityForOffers
89 var ducWithdrawCap = dapper.storage.copy<Capability<auth(FungibleToken.Withdraw) &{FungibleToken.Vault}>>(from: ducWithdrawCapPath)
90 if ducWithdrawCap == nil || !ducWithdrawCap!.check() {
91 self.ducVaultRef = dapper.capabilities.storage.issue<auth(FungibleToken.Withdraw) &{FungibleToken.Vault}>(/storage/dapperUtilityCoinVault)
92 // save capability to storage
93 dapper.capabilities.storage.getController(byCapabilityID: self.ducVaultRef.id)!.setTag("OffersDUCWithdrawCap")
94 dapper.storage.save(
95 self.ducVaultRef,
96 to: ducWithdrawCapPath
97 )
98 } else{
99 self.ducVaultRef = ducWithdrawCap!
100 }
101
102 // Validate marketplace royalties
103 self.ROYALITY_ADDRESS = 0xfaf0cc52c6e3acaf
104 self.ROYALITY_PERCENT = 0.05000000
105 assert(royalties[self.ROYALITY_ADDRESS] == self.ROYALITY_PERCENT * amount, message: "Missing or mis-typed royalty information for marketplace")
106 assert(royalties.keys.length == 1, message: "please provide only one royalty address")
107 // Validate offerParamsString and resolver for type NFT
108 assert(offerParamsString.containsKey("nftId"), message: "nftId missing from offerParamsString")
109 assert(offerParamsString.containsKey("resolver"), message: "resolver missing from offerParamsString")
110 assert(offerParamsString["resolver"] == Resolver.ResolverType.NFT.rawValue.toString(), message: "Invalid resolver")
111 // Setup and link offer Resolver
112 if signer.storage.borrow<&Resolver.OfferResolver>(from: /storage/OfferResolver) == nil {
113 let resolver <- Resolver.createResolver()
114 signer.storage.save(<-resolver, to: /storage/OfferResolver)
115 signer.capabilities.publish(
116 signer.capabilities.storage.issue<&Resolver.OfferResolver>(/storage/OfferResolver),
117 at: /public/OfferResolver
118 )
119 }
120 self.resolverCapability = signer.capabilities.get<&{Resolver.ResolverPublic}>(/public/OfferResolver)!
121 }
122 execute {
123 var royaltysList: [OffersV2.Royalty] = []
124 let keys = royalties.keys
125 for key in keys {
126 royaltysList.append(OffersV2.Royalty(
127 receiver: getAccount(key).capabilities.get<&{FungibleToken.Receiver}>(/public/dapperUtilityCoinReceiver)!,
128 amount: royalties[key]!
129 ))
130 }
131 offerParamsString.insert(key: "typeId", "Type<@TopShot.NFT>()")
132 offerParamsString.insert(key: "_type", "NFT")
133 self.dapperOffer.createOffer(
134 vaultRefCapability: self.ducVaultRef,
135 nftReceiverCapability: self.nftReceiver!,
136 nftType: Type<@TopShot.NFT>(),
137 amount: amount,
138 royalties: royaltysList,
139 offerParamsString: offerParamsString,
140 offerParamsUFix64: {},
141 offerParamsUInt64: {},
142 resolverCapability: self.resolverCapability
143 )
144 }
145}