66
77use super :: * ;
88use codec:: { Codec , Decode , Encode } ;
9- use frame_support:: traits:: { tokens:: Locker , Get } ;
9+ use frame_support:: {
10+ pallet_prelude:: * ,
11+ traits:: { tokens:: Locker , Get } ,
12+ } ;
1013
1114use sp_runtime:: {
1215 traits:: { Saturating , TrailingZeroInput } ,
@@ -24,15 +27,11 @@ where
2427 T : pallet_uniques:: Config < CollectionId = CollectionId , ItemId = NftId > ,
2528{
2629 fn priority_set (
27- sender : T :: AccountId ,
30+ _sender : T :: AccountId ,
2831 collection_id : CollectionId ,
2932 nft_id : NftId ,
3033 priorities : BoundedVec < ResourceId , T :: MaxPriorities > ,
3134 ) -> DispatchResult {
32- let ( root_owner, _) = Pallet :: < T > :: lookup_root_owner ( collection_id, nft_id) ?;
33- ensure ! ( sender == root_owner, Error :: <T >:: NoPermission ) ;
34- // Check NFT lock status
35- ensure ! ( !Pallet :: <T >:: is_locked( collection_id, nft_id) , pallet_uniques:: Error :: <T >:: Locked ) ;
3635 let _multi_removal_results =
3736 Priorities :: < T > :: clear_prefix ( ( collection_id, nft_id) , T :: MaxPriorities :: get ( ) , None ) ;
3837 let mut priority_index = 0 ;
@@ -107,25 +106,18 @@ where
107106 T : pallet_uniques:: Config < CollectionId = CollectionId , ItemId = NftId > ,
108107{
109108 fn resource_add (
110- sender : T :: AccountId ,
109+ _sender : T :: AccountId ,
111110 collection_id : CollectionId ,
112111 nft_id : NftId ,
113112 resource : ResourceTypes < BoundedVec < u8 , T :: StringLimit > , BoundedVec < PartId , T :: PartsLimit > > ,
114- adding_on_mint : bool ,
113+ pending : bool ,
115114 resource_id : ResourceId ,
116115 ) -> Result < ResourceId , DispatchError > {
117116 ensure ! (
118117 Resources :: <T >:: get( ( collection_id, nft_id, resource_id) ) . is_none( ) ,
119118 Error :: <T >:: ResourceAlreadyExists
120119 ) ;
121120
122- let collection = Self :: collections ( collection_id) . ok_or ( Error :: < T > :: CollectionUnknown ) ?;
123-
124- ensure ! ( collection. issuer == sender, Error :: <T >:: NoPermission ) ;
125- let ( root_owner, _) = Pallet :: < T > :: lookup_root_owner ( collection_id, nft_id) ?;
126- // Check NFT lock status
127- ensure ! ( !Pallet :: <T >:: is_locked( collection_id, nft_id) , pallet_uniques:: Error :: <T >:: Locked ) ;
128-
129121 match resource. clone ( ) {
130122 ResourceTypes :: Basic ( _r) => ( ) ,
131123 ResourceTypes :: Composable ( r) => {
@@ -145,15 +137,6 @@ where
145137 } ,
146138 }
147139
148- // Resource should be in a pending state if the rootowner of the resource is not the sender
149- // of the transaction, unless the resource is being added on mint. This prevents the
150- // situation where an NFT being minted *directly to* a non-owned NFT *with resources* will
151- // have those resources be *pending*. While the minted NFT itself will be pending, it is
152- // inefficent and unnecessary to have the resources also be pending. Otherwise, in such a
153- // case, the owner would have to accept not only the NFT but also all originally-added
154- // resources.
155- let pending = ( root_owner != sender) && !adding_on_mint;
156-
157140 let res: ResourceInfo < BoundedVec < u8 , T :: StringLimit > , BoundedVec < PartId , T :: PartsLimit > > =
158141 ResourceInfo :: < BoundedVec < u8 , T :: StringLimit > , BoundedVec < PartId , T :: PartsLimit > > {
159142 id : resource_id,
@@ -163,50 +146,50 @@ where
163146 } ;
164147 Resources :: < T > :: insert ( ( collection_id, nft_id, resource_id) , res) ;
165148
149+ Self :: deposit_event ( Event :: ResourceAdded { nft_id, resource_id, collection_id } ) ;
150+
166151 Ok ( resource_id)
167152 }
168153
169154 fn accept (
170- sender : T :: AccountId ,
155+ _sender : T :: AccountId ,
171156 collection_id : CollectionId ,
172157 nft_id : NftId ,
173158 resource_id : ResourceId ,
174159 ) -> DispatchResult {
175- let ( root_owner , _ ) = Pallet :: < T > :: lookup_root_owner ( collection_id , nft_id ) ? ;
176- ensure ! ( root_owner == sender , Error :: <T >:: NoPermission ) ;
177- // Check NFT lock status
178- ensure ! ( ! Pallet :: < T > :: is_locked ( collection_id , nft_id ) , pallet_uniques :: Error :: < T > :: Locked ) ;
160+ ensure ! (
161+ Resources :: <T >:: get ( ( collection_id , nft_id , resource_id ) ) . is_some ( ) ,
162+ Error :: < T > :: ResourceDoesntExist
163+ ) ;
179164 Resources :: < T > :: try_mutate_exists (
180165 ( collection_id, nft_id, resource_id) ,
181166 |resource| -> DispatchResult {
182- if let Some ( res) = resource {
167+ if let Some ( res) = resource. into_mut ( ) {
168+ ensure ! ( res. pending, Error :: <T >:: ResourceNotPending ) ;
183169 res. pending = false ;
184170 }
185171 Ok ( ( ) )
186172 } ,
187173 ) ?;
188174
189- Self :: deposit_event ( Event :: ResourceAccepted { nft_id, resource_id } ) ;
175+ Self :: deposit_event ( Event :: ResourceAccepted { nft_id, resource_id, collection_id } ) ;
176+
190177 Ok ( ( ) )
191178 }
192179
193180 fn resource_remove (
194- sender : T :: AccountId ,
181+ _sender : T :: AccountId ,
195182 collection_id : CollectionId ,
196183 nft_id : NftId ,
197184 resource_id : ResourceId ,
185+ pending_resource : bool ,
198186 ) -> DispatchResult {
199- let collection = Self :: collections ( collection_id) . ok_or ( Error :: < T > :: CollectionUnknown ) ?;
200- let ( root_owner, _) = Pallet :: < T > :: lookup_root_owner ( collection_id, nft_id) ?;
201- ensure ! ( collection. issuer == sender, Error :: <T >:: NoPermission ) ;
202187 ensure ! (
203188 Resources :: <T >:: contains_key( ( collection_id, nft_id, resource_id) ) ,
204189 Error :: <T >:: ResourceDoesntExist
205190 ) ;
206191
207- if root_owner == sender {
208- Resources :: < T > :: remove ( ( collection_id, nft_id, resource_id) ) ;
209- } else {
192+ if pending_resource {
210193 Resources :: < T > :: try_mutate_exists (
211194 ( collection_id, nft_id, resource_id) ,
212195 |resource| -> DispatchResult {
@@ -216,19 +199,21 @@ where
216199 Ok ( ( ) )
217200 } ,
218201 ) ?;
202+ } else {
203+ Resources :: < T > :: remove ( ( collection_id, nft_id, resource_id) ) ;
219204 }
220205
206+ Self :: deposit_event ( Event :: ResourceRemoval { nft_id, resource_id, collection_id } ) ;
207+
221208 Ok ( ( ) )
222209 }
223210
224211 fn accept_removal (
225- sender : T :: AccountId ,
212+ _sender : T :: AccountId ,
226213 collection_id : CollectionId ,
227214 nft_id : NftId ,
228215 resource_id : ResourceId ,
229216 ) -> DispatchResult {
230- let ( root_owner, _) = Pallet :: < T > :: lookup_root_owner ( collection_id, nft_id) ?;
231- ensure ! ( root_owner == sender, Error :: <T >:: NoPermission ) ;
232217 ensure ! (
233218 Resources :: <T >:: contains_key( ( collection_id, nft_id, & resource_id) ) ,
234219 Error :: <T >:: ResourceDoesntExist
@@ -245,6 +230,8 @@ where
245230 } ,
246231 ) ?;
247232
233+ Self :: deposit_event ( Event :: ResourceRemovalAccepted { nft_id, resource_id, collection_id } ) ;
234+
248235 Ok ( ( ) )
249236 }
250237}
@@ -290,10 +277,23 @@ where
290277 Ok ( collection_id)
291278 }
292279
293- fn collection_burn ( _issuer : T :: AccountId , collection_id : CollectionId ) -> DispatchResult {
280+ fn collection_burn ( issuer : T :: AccountId , collection_id : CollectionId ) -> DispatchResult {
294281 let collection = Self :: collections ( collection_id) . ok_or ( Error :: < T > :: CollectionUnknown ) ?;
295282 ensure ! ( collection. nfts_count == 0 , Error :: <T >:: CollectionNotEmpty ) ;
283+ // Get DestroyWitness for Uniques pallet
284+ let witness = pallet_uniques:: Pallet :: < T > :: get_destroy_witness ( & collection_id)
285+ . ok_or ( Error :: < T > :: NoWitness ) ?;
286+ ensure ! ( witness. items == 0u32 , Error :: <T >:: CollectionNotEmpty ) ;
287+ // Remove from RMRK storage
296288 Collections :: < T > :: remove ( collection_id) ;
289+
290+ pallet_uniques:: Pallet :: < T > :: do_destroy_collection (
291+ collection_id,
292+ witness,
293+ issuer. clone ( ) . into ( ) ,
294+ ) ?;
295+
296+ Self :: deposit_event ( Event :: CollectionDestroyed { issuer, collection_id } ) ;
297297 Ok ( ( ) )
298298 }
299299
@@ -319,10 +319,12 @@ where
319319 ) -> Result < CollectionId , DispatchError > {
320320 Collections :: < T > :: try_mutate_exists ( collection_id, |collection| -> DispatchResult {
321321 let collection = collection. as_mut ( ) . ok_or ( Error :: < T > :: CollectionUnknown ) ?;
322- ensure ! ( collection. issuer == sender, Error :: <T >:: NoPermission ) ;
323322 collection. max = Some ( collection. nfts_count ) ;
324323 Ok ( ( ) )
325324 } ) ?;
325+
326+ Self :: deposit_event ( Event :: CollectionLocked { issuer : sender, collection_id } ) ;
327+
326328 Ok ( collection_id)
327329 }
328330}
@@ -401,7 +403,7 @@ where
401403 collection_id,
402404 nft_id,
403405 res. resource ,
404- true ,
406+ false ,
405407 res. id ,
406408 ) ?;
407409 }
@@ -488,7 +490,7 @@ where
488490 collection_id,
489491 nft_id,
490492 res. resource ,
491- true ,
493+ false ,
492494 res. id ,
493495 ) ?;
494496 }
@@ -504,6 +506,7 @@ where
504506 }
505507
506508 fn nft_burn (
509+ owner : T :: AccountId ,
507510 collection_id : CollectionId ,
508511 nft_id : NftId ,
509512 max_recursions : u32 ,
@@ -530,7 +533,7 @@ where
530533 for ( ( child_collection_id, child_nft_id) , _) in
531534 Children :: < T > :: drain_prefix ( ( collection_id, nft_id) )
532535 {
533- Self :: nft_burn ( child_collection_id, child_nft_id, max_recursions - 1 ) ?;
536+ Self :: nft_burn ( owner . clone ( ) , child_collection_id, child_nft_id, max_recursions - 1 ) ?;
534537 }
535538
536539 // decrement nfts counter
@@ -540,6 +543,11 @@ where
540543 Ok ( ( ) )
541544 } ) ?;
542545
546+ // Call pallet uniques to ensure NFT is burned
547+ pallet_uniques:: Pallet :: < T > :: do_burn ( collection_id, nft_id, |_, _| Ok ( ( ) ) ) ?;
548+
549+ Self :: deposit_event ( Event :: NFTBurned { owner, nft_id, collection_id } ) ;
550+
543551 Ok ( ( collection_id, nft_id) )
544552 }
545553
@@ -599,7 +607,7 @@ where
599607 } ,
600608 } ;
601609
602- sending_nft. owner = new_owner;
610+ sending_nft. owner = new_owner. clone ( ) ;
603611 // Nfts::<T>::insert(collection_id, nft_id, sending_nft);
604612
605613 if approval_required {
@@ -630,6 +638,21 @@ where
630638 Pallet :: < T > :: add_child ( new_owner_cid_nid, ( collection_id, nft_id) ) ;
631639 }
632640
641+ pallet_uniques:: Pallet :: < T > :: do_transfer (
642+ collection_id,
643+ nft_id,
644+ new_owner_account. clone ( ) ,
645+ |_class_details, _details| Ok ( ( ) ) ,
646+ ) ?;
647+
648+ Self :: deposit_event ( Event :: NFTSent {
649+ sender,
650+ recipient : new_owner,
651+ collection_id,
652+ nft_id,
653+ approval_required,
654+ } ) ;
655+
633656 Ok ( ( new_owner_account, approval_required) )
634657 }
635658
@@ -649,7 +672,7 @@ where
649672 Nfts :: < T > :: get ( collection_id, nft_id) . ok_or ( Error :: < T > :: NoAvailableNftId ) ?;
650673
651674 // Prepare acceptance
652- let new_owner_account = match new_owner {
675+ let new_owner_account = match new_owner. clone ( ) {
653676 AccountIdOrCollectionNftTuple :: AccountId ( id) => id,
654677 AccountIdOrCollectionNftTuple :: CollectionAndNftTuple ( cid, nid) => {
655678 // Check if NFT target exists
@@ -682,6 +705,20 @@ where
682705 Ok ( ( ) )
683706 } ) ?;
684707
708+ pallet_uniques:: Pallet :: < T > :: do_transfer (
709+ collection_id,
710+ nft_id,
711+ new_owner_account. clone ( ) ,
712+ |_class_details, _details| Ok ( ( ) ) ,
713+ ) ?;
714+
715+ Self :: deposit_event ( Event :: NFTAccepted {
716+ sender,
717+ recipient : new_owner,
718+ collection_id,
719+ nft_id,
720+ } ) ;
721+
685722 Ok ( ( new_owner_account, collection_id, nft_id) )
686723 }
687724
@@ -720,7 +757,7 @@ where
720757 let _rejecting_nft =
721758 Nfts :: < T > :: get ( collection_id, nft_id) . ok_or ( Error :: < T > :: NoAvailableNftId ) ?;
722759
723- Self :: nft_burn ( collection_id, nft_id, max_recursions) ?;
760+ Self :: nft_burn ( sender . clone ( ) , collection_id, nft_id, max_recursions) ?;
724761
725762 Ok ( ( sender, collection_id, nft_id) )
726763 }
0 commit comments