TransactionSEALED

░^░╳░□□&╳▓*□╱&╱▫╲░□▪@?^▪?╱~&?╳@╲░▓#%░╳*■&%$╱~$█╳╲~?□^◆▪□◇~&□▓*□%

Transaction ID

Timestamp

Feb 25, 2026, 07:09:02 PM UTC
1d ago

Block Height

143,398,618

Computation

0

Transaction Summary

Contract Call

Called OffersV2, DapperOffersV2, AllDay +4 more

Script Arguments

0amountUFix64
3.00000000
1royalties{Address
{
  "0xe4cf4bdc1751c65d": "0.15000000"
}
2offerParamsString{String
{
  "editionId": "4897",
  "_type": "EDITION"
}

Cadence Script

1import OffersV2 from  0xb8ea91944fd51c43
2import DapperOffersV2 from  0xb8ea91944fd51c43
3import AllDay from 0xe4cf4bdc1751c65d
4import NonFungibleToken from 0x1d7e57aa55817448
5import FungibleToken from 0xf233dcee88fe0abe
6import DapperUtilityCoin from 0xead892083b3e2c6c
7import Resolver from  0xb8ea91944fd51c43
8
9/// This transaction creates an offer to exchange a AllDay NFT for DapperUtilityCoin.
10///
11/// @param amount: The amount of DapperUtilityCoin to offer for the NFT.
12/// @param royalties: A dictionary of royalties to pay out for the NFT sale.
13/// @param offerParamsString: A dictionary of offer parameters. If only a editionId is provided, an edition offer
14/// is created. If a serialNumber is also provided, a serial offer is created, meaning only the NFT with the
15/// provided serial number from the provided edition can be accepted with this offer.
16///
17transaction(amount: UFix64, royalties: {Address:UFix64}, offerParamsString: {String:String}) {
18    var nftReceiver: Capability<&{NonFungibleToken.CollectionPublic}>?
19    let dapperOfferRef: auth(DapperOffersV2.Manager) &DapperOffersV2.DapperOffer
20    var ducWithdrawCap: Capability<auth(FungibleToken.Withdraw) &{FungibleToken.Vault}>
21    let resolverCap: Capability<&{Resolver.ResolverPublic}>
22    var proxyManagerCap: Capability<auth(DapperOffersV2.ProxyManager) &DapperOffersV2.DapperOffer>
23
24    prepare(signer: auth(Storage, Capabilities) &Account, dapper: auth(Storage, Capabilities) &Account) {
25        // Create and publish a new AllDay collection if the signer account doesn't already have one
26        if signer.storage.borrow<&AllDay.Collection>(from: AllDay.CollectionStoragePath) == nil {
27            signer.storage.save(<- AllDay.createEmptyCollection(nftType: Type<@AllDay.NFT>()), to: AllDay.CollectionStoragePath)
28            signer.capabilities.unpublish(AllDay.CollectionPublicPath)
29            signer.capabilities.publish(
30                signer.capabilities.storage.issue<&AllDay.Collection>(AllDay.CollectionStoragePath),
31                at: AllDay.CollectionPublicPath
32            )
33        }
34
35        // Get the AllDay collection receiver capability, republishing if missing
36        self.nftReceiver = signer.capabilities.get<&{NonFungibleToken.CollectionPublic}>(AllDay.CollectionPublicPath)
37        if self.nftReceiver == nil || !self.nftReceiver!.check() {
38            signer.capabilities.unpublish(AllDay.CollectionPublicPath)
39            signer.capabilities.publish(
40                signer.capabilities.storage.issue<&{NonFungibleToken.CollectionPublic}>(AllDay.CollectionStoragePath),
41                at: AllDay.CollectionPublicPath
42            )
43            self.nftReceiver = signer.capabilities.get<&{NonFungibleToken.CollectionPublic}>(AllDay.CollectionPublicPath)
44        }
45
46        // Create and publish a new DapperOffers resource if the signer account doesn't already have one
47        if signer.storage.borrow<&DapperOffersV2.DapperOffer>(from: DapperOffersV2.DapperOffersStoragePath) == nil {
48            signer.storage.save(<- DapperOffersV2.createDapperOffer(), to: DapperOffersV2.DapperOffersStoragePath)
49            signer.capabilities.unpublish(DapperOffersV2.DapperOffersPublicPath)
50            signer.capabilities.publish(
51                signer.capabilities.storage.issue<&DapperOffersV2.DapperOffer>(DapperOffersV2.DapperOffersStoragePath),
52                at: DapperOffersV2.DapperOffersPublicPath
53            )
54        }
55
56        // Get authorized reference to the DapperOffers resource
57        self.dapperOfferRef = signer.storage.borrow<auth(DapperOffersV2.Manager) &DapperOffersV2.DapperOffer>(from: DapperOffersV2.DapperOffersStoragePath)
58            ?? panic("Could not borrow DapperOffersV2.DapperOffer")
59
60        // Create authorized capability to the DapperOffers resource and add to the dapper account to allow cancelling on behalf of the signer (e.g., balance got too low)
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        dapper.capabilities.borrow<&DapperOffersV2.DapperOffer>(/public/DapperOffersV2)!.addProxyCapability(
75            account: signer.address,
76            cap: self.proxyManagerCap,
77        )
78
79    
80        // Create authorized capability to withdraw from the dapper account's DUC vault
81        let ducWithdrawCapPath = /storage/DUCWithdrawCapabilityForOffers
82        var ducWithdrawCap = dapper.storage.copy<Capability<auth(FungibleToken.Withdraw) &{FungibleToken.Vault}>>(from: ducWithdrawCapPath)
83        if ducWithdrawCap == nil || !ducWithdrawCap!.check() {
84            self.ducWithdrawCap = dapper.capabilities.storage.issue<auth(FungibleToken.Withdraw) &{FungibleToken.Vault}>(/storage/dapperUtilityCoinVault)
85            // save capability to storage
86            dapper.capabilities.storage.getController(byCapabilityID: self.ducWithdrawCap.id)!.setTag("OffersDUCWithdrawCap")
87            dapper.storage.save(
88                self.ducWithdrawCap,
89                to: ducWithdrawCapPath
90            )
91        } else{
92            self.ducWithdrawCap = ducWithdrawCap!
93        }
94
95        // Create and publish a new Resolver resource if the signer account doesn't already have one
96        if signer.storage.borrow<&Resolver.OfferResolver>(from: /storage/OfferResolver) == nil {
97            signer.storage.save(<- Resolver.createResolver(), to: /storage/OfferResolver)
98            signer.capabilities.unpublish(/public/OfferResolver)
99            signer.capabilities.publish(
100                signer.capabilities.storage.issue<&Resolver.OfferResolver>(/storage/OfferResolver),
101                at: /public/OfferResolver
102            )
103        }
104
105        // Get the Resolver capability
106        self.resolverCap = signer.capabilities.get<&{Resolver.ResolverPublic}>(/public/OfferResolver)
107    }
108
109    // Validate transaction parameters
110    pre {
111        (royalties[0xe4cf4bdc1751c65d] == 0.05000000 * amount): "Missing or mis-typed royalty information"
112        (royalties.keys.length == 1): "please provide only one royalty address"
113        (offerParamsString.containsKey("editionId")): "editionId missing from offerParamsString"
114        (offerParamsString.containsKey("_type")): "Invalid offerParamsString"
115    }
116
117    execute {
118        // Create royalties list for the offer
119        var royaltysList: [OffersV2.Royalty] = []
120        for key in royalties.keys {
121            royaltysList.append(OffersV2.Royalty(
122                receiver: getAccount(key).capabilities.get<&{FungibleToken.Receiver}>(/public/dapperUtilityCoinReceiver)!,
123                amount: royalties[key]!
124            ))
125        }
126
127        // Add offer parameters
128        offerParamsString.insert(key: "typeId", "Type<@AllDay.NFT>()")
129        offerParamsString.insert(key: "resolver", Resolver.ResolverType.EditionIdAndSerialNumberTraits.rawValue.toString())
130        var offerType = "EDITION"
131        if offerParamsString.containsKey("serialNumber"){
132            offerType = "NFT"
133        }
134        offerParamsString.insert(key: "_type", offerType)
135
136        // Create the offer
137        self.dapperOfferRef.createOffer(
138            vaultRefCapability: self.ducWithdrawCap,
139            nftReceiverCapability: self.nftReceiver!,
140            nftType: Type<@AllDay.NFT>(),
141            amount: amount,
142            royalties: royaltysList,
143            offerParamsString: offerParamsString,
144            offerParamsUFix64: {},
145            offerParamsUInt64: {},
146            resolverCapability: self.resolverCap
147        )
148    }
149}