@silvana-one/nft 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. package/README.md +1400 -0
  2. package/dist/node/admin/advanced.d.ts +469 -0
  3. package/dist/node/admin/advanced.js +525 -0
  4. package/dist/node/admin/advanced.js.map +1 -0
  5. package/dist/node/admin/index.d.ts +1 -0
  6. package/dist/node/admin/index.js +2 -0
  7. package/dist/node/admin/index.js.map +1 -0
  8. package/dist/node/contracts/admin.d.ts +140 -0
  9. package/dist/node/contracts/admin.js +336 -0
  10. package/dist/node/contracts/admin.js.map +1 -0
  11. package/dist/node/contracts/collection.d.ts +551 -0
  12. package/dist/node/contracts/collection.js +1049 -0
  13. package/dist/node/contracts/collection.js.map +1 -0
  14. package/dist/node/contracts/index.d.ts +3 -0
  15. package/dist/node/contracts/index.js +4 -0
  16. package/dist/node/contracts/index.js.map +1 -0
  17. package/dist/node/contracts/nft.d.ts +76 -0
  18. package/dist/node/contracts/nft.js +329 -0
  19. package/dist/node/contracts/nft.js.map +1 -0
  20. package/dist/node/contracts.d.ts +709 -0
  21. package/dist/node/contracts.js +61 -0
  22. package/dist/node/contracts.js.map +1 -0
  23. package/dist/node/index.cjs +5032 -0
  24. package/dist/node/index.d.ts +8 -0
  25. package/dist/node/index.js +9 -0
  26. package/dist/node/index.js.map +1 -0
  27. package/dist/node/interfaces/admin.d.ts +102 -0
  28. package/dist/node/interfaces/admin.js +2 -0
  29. package/dist/node/interfaces/admin.js.map +1 -0
  30. package/dist/node/interfaces/approval.d.ts +57 -0
  31. package/dist/node/interfaces/approval.js +62 -0
  32. package/dist/node/interfaces/approval.js.map +1 -0
  33. package/dist/node/interfaces/collection.d.ts +57 -0
  34. package/dist/node/interfaces/collection.js +2 -0
  35. package/dist/node/interfaces/collection.js.map +1 -0
  36. package/dist/node/interfaces/encoding.d.ts +24 -0
  37. package/dist/node/interfaces/encoding.js +32 -0
  38. package/dist/node/interfaces/encoding.js.map +1 -0
  39. package/dist/node/interfaces/events.d.ts +833 -0
  40. package/dist/node/interfaces/events.js +106 -0
  41. package/dist/node/interfaces/events.js.map +1 -0
  42. package/dist/node/interfaces/index.d.ts +10 -0
  43. package/dist/node/interfaces/index.js +11 -0
  44. package/dist/node/interfaces/index.js.map +1 -0
  45. package/dist/node/interfaces/ownable.d.ts +94 -0
  46. package/dist/node/interfaces/ownable.js +12 -0
  47. package/dist/node/interfaces/ownable.js.map +1 -0
  48. package/dist/node/interfaces/owner.d.ts +61 -0
  49. package/dist/node/interfaces/owner.js +101 -0
  50. package/dist/node/interfaces/owner.js.map +1 -0
  51. package/dist/node/interfaces/pausable.d.ts +74 -0
  52. package/dist/node/interfaces/pausable.js +14 -0
  53. package/dist/node/interfaces/pausable.js.map +1 -0
  54. package/dist/node/interfaces/types.d.ts +2297 -0
  55. package/dist/node/interfaces/types.js +507 -0
  56. package/dist/node/interfaces/types.js.map +1 -0
  57. package/dist/node/interfaces/update.d.ts +53 -0
  58. package/dist/node/interfaces/update.js +58 -0
  59. package/dist/node/interfaces/update.js.map +1 -0
  60. package/dist/node/marketplace/auction.d.ts +775 -0
  61. package/dist/node/marketplace/auction.js +430 -0
  62. package/dist/node/marketplace/auction.js.map +1 -0
  63. package/dist/node/marketplace/bid.d.ts +254 -0
  64. package/dist/node/marketplace/bid.js +260 -0
  65. package/dist/node/marketplace/bid.js.map +1 -0
  66. package/dist/node/marketplace/index.d.ts +5 -0
  67. package/dist/node/marketplace/index.js +6 -0
  68. package/dist/node/marketplace/index.js.map +1 -0
  69. package/dist/node/marketplace/nft-shares.d.ts +1083 -0
  70. package/dist/node/marketplace/nft-shares.js +398 -0
  71. package/dist/node/marketplace/nft-shares.js.map +1 -0
  72. package/dist/node/marketplace/offer.d.ts +192 -0
  73. package/dist/node/marketplace/offer.js +132 -0
  74. package/dist/node/marketplace/offer.js.map +1 -0
  75. package/dist/node/marketplace/types.d.ts +374 -0
  76. package/dist/node/marketplace/types.js +33 -0
  77. package/dist/node/marketplace/types.js.map +1 -0
  78. package/dist/node/metadata/index.d.ts +3 -0
  79. package/dist/node/metadata/index.js +4 -0
  80. package/dist/node/metadata/index.js.map +1 -0
  81. package/dist/node/metadata/metadata.d.ts +337 -0
  82. package/dist/node/metadata/metadata.js +439 -0
  83. package/dist/node/metadata/metadata.js.map +1 -0
  84. package/dist/node/metadata/text.d.ts +44 -0
  85. package/dist/node/metadata/text.js +42 -0
  86. package/dist/node/metadata/text.js.map +1 -0
  87. package/dist/node/metadata/tree.d.ts +75 -0
  88. package/dist/node/metadata/tree.js +85 -0
  89. package/dist/node/metadata/tree.js.map +1 -0
  90. package/dist/node/vk.d.ts +42 -0
  91. package/dist/node/vk.js +45 -0
  92. package/dist/node/vk.js.map +1 -0
  93. package/dist/node/zkprogram-example/game.d.ts +76 -0
  94. package/dist/node/zkprogram-example/game.js +108 -0
  95. package/dist/node/zkprogram-example/game.js.map +1 -0
  96. package/dist/node/zkprogram-example/index.d.ts +2 -0
  97. package/dist/node/zkprogram-example/index.js +3 -0
  98. package/dist/node/zkprogram-example/index.js.map +1 -0
  99. package/dist/node/zkprogram-example/update.d.ts +76 -0
  100. package/dist/node/zkprogram-example/update.js +85 -0
  101. package/dist/node/zkprogram-example/update.js.map +1 -0
  102. package/dist/tsconfig.tsbuildinfo +1 -0
  103. package/dist/tsconfig.web.tsbuildinfo +1 -0
  104. package/dist/web/admin/advanced.d.ts +469 -0
  105. package/dist/web/admin/advanced.js +525 -0
  106. package/dist/web/admin/advanced.js.map +1 -0
  107. package/dist/web/admin/index.d.ts +1 -0
  108. package/dist/web/admin/index.js +2 -0
  109. package/dist/web/admin/index.js.map +1 -0
  110. package/dist/web/contracts/admin.d.ts +140 -0
  111. package/dist/web/contracts/admin.js +336 -0
  112. package/dist/web/contracts/admin.js.map +1 -0
  113. package/dist/web/contracts/collection.d.ts +551 -0
  114. package/dist/web/contracts/collection.js +1049 -0
  115. package/dist/web/contracts/collection.js.map +1 -0
  116. package/dist/web/contracts/index.d.ts +3 -0
  117. package/dist/web/contracts/index.js +4 -0
  118. package/dist/web/contracts/index.js.map +1 -0
  119. package/dist/web/contracts/nft.d.ts +76 -0
  120. package/dist/web/contracts/nft.js +329 -0
  121. package/dist/web/contracts/nft.js.map +1 -0
  122. package/dist/web/contracts.d.ts +709 -0
  123. package/dist/web/contracts.js +61 -0
  124. package/dist/web/contracts.js.map +1 -0
  125. package/dist/web/index.d.ts +8 -0
  126. package/dist/web/index.js +9 -0
  127. package/dist/web/index.js.map +1 -0
  128. package/dist/web/interfaces/admin.d.ts +102 -0
  129. package/dist/web/interfaces/admin.js +2 -0
  130. package/dist/web/interfaces/admin.js.map +1 -0
  131. package/dist/web/interfaces/approval.d.ts +57 -0
  132. package/dist/web/interfaces/approval.js +62 -0
  133. package/dist/web/interfaces/approval.js.map +1 -0
  134. package/dist/web/interfaces/collection.d.ts +57 -0
  135. package/dist/web/interfaces/collection.js +2 -0
  136. package/dist/web/interfaces/collection.js.map +1 -0
  137. package/dist/web/interfaces/encoding.d.ts +24 -0
  138. package/dist/web/interfaces/encoding.js +32 -0
  139. package/dist/web/interfaces/encoding.js.map +1 -0
  140. package/dist/web/interfaces/events.d.ts +833 -0
  141. package/dist/web/interfaces/events.js +106 -0
  142. package/dist/web/interfaces/events.js.map +1 -0
  143. package/dist/web/interfaces/index.d.ts +10 -0
  144. package/dist/web/interfaces/index.js +11 -0
  145. package/dist/web/interfaces/index.js.map +1 -0
  146. package/dist/web/interfaces/ownable.d.ts +94 -0
  147. package/dist/web/interfaces/ownable.js +12 -0
  148. package/dist/web/interfaces/ownable.js.map +1 -0
  149. package/dist/web/interfaces/owner.d.ts +61 -0
  150. package/dist/web/interfaces/owner.js +101 -0
  151. package/dist/web/interfaces/owner.js.map +1 -0
  152. package/dist/web/interfaces/pausable.d.ts +74 -0
  153. package/dist/web/interfaces/pausable.js +14 -0
  154. package/dist/web/interfaces/pausable.js.map +1 -0
  155. package/dist/web/interfaces/types.d.ts +2297 -0
  156. package/dist/web/interfaces/types.js +507 -0
  157. package/dist/web/interfaces/types.js.map +1 -0
  158. package/dist/web/interfaces/update.d.ts +53 -0
  159. package/dist/web/interfaces/update.js +58 -0
  160. package/dist/web/interfaces/update.js.map +1 -0
  161. package/dist/web/marketplace/auction.d.ts +775 -0
  162. package/dist/web/marketplace/auction.js +430 -0
  163. package/dist/web/marketplace/auction.js.map +1 -0
  164. package/dist/web/marketplace/bid.d.ts +254 -0
  165. package/dist/web/marketplace/bid.js +260 -0
  166. package/dist/web/marketplace/bid.js.map +1 -0
  167. package/dist/web/marketplace/index.d.ts +5 -0
  168. package/dist/web/marketplace/index.js +6 -0
  169. package/dist/web/marketplace/index.js.map +1 -0
  170. package/dist/web/marketplace/nft-shares.d.ts +1083 -0
  171. package/dist/web/marketplace/nft-shares.js +398 -0
  172. package/dist/web/marketplace/nft-shares.js.map +1 -0
  173. package/dist/web/marketplace/offer.d.ts +192 -0
  174. package/dist/web/marketplace/offer.js +132 -0
  175. package/dist/web/marketplace/offer.js.map +1 -0
  176. package/dist/web/marketplace/types.d.ts +374 -0
  177. package/dist/web/marketplace/types.js +33 -0
  178. package/dist/web/marketplace/types.js.map +1 -0
  179. package/dist/web/metadata/index.d.ts +3 -0
  180. package/dist/web/metadata/index.js +4 -0
  181. package/dist/web/metadata/index.js.map +1 -0
  182. package/dist/web/metadata/metadata.d.ts +337 -0
  183. package/dist/web/metadata/metadata.js +439 -0
  184. package/dist/web/metadata/metadata.js.map +1 -0
  185. package/dist/web/metadata/text.d.ts +44 -0
  186. package/dist/web/metadata/text.js +42 -0
  187. package/dist/web/metadata/text.js.map +1 -0
  188. package/dist/web/metadata/tree.d.ts +75 -0
  189. package/dist/web/metadata/tree.js +85 -0
  190. package/dist/web/metadata/tree.js.map +1 -0
  191. package/dist/web/vk.d.ts +42 -0
  192. package/dist/web/vk.js +45 -0
  193. package/dist/web/vk.js.map +1 -0
  194. package/dist/web/zkprogram-example/game.d.ts +76 -0
  195. package/dist/web/zkprogram-example/game.js +108 -0
  196. package/dist/web/zkprogram-example/game.js.map +1 -0
  197. package/dist/web/zkprogram-example/index.d.ts +2 -0
  198. package/dist/web/zkprogram-example/index.js +3 -0
  199. package/dist/web/zkprogram-example/index.js.map +1 -0
  200. package/dist/web/zkprogram-example/update.d.ts +76 -0
  201. package/dist/web/zkprogram-example/update.js +85 -0
  202. package/dist/web/zkprogram-example/update.js.map +1 -0
  203. package/package.json +65 -0
  204. package/src/admin/advanced.ts +601 -0
  205. package/src/admin/index.ts +1 -0
  206. package/src/contracts/admin.ts +301 -0
  207. package/src/contracts/collection.ts +1172 -0
  208. package/src/contracts/index.ts +3 -0
  209. package/src/contracts/nft.ts +344 -0
  210. package/src/contracts.ts +107 -0
  211. package/src/index.ts +8 -0
  212. package/src/interfaces/admin.ts +127 -0
  213. package/src/interfaces/approval.ts +99 -0
  214. package/src/interfaces/collection.ts +68 -0
  215. package/src/interfaces/encoding.ts +32 -0
  216. package/src/interfaces/events.ts +115 -0
  217. package/src/interfaces/index.ts +10 -0
  218. package/src/interfaces/ownable.ts +32 -0
  219. package/src/interfaces/owner.ts +143 -0
  220. package/src/interfaces/pausable.ts +41 -0
  221. package/src/interfaces/types.ts +623 -0
  222. package/src/interfaces/update.ts +104 -0
  223. package/src/marketplace/auction.ts +527 -0
  224. package/src/marketplace/bid.ts +294 -0
  225. package/src/marketplace/index.ts +5 -0
  226. package/src/marketplace/nft-shares.ts +388 -0
  227. package/src/marketplace/offer.ts +153 -0
  228. package/src/marketplace/types.ts +33 -0
  229. package/src/metadata/index.ts +3 -0
  230. package/src/metadata/metadata.ts +603 -0
  231. package/src/metadata/text.ts +60 -0
  232. package/src/metadata/tree.ts +128 -0
  233. package/src/vk.ts +64 -0
  234. package/src/zkprogram-example/game.ts +136 -0
  235. package/src/zkprogram-example/index.ts +2 -0
  236. package/src/zkprogram-example/update.ts +98 -0
@@ -0,0 +1,1049 @@
1
+ /**
2
+ * The NFT Collection Contract is responsible for managing a collection of NFTs.
3
+ * It handles minting new NFTs, transferring ownership, buying, selling,
4
+ * and interfacing with Admin Contracts for additional functionalities.
5
+ *
6
+ * @module CollectionContract
7
+ */
8
+ import { __decorate, __metadata } from "tslib";
9
+ import { Field, PublicKey, AccountUpdate, Bool, method, state, State, Permissions, TokenContract, VerificationKey, UInt32, UInt64, Mina, Provable, } from "o1js";
10
+ import { NFT } from "./nft.js";
11
+ import { MintParams, MintRequest, TransferParams, CollectionData, NFTUpdateProof, NFTStateStruct, MintEvent, TransferEvent, ApproveEvent, UpgradeVerificationKeyEvent, LimitMintingEvent, PauseNFTEvent, PauseEvent, OwnershipChangeEvent, UInt64Option, MAX_ROYALTY_FEE, TransferExtendedParams, } from "../interfaces/index.js";
12
+ import { nftVerificationKeys } from "../vk.js";
13
+ export { CollectionFactory, CollectionErrors };
14
+ const CollectionErrors = {
15
+ wrongMasterNFTaddress: "Master NFT address should be the same as the collection address",
16
+ transferNotAllowed: "Transfers of tokens are not allowed, change the owner instead",
17
+ collectionPaused: "Collection is currently paused",
18
+ cannotMintMasterNFT: "Only the creator can mint the Master NFT",
19
+ cannotMint: "Admin contract did not provide permission to mint",
20
+ noPermissionToPause: "Not allowed to pause collection",
21
+ noPermissionToResume: "Not allowed to resume collection",
22
+ collectionNotPaused: "Collection is not paused",
23
+ transferApprovalRequired: "Transfer approval is required",
24
+ noPermissionToChangeName: "Not allowed to change collection name",
25
+ noPermissionToChangeBaseUri: "Not allowed to change collection base URI",
26
+ noPermissionToChangeCreator: "Not allowed to change collection creator",
27
+ noPermissionToChangeRoyalty: "Not allowed to change royalty fee",
28
+ noPermissionToChangeTransferFee: "Not allowed to change transfer fee",
29
+ noPermissionToSetAdmin: "Not allowed to set admin contract",
30
+ cannotUpgradeVerificationKey: "Cannot upgrade verification key",
31
+ upgradeContractAddressNotSet: "Upgrade contract address is not set",
32
+ adminContractAddressNotSet: "Admin contract address is not set",
33
+ onlyOwnerCanUpgradeVerificationKey: "Only owner can upgrade verification key",
34
+ invalidRoyaltyFee: "Royalty fee is too high, cannot be more than 100%",
35
+ invalidOracleAddress: "Oracle address is invalid",
36
+ };
37
+ /**
38
+ * Creates a new NFT Collection Contract class.
39
+ *
40
+ * @param params - Constructor parameters including admin and upgrade contracts, and network ID.
41
+ * @returns The Collection class extending TokenContract and implementing required interfaces.
42
+ */
43
+ function CollectionFactory(params) {
44
+ const { adminContract, ownerContract, approvalContract, updateContract } = params;
45
+ /**
46
+ * The NFT Collection Contract manages a collection of NFTs.
47
+ * It handles minting, transferring, buying, selling, and integrates with Admin Contracts.
48
+ */
49
+ class Collection extends TokenContract {
50
+ constructor() {
51
+ super(...arguments);
52
+ /** The name of the NFT collection. */
53
+ this.collectionName = State();
54
+ /** The public key of the creator of the collection. */
55
+ this.creator = State();
56
+ /** The public key of the Admin Contract. */
57
+ this.admin = State();
58
+ /** The base URL for the metadata of the NFTs in the collection. */
59
+ this.baseURL = State();
60
+ /**
61
+ * A packed data field containing additional collection parameters,
62
+ * such as flags and fee configurations.
63
+ */
64
+ this.packedData = State();
65
+ /**
66
+ * Defines the events emitted by the contract.
67
+ */
68
+ this.events = {
69
+ mint: MintEvent,
70
+ update: PublicKey,
71
+ transfer: TransferEvent,
72
+ approve: ApproveEvent,
73
+ upgradeNFTVerificationKey: UpgradeVerificationKeyEvent,
74
+ upgradeVerificationKey: Field,
75
+ limitMinting: LimitMintingEvent,
76
+ pause: PauseEvent,
77
+ resume: PauseEvent,
78
+ pauseNFT: PauseNFTEvent,
79
+ resumeNFT: PauseNFTEvent,
80
+ ownershipChange: OwnershipChangeEvent,
81
+ setName: Field,
82
+ setBaseURL: Field,
83
+ setRoyaltyFee: UInt32,
84
+ setTransferFee: UInt64,
85
+ setAdmin: PublicKey,
86
+ };
87
+ }
88
+ /**
89
+ * Deploys the NFT Collection Contract with the initial settings.
90
+ *
91
+ * @param props - Deployment properties including collection name, creator, admin, baseURL, symbol, and URL.
92
+ */
93
+ async deploy(props) {
94
+ await super.deploy(props);
95
+ this.collectionName.set(props.collectionName);
96
+ this.creator.set(props.creator);
97
+ this.admin.set(props.admin);
98
+ this.baseURL.set(props.baseURL);
99
+ // Set the collection to be paused by default
100
+ this.packedData.set(CollectionData.new({
101
+ isPaused: true,
102
+ }).pack());
103
+ this.account.zkappUri.set(props.url);
104
+ this.account.tokenSymbol.set(props.symbol);
105
+ this.account.permissions.set({
106
+ ...Permissions.default(),
107
+ setVerificationKey: Permissions.VerificationKey.proofDuringCurrentVersion(),
108
+ setPermissions: Permissions.impossible(),
109
+ access: Permissions.proof(),
110
+ send: Permissions.proof(),
111
+ setZkappUri: Permissions.none(),
112
+ setTokenSymbol: Permissions.none(),
113
+ });
114
+ }
115
+ /**
116
+ * Initializes the collection with a master NFT and initial data.
117
+ *
118
+ * @param masterNFT - The master NFT parameters.
119
+ * @param collectionData - Initial collection data including flags and configurations.
120
+ */
121
+ async initialize(masterNFT, collectionData) {
122
+ this.account.provedState.requireEquals(Bool(false));
123
+ collectionData.royaltyFee.assertLessThanOrEqual(UInt32.from(MAX_ROYALTY_FEE), CollectionErrors.invalidRoyaltyFee);
124
+ this.packedData.set(collectionData.pack());
125
+ masterNFT.address
126
+ .equals(this.address)
127
+ .assertTrue(CollectionErrors.wrongMasterNFTaddress);
128
+ await this._mint(masterNFT);
129
+ }
130
+ /**
131
+ * Overrides the approveBase method to prevent transfers of tokens.
132
+ *
133
+ * @param forest - The account update forest.
134
+ */
135
+ async approveBase(forest) {
136
+ throw Error(CollectionErrors.transferNotAllowed);
137
+ }
138
+ /**
139
+ * Retrieves the Admin Contract instance.
140
+ *
141
+ * @returns The Admin Contract instance implementing NFTAdminBase.
142
+ */
143
+ getAdminContract() {
144
+ const admin = this.admin.getAndRequireEquals();
145
+ const AdminContract = adminContract();
146
+ return new AdminContract(admin);
147
+ }
148
+ /**
149
+ * Retrieves the NFT Owner Contract instance.
150
+ *
151
+ * @returns The Owner Contract instance implementing NFTOwnerBase.
152
+ */
153
+ getOwnerContract(address) {
154
+ const OwnerContract = ownerContract();
155
+ return new OwnerContract(address);
156
+ }
157
+ /**
158
+ * Retrieves the NFT Approval Contract instance.
159
+ *
160
+ * @returns The Approval Contract instance implementing NFTApprovalBase.
161
+ */
162
+ getApprovalContract(address) {
163
+ const ApprovalContract = approvalContract();
164
+ return new ApprovalContract(address);
165
+ }
166
+ /**
167
+ * Retrieves the NFT Update Contract instance.
168
+ *
169
+ * @returns The Update Contract instance implementing NFTUpdateBase.
170
+ */
171
+ getUpdateContract(address) {
172
+ const UpdateContract = updateContract();
173
+ return new UpdateContract(address);
174
+ }
175
+ /**
176
+ * Ensures that the transaction is authorized by the creator.
177
+ *
178
+ * @returns The AccountUpdate of the creator.
179
+ */
180
+ async ensureCreatorSignature() {
181
+ const creator = this.creator.getAndRequireEquals();
182
+ const creatorUpdate = AccountUpdate.createSigned(creator);
183
+ creatorUpdate.body.useFullCommitment = Bool(true); // Prevent memo and fee change
184
+ return creatorUpdate;
185
+ }
186
+ /**
187
+ * Ensures that the transaction is authorized by the NFT owner
188
+ *
189
+ * @returns The AccountUpdate of the NFT owner.
190
+ */
191
+ async ensureOwnerSignature(owner) {
192
+ const ownerUpdate = AccountUpdate.createSigned(owner);
193
+ ownerUpdate.body.useFullCommitment = Bool(true); // Prevent memo and fee change
194
+ return ownerUpdate;
195
+ }
196
+ /**
197
+ * Ensures that the collection is not paused.
198
+ *
199
+ * @returns The packed data of the collection.
200
+ */
201
+ async ensureNotPaused() {
202
+ CollectionData.isPaused(this.packedData.getAndRequireEquals()).assertFalse(CollectionErrors.collectionPaused);
203
+ }
204
+ /**
205
+ * Mints a new NFT directly by the creator.
206
+ *
207
+ * This method allows the creator of the collection to mint an NFT without requiring approval
208
+ * from the admin contract. It ensures that the collection is not paused and that the caller
209
+ * is the creator of the collection. A fee of 1 MINA is deducted from the creator's balance
210
+ * to cover the cost of creating a new account.
211
+ *
212
+ * We do not constrain here the address of the NFT to allow for the Master NFT to be minted.
213
+ * The Master NFT is the NFT with the same address as the Collection contract and it holds
214
+ * the metadata for the collection. It can be minted only by the creator of the collection.
215
+ *
216
+ * @param params - The mint parameters containing details of the NFT to be minted.
217
+ */
218
+ async mintByCreator(params) {
219
+ CollectionData.mintingIsLimited(this.packedData.getAndRequireEquals()).assertFalse(CollectionErrors.cannotMint);
220
+ const creatorUpdate = await this.ensureCreatorSignature();
221
+ // Pay 1 MINA fee for a new account
222
+ creatorUpdate.balance.subInPlace(1_000_000_000);
223
+ await this._mint(params);
224
+ }
225
+ /**
226
+ * Mints a new NFT with approval.
227
+ *
228
+ * @param mintRequest - The minting request containing parameters and proofs.
229
+ */
230
+ async mint(mintRequest) {
231
+ CollectionData.mintingIsLimited(this.packedData.getAndRequireEquals()).assertFalse(CollectionErrors.cannotMint);
232
+ const adminContract = this.getAdminContract();
233
+ // The admin contract checks that the sender is allowed to mint
234
+ const mintParams = (await adminContract.canMint(mintRequest)).assertSome(CollectionErrors.cannotMint);
235
+ // Prevent minting the Master NFT using this method
236
+ mintParams.address
237
+ .equals(this.address)
238
+ .assertFalse(CollectionErrors.cannotMintMasterNFT);
239
+ await this._mint(mintParams);
240
+ }
241
+ /**
242
+ * Internal method to mint an NFT.
243
+ *
244
+ * @param params - The mint parameters.
245
+ * @param collectionData - The current collection data.
246
+ * @returns The MintEvent emitted.
247
+ */
248
+ async _mint(params) {
249
+ const { name, address, data, metadata, storage, metadataVerificationKeyHash, expiry, } = params;
250
+ this.network.globalSlotSinceGenesis.requireBetween(UInt32.zero, expiry);
251
+ data.version.assertEquals(UInt32.zero);
252
+ const packedData = data.pack();
253
+ const tokenId = this.deriveTokenId();
254
+ const update = AccountUpdate.createSigned(address, tokenId);
255
+ update.body.useFullCommitment = Bool(true); // Prevent memo and fee change
256
+ update.account.isNew.getAndRequireEquals().assertTrue();
257
+ // Mint 1 NFT
258
+ this.internal.mint({ address: update, amount: 1_000_000_000 });
259
+ const verificationKey = Provable.witness(VerificationKey, () => {
260
+ // This code does NOT create a constraint on the verification key
261
+ // as this witness can be replaced during runtime
262
+ // We use devnet to get future compatibility https://github.com/o1-labs/o1js/pull/1938
263
+ // As of writing this, 'testnet' is used in the o1js codebase
264
+ const networkId = Mina.getNetworkId() === "mainnet" ? "mainnet" : "devnet";
265
+ const verificationKey = new VerificationKey({
266
+ data: nftVerificationKeys[networkId].vk.NFT.data,
267
+ hash: Field(nftVerificationKeys[networkId].vk.NFT.hash),
268
+ });
269
+ const vkHash = NFT._verificationKey?.hash;
270
+ if (!verificationKey ||
271
+ !verificationKey.hash ||
272
+ !verificationKey.data)
273
+ throw Error("NFT verification key is incorrect");
274
+ if (vkHash &&
275
+ vkHash.equals(verificationKey.hash).toBoolean() === false)
276
+ throw Error("NFT verification key does not match the compiled verification key");
277
+ return verificationKey;
278
+ });
279
+ const mainnetVerificationKeyHash = Field(nftVerificationKeys.mainnet.vk.NFT.hash);
280
+ const devnetVerificationKeyHash = Field(nftVerificationKeys.devnet.vk.NFT.hash);
281
+ const isMainnet = Provable.witness(Bool, () => {
282
+ // This check does NOT create a constraint on the verification key
283
+ // as this witness can be replaced during runtime
284
+ // and is useful only for making sure that the verification key
285
+ // of the NFT will match the compiled verification key of the NFT
286
+ // at the time of the deployment of the Collection Contract
287
+ return Bool(Mina.getNetworkId() === "mainnet");
288
+ });
289
+ // We check that the verification key hash is the same as the one
290
+ // that was compiled at the time of the deployment
291
+ verificationKey.hash.assertEquals(Provable.if(isMainnet, mainnetVerificationKeyHash, devnetVerificationKeyHash));
292
+ update.body.update.verificationKey = {
293
+ isSome: Bool(true),
294
+ value: verificationKey,
295
+ };
296
+ update.body.update.permissions = {
297
+ isSome: Bool(true),
298
+ value: {
299
+ ...Permissions.default(),
300
+ // NFT cannot be sent to other accounts, only owner can be changed
301
+ send: Permissions.impossible(),
302
+ // Allow the upgrade authority to set the verification key
303
+ // even when there is no protocol upgrade
304
+ setVerificationKey: Permissions.VerificationKey.proofDuringCurrentVersion(),
305
+ setPermissions: Permissions.impossible(),
306
+ access: Permissions.proof(),
307
+ setZkappUri: Permissions.impossible(),
308
+ setTokenSymbol: Permissions.impossible(),
309
+ },
310
+ };
311
+ const initialState = new NFTStateStruct({
312
+ name,
313
+ metadata,
314
+ storage,
315
+ packedData,
316
+ metadataVerificationKeyHash,
317
+ });
318
+ update.body.update.appState = NFTStateStruct.toFields(initialState).map((field) => ({
319
+ isSome: Bool(true),
320
+ value: field,
321
+ }));
322
+ const event = new MintEvent({
323
+ initialState,
324
+ address,
325
+ });
326
+ this.emitEvent("mint", event);
327
+ return event;
328
+ }
329
+ /**
330
+ * Updates the NFT with admin approval.
331
+ *
332
+ * @param proof - The proof of the NFT update.
333
+ * @param vk - The verification key.
334
+ */
335
+ async update(proof, vk) {
336
+ await this._update(proof, vk);
337
+ }
338
+ /**
339
+ * Updates the NFT with admin approval and oracle approval.
340
+ *
341
+ * @param proof - The proof of the NFT update.
342
+ * @param vk - The verification key.
343
+ */
344
+ async updateWithOracle(proof, vk) {
345
+ // The oracle address is optional and can be empty, NFT ZkProgram can verify the address
346
+ // as it can be different for different NFTs
347
+ const oracleAddress = proof.publicInput.oracleAddress;
348
+ oracleAddress
349
+ .equals(PublicKey.empty())
350
+ .assertFalse(CollectionErrors.invalidOracleAddress);
351
+ const oracle = this.getUpdateContract(oracleAddress);
352
+ const canUpdate = await oracle.canUpdate(this.address, proof.publicInput.immutableState.address, proof.publicInput, proof.publicOutput);
353
+ canUpdate.assertTrue();
354
+ await this._update(proof, vk);
355
+ }
356
+ /**
357
+ * Updates the NFT with admin approval - internal method.
358
+ *
359
+ * @param proof - The proof of the NFT update.
360
+ * @param vk - The verification key.
361
+ */
362
+ async _update(proof, vk) {
363
+ await this.ensureNotPaused();
364
+ const adminContract = this.getAdminContract();
365
+ const canUpdate = await adminContract.canUpdate(proof.publicInput, proof.publicOutput);
366
+ canUpdate.assertTrue();
367
+ const creator = this.creator.getAndRequireEquals();
368
+ creator.assertEquals(proof.publicInput.creator);
369
+ const tokenId = this.deriveTokenId();
370
+ tokenId.assertEquals(proof.publicInput.immutableState.tokenId);
371
+ const nft = new NFT(proof.publicInput.immutableState.address, tokenId);
372
+ const metadataVerificationKeyHash = await nft.update(proof.publicInput, proof.publicOutput, creator);
373
+ // Verify the metadata update proof
374
+ metadataVerificationKeyHash.assertEquals(vk.hash);
375
+ proof.verify(vk);
376
+ this.emitEvent("update", proof.publicInput.immutableState.address);
377
+ }
378
+ /**
379
+ * Approves an address to transfer an NFT.
380
+ *
381
+ * @param nftAddress - The address of the NFT.
382
+ * @param approved - The approved public key.
383
+ */
384
+ async approveAddress(nftAddress, approved) {
385
+ await this.ensureNotPaused();
386
+ const tokenId = this.deriveTokenId();
387
+ const nft = new NFT(nftAddress, tokenId);
388
+ const owner = await nft.approveAddress(approved);
389
+ await this.ensureOwnerSignature(owner);
390
+ this.emitEvent("approve", new ApproveEvent({ nftAddress, approved }));
391
+ }
392
+ /**
393
+ * Transfers ownership of an NFT without admin approval.
394
+ *
395
+ * @param address - The address of the NFT.
396
+ * @param to - The recipient's public key.
397
+ */
398
+ async approveAddressByProof(nftAddress, approved) {
399
+ const tokenId = this.deriveTokenId();
400
+ const nft = new NFT(nftAddress, tokenId);
401
+ const owner = await nft.approveAddress(approved);
402
+ const ownerContract = this.getOwnerContract(owner);
403
+ const canApprove = await ownerContract.canApproveAddress(this.address, nftAddress, approved);
404
+ canApprove.assertTrue();
405
+ this.emitEvent("approve", new ApproveEvent({ nftAddress, approved }));
406
+ }
407
+ /**
408
+ * Transfers ownership of an NFT without admin approval.
409
+ * This method should be used by wallets for collections that do not require transfer approval
410
+ * and the owners of the NFTs which approve the transfer by signature
411
+ *
412
+ * @param address - The address of the NFT.
413
+ * @param to - The recipient's public key.
414
+ * @param price - The price of the NFT (optional).
415
+ */
416
+ async transferBySignature(params) {
417
+ const { address, to, price, context } = params;
418
+ const collectionData = CollectionData.unpack(this.packedData.getAndRequireEquals());
419
+ collectionData.isPaused.assertFalse(CollectionErrors.collectionPaused);
420
+ collectionData.requireTransferApproval.assertFalse(CollectionErrors.transferApprovalRequired);
421
+ const transferEventDraft = new TransferExtendedParams({
422
+ from: PublicKey.empty(), // will be added later
423
+ to,
424
+ collection: this.address,
425
+ nft: address,
426
+ fee: UInt64Option.none(), // will be added later
427
+ price,
428
+ transferByOwner: Bool(false), // will be added later
429
+ approved: PublicKey.empty(), // will be added later
430
+ context,
431
+ });
432
+ await this._transfer({
433
+ transferEventDraft,
434
+ transferFee: collectionData.transferFee,
435
+ royaltyFee: collectionData.royaltyFee,
436
+ });
437
+ }
438
+ /**
439
+ * Transfers ownership of an NFT using a proof in case the owner is a contract
440
+ * Can be called by the owner or approved that should be a contracts
441
+ * supporting NFTApprovalBase interface
442
+ *
443
+ * @param params - The transfer parameters.
444
+ */
445
+ async transferByProof(params) {
446
+ const { address, from, to, price, context } = params;
447
+ const collectionData = CollectionData.unpack(this.packedData.getAndRequireEquals());
448
+ collectionData.isPaused.assertFalse(CollectionErrors.collectionPaused);
449
+ const transferEventDraft = new TransferExtendedParams({
450
+ from,
451
+ to,
452
+ collection: this.address,
453
+ nft: address,
454
+ fee: UInt64Option.none(), // will be added later
455
+ price,
456
+ transferByOwner: Bool(false), // will be added later
457
+ approved: PublicKey.empty(), // will be added later
458
+ context,
459
+ });
460
+ const transferEvent = await this._transfer({
461
+ transferEventDraft,
462
+ transferFee: collectionData.transferFee,
463
+ royaltyFee: collectionData.royaltyFee,
464
+ });
465
+ const approvalContract = this.getApprovalContract(from);
466
+ // This operation is not atomic and the owner or approval contract cannot rely on the fact
467
+ // that it is being called by the Collection contract
468
+ // It is the responsibility of the owner contract to maintain the state
469
+ // that allow for escrow-like agreement between the buyer and the seller
470
+ // in case of the selling and buying of the NFT and return 'true' only if the
471
+ // payment is made or guaranteed by the deposit of the funds in the owner contract
472
+ // or the owner contract is able to verify that it is being called by the Collection contract
473
+ // by setting the flag in its state as in the Offer contract example
474
+ const canTransfer = await approvalContract.canTransfer(transferEvent);
475
+ canTransfer.assertTrue();
476
+ }
477
+ /**
478
+ * Transfers ownership of an NFT using a proof in case the owner is a contract
479
+ * Can be called by the owner or approved that should be a contracts
480
+ * supporting NFTApprovalBase interface
481
+ *
482
+ * @param params - The transfer parameters.
483
+ */
484
+ async approvedTransferByProof(params) {
485
+ const { address, from, to, price, context } = params;
486
+ const collectionData = CollectionData.unpack(this.packedData.getAndRequireEquals());
487
+ collectionData.isPaused.assertFalse(CollectionErrors.collectionPaused);
488
+ const transferEventDraft = new TransferExtendedParams({
489
+ from,
490
+ to,
491
+ collection: this.address,
492
+ nft: address,
493
+ fee: UInt64Option.none(), // will be added later
494
+ price,
495
+ transferByOwner: Bool(false), // will be added later
496
+ approved: PublicKey.empty(), // will be added later
497
+ context,
498
+ });
499
+ const transferEvent = await this._transfer({
500
+ transferEventDraft,
501
+ transferFee: collectionData.transferFee,
502
+ royaltyFee: collectionData.royaltyFee,
503
+ });
504
+ const adminContract = this.getAdminContract();
505
+ const adminApprovedTransfer = await adminContract.canTransfer(transferEvent);
506
+ adminApprovedTransfer.assertTrue();
507
+ const approvalContract = this.getApprovalContract(from);
508
+ // This operation is not atomic and the owner or approval contract cannot rely on the fact
509
+ // that it is being called by the Collection contract
510
+ // It is the responsibility of the owner contract to maintain the state
511
+ // that allow for escrow-like agreement between the buyer and the seller
512
+ // in case of the selling and buying of the NFT and return 'true' only if the
513
+ // payment is made or guaranteed by the deposit of the funds in the owner contract
514
+ // or the owner contract is able to verify that it is being called by the Collection contract
515
+ // by setting the flag in its state as in the Offer contract example
516
+ const canTransfer = await approvalContract.canTransfer(transferEvent);
517
+ canTransfer.assertTrue();
518
+ }
519
+ /**
520
+ * Transfers ownership of an NFT with admin approval.
521
+ *
522
+ * @param address - The address of the NFT.
523
+ * @param to - The recipient's public key.
524
+ * @param price - The price of the NFT (optional).
525
+ */
526
+ async approvedTransferBySignature(params) {
527
+ const { address, to, price, context } = params;
528
+ const collectionData = CollectionData.unpack(this.packedData.getAndRequireEquals());
529
+ collectionData.isPaused.assertFalse(CollectionErrors.collectionPaused);
530
+ const transferEventDraft = new TransferExtendedParams({
531
+ from: PublicKey.empty(), // will be added later
532
+ to,
533
+ collection: this.address,
534
+ nft: address,
535
+ fee: UInt64Option.none(), // will be added later
536
+ price,
537
+ transferByOwner: Bool(false), // will be added later
538
+ approved: PublicKey.empty(), // will be added later
539
+ context,
540
+ });
541
+ const transferEvent = await this._transfer({
542
+ transferEventDraft,
543
+ transferFee: collectionData.transferFee,
544
+ royaltyFee: collectionData.royaltyFee,
545
+ });
546
+ const adminContract = this.getAdminContract();
547
+ const canTransfer = await adminContract.canTransfer(transferEvent);
548
+ canTransfer.assertTrue();
549
+ this.emitEvent("transfer", transferEvent);
550
+ }
551
+ /**
552
+ * Internal method to transfer an NFT.
553
+ *
554
+ * @param address - The address of the NFT.
555
+ * @param to - The recipient's public key.
556
+ * @param transferFee - The transfer fee amount.
557
+ * @returns The TransferEvent emitted.
558
+ */
559
+ async _transfer(params) {
560
+ const { transferEventDraft, transferFee, royaltyFee } = params;
561
+ const sender = this.sender.getUnconstrained();
562
+ // If the from is empty, we set the sender as the from and require signature from the sender
563
+ const isFromEmpty = transferEventDraft.from.equals(PublicKey.empty());
564
+ transferEventDraft.from = Provable.if(isFromEmpty, sender, transferEventDraft.from);
565
+ const tokenId = this.deriveTokenId();
566
+ const nft = new NFT(transferEventDraft.nft, tokenId);
567
+ const transferEvent = await nft.transfer(transferEventDraft);
568
+ const creator = this.creator.getAndRequireEquals();
569
+ // TODO: check is the owner is the creator
570
+ let fee = Provable.if(transferEventDraft.price.isSome,
571
+ // We cannot check the price here, so we just rely on owner contract
572
+ // Malicious owner contracts can be blocked by the admin contract
573
+ // or by setting the transfer fee to a higher value reflecting the market price
574
+ transferEventDraft.price
575
+ .orElse(1000000000n) // is not used, can be any value
576
+ .div(MAX_ROYALTY_FEE)
577
+ .mul(UInt64.from(royaltyFee)), transferFee);
578
+ const isOwnedByCreator = transferEvent.from.equals(creator);
579
+ fee = Provable.if(isOwnedByCreator, UInt64.zero,
580
+ // The minimum fee is the transfer fee
581
+ Provable.if(fee.lessThanOrEqual(transferFee), transferFee, fee));
582
+ const senderUpdate = AccountUpdate.createIf(fee.equals(UInt64.zero).not().or(isFromEmpty), sender);
583
+ senderUpdate.requireSignature();
584
+ senderUpdate.body.useFullCommitment = Bool(true); // Prevent memo and fee change
585
+ senderUpdate.account.balance.requireBetween(fee, UInt64.MAXINT());
586
+ senderUpdate.send({
587
+ to: this.creator.getAndRequireEquals(),
588
+ amount: fee,
589
+ });
590
+ transferEvent.fee = UInt64Option.fromValue({
591
+ value: fee,
592
+ isSome: fee.equals(UInt64.zero).not(),
593
+ });
594
+ this.emitEvent("transfer", new TransferEvent({
595
+ ...transferEvent,
596
+ }));
597
+ return transferEvent;
598
+ }
599
+ /**
600
+ * Upgrades the verification key of a specific NFT.
601
+ *
602
+ * @param address - The address of the NFT.
603
+ * @param vk - The new verification key.
604
+ */
605
+ async upgradeNFTVerificationKeyBySignature(address, vk) {
606
+ const sender = this.sender.getAndRequireSignature();
607
+ const data = await this._upgrade(address, vk);
608
+ data.owner
609
+ .equals(sender)
610
+ .or(data.isOwnerApprovalRequired.not())
611
+ .assertTrue(CollectionErrors.onlyOwnerCanUpgradeVerificationKey);
612
+ }
613
+ /**
614
+ * Upgrades the verification key of a specific NFT by Proof.
615
+ *
616
+ * @param address - The address of the NFT.
617
+ * @param vk - The new verification key.
618
+ */
619
+ async upgradeNFTVerificationKeyByProof(address, vk) {
620
+ const data = await this._upgrade(address, vk);
621
+ const ownerContract = this.getOwnerContract(data.owner);
622
+ const canUpgrade = await ownerContract.canChangeVerificationKey(this.address, address, vk);
623
+ canUpgrade.assertTrue();
624
+ }
625
+ async _upgrade(address, vk) {
626
+ const tokenId = this.deriveTokenId();
627
+ const nft = new NFT(address, tokenId);
628
+ const adminContract = this.getAdminContract();
629
+ const canUpgrade = await adminContract.canChangeVerificationKey(vk, address, tokenId);
630
+ canUpgrade.assertTrue(CollectionErrors.cannotUpgradeVerificationKey);
631
+ const data = await nft.upgradeVerificationKey(vk);
632
+ const event = new UpgradeVerificationKeyEvent({
633
+ address,
634
+ tokenId,
635
+ verificationKeyHash: vk.hash,
636
+ });
637
+ this.emitEvent("upgradeNFTVerificationKey", event);
638
+ return data;
639
+ }
640
+ /**
641
+ * Upgrades the verification key of the collection contract.
642
+ *
643
+ * @param vk - The new verification key.
644
+ */
645
+ async upgradeVerificationKey(vk) {
646
+ const adminContract = this.getAdminContract();
647
+ const canUpgrade = await adminContract.canChangeVerificationKey(vk, this.address, this.tokenId);
648
+ canUpgrade.assertTrue(CollectionErrors.cannotUpgradeVerificationKey);
649
+ this.account.verificationKey.set(vk);
650
+ this.emitEvent("upgradeVerificationKey", vk.hash);
651
+ }
652
+ /**
653
+ * Limits further minting of NFTs in the collection.
654
+ */
655
+ async limitMinting() {
656
+ await this.ensureCreatorSignature();
657
+ const collectionData = CollectionData.unpack(this.packedData.getAndRequireEquals());
658
+ collectionData.isPaused.assertFalse(CollectionErrors.collectionPaused);
659
+ collectionData.mintingIsLimited = Bool(true);
660
+ this.packedData.set(collectionData.pack());
661
+ this.emitEvent("limitMinting", new LimitMintingEvent({ mintingLimited: Bool(true) }));
662
+ }
663
+ /**
664
+ * Pauses the collection, disabling certain actions.
665
+ */
666
+ async pause() {
667
+ const collectionData = CollectionData.unpack(this.packedData.getAndRequireEquals());
668
+ collectionData.isPaused.assertFalse(CollectionErrors.collectionPaused);
669
+ const adminContract = this.getAdminContract();
670
+ const canPause = await adminContract.canPause();
671
+ canPause.assertTrue(CollectionErrors.noPermissionToPause);
672
+ collectionData.isPaused = Bool(true);
673
+ this.packedData.set(collectionData.pack());
674
+ this.emitEvent("pause", new PauseEvent({ isPaused: Bool(true) }));
675
+ }
676
+ /**
677
+ * Resumes the collection, re-enabling actions.
678
+ */
679
+ async resume() {
680
+ const collectionData = CollectionData.unpack(this.packedData.getAndRequireEquals());
681
+ collectionData.isPaused.assertTrue(CollectionErrors.collectionNotPaused);
682
+ const adminContract = this.getAdminContract();
683
+ const canResume = await adminContract.canResume();
684
+ canResume.assertTrue(CollectionErrors.noPermissionToResume);
685
+ collectionData.isPaused = Bool(false);
686
+ this.packedData.set(collectionData.pack());
687
+ this.emitEvent("resume", new PauseEvent({ isPaused: Bool(false) }));
688
+ }
689
+ /**
690
+ * Pauses a specific NFT, disabling its actions.
691
+ *
692
+ * @param address - The address of the NFT to pause.
693
+ */
694
+ async pauseNFTBySignature(address) {
695
+ const tokenId = this.deriveTokenId();
696
+ const nft = new NFT(address, tokenId);
697
+ const owner = await nft.pause();
698
+ await this.ensureOwnerSignature(owner);
699
+ this.emitEvent("pauseNFT", new PauseNFTEvent({ isPaused: Bool(true), address }));
700
+ }
701
+ /**
702
+ * Pauses a specific NFT, disabling its actions.
703
+ *
704
+ * @param address - The address of the NFT to pause.
705
+ */
706
+ async pauseNFTByProof(address) {
707
+ const tokenId = this.deriveTokenId();
708
+ const nft = new NFT(address, tokenId);
709
+ const owner = await nft.pause();
710
+ const ownerContract = this.getOwnerContract(owner);
711
+ const canPause = await ownerContract.canPause(this.address, address);
712
+ canPause.assertTrue();
713
+ this.emitEvent("pauseNFT", new PauseNFTEvent({ isPaused: Bool(true), address }));
714
+ }
715
+ /**
716
+ * Resumes a specific NFT, re-enabling its actions.
717
+ *
718
+ * @param address - The address of the NFT to resume.
719
+ */
720
+ async resumeNFT(address) {
721
+ const tokenId = this.deriveTokenId();
722
+ const nft = new NFT(address, tokenId);
723
+ const owner = await nft.resume();
724
+ await this.ensureOwnerSignature(owner);
725
+ this.emitEvent("resumeNFT", new PauseNFTEvent({ isPaused: Bool(false), address }));
726
+ }
727
+ /**
728
+ * Resumes a specific NFT, re-enabling its actions.
729
+ *
730
+ * @param address - The address of the NFT to resume.
731
+ */
732
+ async resumeNFTByProof(address) {
733
+ const tokenId = this.deriveTokenId();
734
+ const nft = new NFT(address, tokenId);
735
+ const owner = await nft.resume();
736
+ const ownerContract = this.getOwnerContract(owner);
737
+ const canResume = await ownerContract.canResume(this.address, address);
738
+ canResume.assertTrue();
739
+ this.emitEvent("resumeNFT", new PauseNFTEvent({ isPaused: Bool(false), address }));
740
+ }
741
+ /**
742
+ * Sets a new name for the collection.
743
+ * Requires owner signature and collection to not be paused.
744
+ * Emits a 'setName' event with the new name.
745
+ *
746
+ * @param name - The new name for the collection as a Field value
747
+ * @throws {Error} If caller lacks permission to change name
748
+ */
749
+ async setName(name) {
750
+ await this.ensureNotPaused();
751
+ const adminContract = this.getAdminContract();
752
+ const canChangeName = await adminContract.canChangeName(name);
753
+ canChangeName.assertTrue(CollectionErrors.noPermissionToChangeName);
754
+ this.collectionName.set(name);
755
+ this.emitEvent("setName", name);
756
+ }
757
+ /**
758
+ * Updates the base URL for the collection's metadata.
759
+ * Requires owner signature and collection to not be paused.
760
+ * Emits a 'setBaseURL' event with the new URL.
761
+ *
762
+ * @param baseURL - The new base URL as a Field value
763
+ * @throws {Error} If caller lacks permission to change base URI
764
+ */
765
+ async setBaseURL(baseURL) {
766
+ await this.ensureNotPaused();
767
+ const adminContract = this.getAdminContract();
768
+ const canChangeBaseUri = await adminContract.canChangeBaseUri(baseURL);
769
+ canChangeBaseUri.assertTrue(CollectionErrors.noPermissionToChangeBaseUri);
770
+ this.baseURL.set(baseURL);
771
+ this.emitEvent("setBaseURL", baseURL);
772
+ }
773
+ /**
774
+ * Sets a new admin address for the collection.
775
+ * Requires owner signature and collection to not be paused.
776
+ * Emits a 'setAdmin' event with the new admin address.
777
+ *
778
+ * @param admin - The public key of the new admin
779
+ * @throws {Error} If caller lacks permission to set admin
780
+ */
781
+ async setAdmin(admin) {
782
+ await this.ensureNotPaused();
783
+ const adminContract = this.getAdminContract();
784
+ const canSetAdmin = await adminContract.canSetAdmin(admin);
785
+ canSetAdmin.assertTrue(CollectionErrors.noPermissionToSetAdmin);
786
+ this.admin.set(admin);
787
+ this.emitEvent("setAdmin", admin);
788
+ }
789
+ /**
790
+ * Updates the royalty fee for the collection.
791
+ * Requires owner signature and collection to not be paused.
792
+ * Emits a 'setRoyaltyFee' event with the new fee.
793
+ *
794
+ * @param royaltyFee - The new royalty fee as a UInt32 value
795
+ * @throws {Error} If caller lacks permission to change royalty fee
796
+ */
797
+ async setRoyaltyFee(royaltyFee) {
798
+ const collectionData = CollectionData.unpack(this.packedData.getAndRequireEquals());
799
+ collectionData.isPaused.assertFalse(CollectionErrors.collectionPaused);
800
+ royaltyFee.assertLessThanOrEqual(UInt32.from(MAX_ROYALTY_FEE), CollectionErrors.invalidRoyaltyFee);
801
+ const adminContract = this.getAdminContract();
802
+ const canChangeRoyalty = await adminContract.canChangeRoyalty(royaltyFee);
803
+ canChangeRoyalty.assertTrue(CollectionErrors.noPermissionToChangeRoyalty);
804
+ collectionData.royaltyFee = royaltyFee;
805
+ this.packedData.set(collectionData.pack());
806
+ this.emitEvent("setRoyaltyFee", royaltyFee);
807
+ }
808
+ /**
809
+ * Updates the transfer fee for the collection.
810
+ * Requires owner signature and collection to not be paused.
811
+ * Emits a 'setTransferFee' event with the new fee.
812
+ *
813
+ * @param transferFee - The new transfer fee as a UInt64 value
814
+ * @throws {Error} If caller lacks permission to change transfer fee
815
+ */
816
+ async setTransferFee(transferFee) {
817
+ const collectionData = CollectionData.unpack(this.packedData.getAndRequireEquals());
818
+ collectionData.isPaused.assertFalse(CollectionErrors.collectionPaused);
819
+ const adminContract = this.getAdminContract();
820
+ const canChangeTransferFee = await adminContract.canChangeTransferFee(transferFee);
821
+ canChangeTransferFee.assertTrue(CollectionErrors.noPermissionToChangeTransferFee);
822
+ collectionData.transferFee = transferFee;
823
+ this.packedData.set(collectionData.pack());
824
+ this.emitEvent("setTransferFee", transferFee);
825
+ }
826
+ /**
827
+ * Transfers ownership of the collection to a new owner.
828
+ *
829
+ * @param to - The public key of the new owner.
830
+ * @returns The public key of the old owner.
831
+ */
832
+ async transferOwnership(to) {
833
+ await this.ensureCreatorSignature();
834
+ await this.ensureNotPaused();
835
+ const adminContract = this.getAdminContract();
836
+ const canChangeCreator = await adminContract.canChangeCreator(to);
837
+ canChangeCreator.assertTrue(CollectionErrors.noPermissionToChangeCreator);
838
+ const from = this.creator.getAndRequireEquals();
839
+ this.creator.set(to);
840
+ this.emitEvent("ownershipChange", new OwnershipChangeEvent({
841
+ from,
842
+ to,
843
+ }));
844
+ return from;
845
+ }
846
+ async getNFTState(address) {
847
+ const tokenId = this.deriveTokenId();
848
+ const nft = new NFT(address, tokenId);
849
+ const state = await nft.getState();
850
+ return state;
851
+ }
852
+ }
853
+ __decorate([
854
+ state(Field),
855
+ __metadata("design:type", Object)
856
+ ], Collection.prototype, "collectionName", void 0);
857
+ __decorate([
858
+ state(PublicKey),
859
+ __metadata("design:type", Object)
860
+ ], Collection.prototype, "creator", void 0);
861
+ __decorate([
862
+ state(PublicKey),
863
+ __metadata("design:type", Object)
864
+ ], Collection.prototype, "admin", void 0);
865
+ __decorate([
866
+ state(Field),
867
+ __metadata("design:type", Object)
868
+ ], Collection.prototype, "baseURL", void 0);
869
+ __decorate([
870
+ state(Field),
871
+ __metadata("design:type", Object)
872
+ ], Collection.prototype, "packedData", void 0);
873
+ __decorate([
874
+ method,
875
+ __metadata("design:type", Function),
876
+ __metadata("design:paramtypes", [MintParams, CollectionData]),
877
+ __metadata("design:returntype", Promise)
878
+ ], Collection.prototype, "initialize", null);
879
+ __decorate([
880
+ method,
881
+ __metadata("design:type", Function),
882
+ __metadata("design:paramtypes", [MintParams]),
883
+ __metadata("design:returntype", Promise)
884
+ ], Collection.prototype, "mintByCreator", null);
885
+ __decorate([
886
+ method,
887
+ __metadata("design:type", Function),
888
+ __metadata("design:paramtypes", [MintRequest]),
889
+ __metadata("design:returntype", Promise)
890
+ ], Collection.prototype, "mint", null);
891
+ __decorate([
892
+ method,
893
+ __metadata("design:type", Function),
894
+ __metadata("design:paramtypes", [NFTUpdateProof,
895
+ VerificationKey]),
896
+ __metadata("design:returntype", Promise)
897
+ ], Collection.prototype, "update", null);
898
+ __decorate([
899
+ method,
900
+ __metadata("design:type", Function),
901
+ __metadata("design:paramtypes", [NFTUpdateProof,
902
+ VerificationKey]),
903
+ __metadata("design:returntype", Promise)
904
+ ], Collection.prototype, "updateWithOracle", null);
905
+ __decorate([
906
+ method,
907
+ __metadata("design:type", Function),
908
+ __metadata("design:paramtypes", [PublicKey,
909
+ PublicKey]),
910
+ __metadata("design:returntype", Promise)
911
+ ], Collection.prototype, "approveAddress", null);
912
+ __decorate([
913
+ method,
914
+ __metadata("design:type", Function),
915
+ __metadata("design:paramtypes", [PublicKey,
916
+ PublicKey]),
917
+ __metadata("design:returntype", Promise)
918
+ ], Collection.prototype, "approveAddressByProof", null);
919
+ __decorate([
920
+ method,
921
+ __metadata("design:type", Function),
922
+ __metadata("design:paramtypes", [TransferParams]),
923
+ __metadata("design:returntype", Promise)
924
+ ], Collection.prototype, "transferBySignature", null);
925
+ __decorate([
926
+ method,
927
+ __metadata("design:type", Function),
928
+ __metadata("design:paramtypes", [TransferParams]),
929
+ __metadata("design:returntype", Promise)
930
+ ], Collection.prototype, "transferByProof", null);
931
+ __decorate([
932
+ method,
933
+ __metadata("design:type", Function),
934
+ __metadata("design:paramtypes", [TransferParams]),
935
+ __metadata("design:returntype", Promise)
936
+ ], Collection.prototype, "approvedTransferByProof", null);
937
+ __decorate([
938
+ method,
939
+ __metadata("design:type", Function),
940
+ __metadata("design:paramtypes", [TransferParams]),
941
+ __metadata("design:returntype", Promise)
942
+ ], Collection.prototype, "approvedTransferBySignature", null);
943
+ __decorate([
944
+ method,
945
+ __metadata("design:type", Function),
946
+ __metadata("design:paramtypes", [PublicKey,
947
+ VerificationKey]),
948
+ __metadata("design:returntype", Promise)
949
+ ], Collection.prototype, "upgradeNFTVerificationKeyBySignature", null);
950
+ __decorate([
951
+ method,
952
+ __metadata("design:type", Function),
953
+ __metadata("design:paramtypes", [PublicKey,
954
+ VerificationKey]),
955
+ __metadata("design:returntype", Promise)
956
+ ], Collection.prototype, "upgradeNFTVerificationKeyByProof", null);
957
+ __decorate([
958
+ method,
959
+ __metadata("design:type", Function),
960
+ __metadata("design:paramtypes", [VerificationKey]),
961
+ __metadata("design:returntype", Promise)
962
+ ], Collection.prototype, "upgradeVerificationKey", null);
963
+ __decorate([
964
+ method,
965
+ __metadata("design:type", Function),
966
+ __metadata("design:paramtypes", []),
967
+ __metadata("design:returntype", Promise)
968
+ ], Collection.prototype, "limitMinting", null);
969
+ __decorate([
970
+ method,
971
+ __metadata("design:type", Function),
972
+ __metadata("design:paramtypes", []),
973
+ __metadata("design:returntype", Promise)
974
+ ], Collection.prototype, "pause", null);
975
+ __decorate([
976
+ method,
977
+ __metadata("design:type", Function),
978
+ __metadata("design:paramtypes", []),
979
+ __metadata("design:returntype", Promise)
980
+ ], Collection.prototype, "resume", null);
981
+ __decorate([
982
+ method,
983
+ __metadata("design:type", Function),
984
+ __metadata("design:paramtypes", [PublicKey]),
985
+ __metadata("design:returntype", Promise)
986
+ ], Collection.prototype, "pauseNFTBySignature", null);
987
+ __decorate([
988
+ method,
989
+ __metadata("design:type", Function),
990
+ __metadata("design:paramtypes", [PublicKey]),
991
+ __metadata("design:returntype", Promise)
992
+ ], Collection.prototype, "pauseNFTByProof", null);
993
+ __decorate([
994
+ method,
995
+ __metadata("design:type", Function),
996
+ __metadata("design:paramtypes", [PublicKey]),
997
+ __metadata("design:returntype", Promise)
998
+ ], Collection.prototype, "resumeNFT", null);
999
+ __decorate([
1000
+ method,
1001
+ __metadata("design:type", Function),
1002
+ __metadata("design:paramtypes", [PublicKey]),
1003
+ __metadata("design:returntype", Promise)
1004
+ ], Collection.prototype, "resumeNFTByProof", null);
1005
+ __decorate([
1006
+ method,
1007
+ __metadata("design:type", Function),
1008
+ __metadata("design:paramtypes", [Field]),
1009
+ __metadata("design:returntype", Promise)
1010
+ ], Collection.prototype, "setName", null);
1011
+ __decorate([
1012
+ method,
1013
+ __metadata("design:type", Function),
1014
+ __metadata("design:paramtypes", [Field]),
1015
+ __metadata("design:returntype", Promise)
1016
+ ], Collection.prototype, "setBaseURL", null);
1017
+ __decorate([
1018
+ method,
1019
+ __metadata("design:type", Function),
1020
+ __metadata("design:paramtypes", [PublicKey]),
1021
+ __metadata("design:returntype", Promise)
1022
+ ], Collection.prototype, "setAdmin", null);
1023
+ __decorate([
1024
+ method,
1025
+ __metadata("design:type", Function),
1026
+ __metadata("design:paramtypes", [UInt32]),
1027
+ __metadata("design:returntype", Promise)
1028
+ ], Collection.prototype, "setRoyaltyFee", null);
1029
+ __decorate([
1030
+ method,
1031
+ __metadata("design:type", Function),
1032
+ __metadata("design:paramtypes", [UInt64]),
1033
+ __metadata("design:returntype", Promise)
1034
+ ], Collection.prototype, "setTransferFee", null);
1035
+ __decorate([
1036
+ method.returns(PublicKey),
1037
+ __metadata("design:type", Function),
1038
+ __metadata("design:paramtypes", [PublicKey]),
1039
+ __metadata("design:returntype", Promise)
1040
+ ], Collection.prototype, "transferOwnership", null);
1041
+ __decorate([
1042
+ method.returns(NFTStateStruct),
1043
+ __metadata("design:type", Function),
1044
+ __metadata("design:paramtypes", [PublicKey]),
1045
+ __metadata("design:returntype", Promise)
1046
+ ], Collection.prototype, "getNFTState", null);
1047
+ return Collection;
1048
+ }
1049
+ //# sourceMappingURL=collection.js.map