Smart Contract

JollyJokersMinter

A.699bf284101a76f1.JollyJokersMinter

Deployed

17h ago
Feb 28, 2026, 02:29:50 AM UTC

Dependents

0 imports
1// SPDX-License-Identifier: MIT
2import JollyJokers from 0x699bf284101a76f1
3import FungibleToken from 0xf233dcee88fe0abe
4import NonFungibleToken from 0x1d7e57aa55817448
5import DapperUtilityCoin from 0xead892083b3e2c6c
6
7access(all) contract JollyJokersMinter {
8
9  access(all) event ContractInitialized()
10
11  access(all) let AdminStoragePath: StoragePath
12  access(all) var preSalePriceInDUC: UFix64
13  access(all) var publicSalePriceInDUC: UFix64
14
15  access(all) var preSaleMintLimitPerTx: UInt64
16  access(all) var publicSaleMintLimitPerTx: UInt64
17
18  access(self) var whitelistedAccounts: {Address: UInt64}
19
20  access(all) fun mintPreOrderNFTWithDUC(buyer: Address, paymentVault: @{FungibleToken.Vault}, merchantAccount: Address, numberOfTokens: UInt64) {
21    pre {
22      JollyJokersMinter.whitelistedAccounts[buyer]! >= 1:
23        "Requesting account is not whitelisted"
24      numberOfTokens <= JollyJokersMinter.preSaleMintLimitPerTx:
25        "purchaseAmount too large"
26      JollyJokersMinter.whitelistedAccounts[buyer]! >= numberOfTokens:
27        "purchaseAmount exeeds allowed whitelist spots"
28      paymentVault.balance >= UFix64(numberOfTokens) * JollyJokersMinter.preSalePriceInDUC:
29        "Insufficient payment amount."
30      paymentVault.getType() == Type<@DapperUtilityCoin.Vault>():
31        "payment type not DapperUtilityCoin.Vault."
32    }
33
34    let minter = self.account.storage.borrow<&JollyJokers.NFTMinter>(from: JollyJokers.MinterStoragePath)
35      ?? panic("Unable to borrow reference to the JJ NFTMinter")
36
37    // Get DUC receiver reference of JollyJokers merchant account
38    let merchantDUCReceiverRef = getAccount(merchantAccount).capabilities.get<&{FungibleToken.Receiver}>(/public/dapperUtilityCoinReceiver)
39      assert(merchantDUCReceiverRef.borrow() != nil, message: "Missing or mis-typed merchant DUC receiver")
40    // Deposit DUC to JollyJokers merchant account DUC Vault (it's then forwarded to the main DUC contract afterwards)
41    merchantDUCReceiverRef.borrow()!.deposit(from: <-paymentVault)
42
43    // Get buyer collection public to receive JollyJokers
44    let recipient: &Account = getAccount(buyer)
45    let NFTReceiver: &{NonFungibleToken.CollectionPublic} = recipient.capabilities.borrow<&{NonFungibleToken.CollectionPublic}>(JollyJokers.CollectionPublicPath)
46      ?? panic("Could not get receiver reference to the NFT Collection")
47
48    // Mint JollyJokers NFTs per purchaseAmount
49    var mintCounter = numberOfTokens
50    while(mintCounter > 0) {
51      minter.mintNFT(recipient: NFTReceiver)
52      mintCounter = mintCounter - 1
53    }
54
55    // Empty whitelist spot
56    if (JollyJokersMinter.whitelistedAccounts[buyer]! - numberOfTokens == 0) {
57      JollyJokersMinter.whitelistedAccounts.remove(key: buyer)
58    } else {
59      JollyJokersMinter.whitelistedAccounts[buyer] = JollyJokersMinter.whitelistedAccounts[buyer]! - numberOfTokens
60    }
61  }
62
63  access(all) fun mintPublicNFTWithDUC(buyer: Address, paymentVault: @{FungibleToken.Vault}, merchantAccount: Address, numberOfTokens: UInt64) {
64    pre {
65      numberOfTokens <= JollyJokersMinter.publicSaleMintLimitPerTx:
66        "purchaseAmount too large"
67      paymentVault.getType() == Type<@DapperUtilityCoin.Vault>():
68        "payment type not DapperUtilityCoin.Vault."
69    }
70
71    let price = JollyJokersMinter.getPriceForAddress(addr: buyer)
72    assert(paymentVault.balance >= price * UFix64(numberOfTokens), message: "Insufficient payment amount.")
73
74    let minter = self.account.storage.borrow<&JollyJokers.NFTMinter>(from: JollyJokers.MinterStoragePath)
75      ?? panic("Unable to borrow reference to the JJ NFTMinter")
76
77    // Get DUC receiver reference of JollyJokers merchant account
78    let merchantDUCReceiverRef = getAccount(merchantAccount).capabilities.get<&{FungibleToken.Receiver}>(/public/dapperUtilityCoinReceiver)
79      assert(merchantDUCReceiverRef.borrow() != nil, message: "Missing or mis-typed merchant DUC receiver")
80    // Deposit DUC to JollyJokers merchant account DUC Vault (it's then forwarded to the main DUC contract afterwards)
81    merchantDUCReceiverRef.borrow()!.deposit(from: <-paymentVault)
82
83    // Get buyer collection public to receive JollyJokers
84    let recipient = getAccount(buyer)
85    let NFTReceiver = recipient.capabilities.borrow<&{NonFungibleToken.CollectionPublic}>(JollyJokers.CollectionPublicPath)
86      ?? panic("Could not get receiver reference to the NFT Collection")
87
88    // Mint JollyJokers NFTs per purchaseAmount
89    var mintCounter = numberOfTokens
90    while(mintCounter > 0) {
91      minter.mintNFT(recipient: NFTReceiver)
92      mintCounter = mintCounter - 1
93    }
94  }
95
96  access(all) resource Admin {
97    access(all) fun addWhiteListAddress(address: Address, amount: UInt64) {
98      pre {
99        amount <= 6:
100          "Unable to allocate more than 6 whitelist spots"
101      }
102      JollyJokersMinter.whitelistedAccounts[address] = amount
103    }
104
105    access(all) fun removeWhiteListAddress(address: Address) {
106      pre {
107        JollyJokersMinter.whitelistedAccounts[address] != nil:
108          "Provided Address is not whitelisted"
109      }
110      JollyJokersMinter.whitelistedAccounts.remove(key: address)
111    }
112
113    access(all) fun pruneWhitelist() {
114      JollyJokersMinter.whitelistedAccounts = {}
115    }
116
117    access(all) fun updateWhiteListAddressAmount(address: Address, amount: UInt64) {
118      pre {
119        JollyJokersMinter.whitelistedAccounts[address] != nil:
120          "Provided Address is not whitelisted"
121      }
122      JollyJokersMinter.whitelistedAccounts[address] = amount
123    }
124
125    access(all) fun updatePreSalePriceInDUC(price: UFix64) {
126      JollyJokersMinter.preSalePriceInDUC = price
127    }
128
129    access(all) fun updatePublicSalePriceInDUC(price: UFix64) {
130      JollyJokersMinter.publicSalePriceInDUC = price
131    }
132  }
133
134  access(all) fun getWhitelistedAccounts(): {Address: UInt64} {
135    return JollyJokersMinter.whitelistedAccounts
136  }
137
138  access(all) fun getWhitelistSpotsForAddress(address: Address): UInt64 {
139    return JollyJokersMinter.whitelistedAccounts[address] ?? 0
140  }
141
142  access(all) fun getPriceForAddress(addr: Address): UFix64 {
143      // if address has a joker, price is 99.0
144      // does this address have any jokers?
145      let cap = getAccount(addr).capabilities.get<&{NonFungibleToken.CollectionPublic}>(JollyJokers.CollectionPublicPath)
146      if !cap.check() {
147          return JollyJokersMinter.publicSalePriceInDUC
148      }
149
150      let ids = cap.borrow()!.getIDs()
151      if ids.length > 0 {
152          return 99.0
153      }
154
155      // otherwise, price is JollyJokersMinter.publicSalePriceInDUC
156      return JollyJokersMinter.publicSalePriceInDUC
157  }
158
159  init() {
160    self.AdminStoragePath = /storage/JollyJokersWhitelistMinterAdmin
161
162    self.preSalePriceInDUC = 299.00
163    self.publicSalePriceInDUC = 299.00
164
165    self.preSaleMintLimitPerTx = 6
166    self.publicSaleMintLimitPerTx = 10
167
168    self.whitelistedAccounts = {}
169
170    let admin <- create Admin()
171    self.account.storage.save(<-admin, to: self.AdminStoragePath)
172
173    emit ContractInitialized()
174  }
175}
176