11//! NFC Collection
22
3- use soroban_sdk:: { contractimpl, contracttype, panic_with_error, Address , Bytes , BytesN , Env , String , Vec } ;
4- use soroban_sdk:: xdr:: ToXdr ;
5- use crate :: { errors, events, Collection , CollectionArgs , CollectionClient , CollectionTrait } ;
3+ use soroban_sdk:: { contractimpl, contracttype, Address , BytesN , Env , String , Vec } ;
4+ use crate :: { Collection , CollectionArgs , CollectionClient , CollectionTrait } ;
65
76#[ contracttype]
87pub enum DataKey {
@@ -13,7 +12,8 @@ pub enum DataKey {
1312pub enum CollectionKey {
1413 NFTContract ,
1514 Collections ,
16- Collectibles ( Address ) ,
15+ Collectibles ( Address , u32 ) , // (contract ID; Token ID) - Owner
16+ OwnerCollectibles ( Address ) , // Owner - (contract ID; Token ID)
1717}
1818
1919
@@ -31,29 +31,43 @@ impl CollectionTrait for Collection {
3131 e. deployer ( ) . update_current_contract_wasm ( wasm_hash. clone ( ) ) ;
3232 }
3333
34- fn create_collection ( e : & Env , wasm_hash : BytesN < 32 > , name : String , symbol : String , uri : String , max_tokens : u32 ) {
34+ fn create_collection ( e : & Env , wasm_hash : BytesN < 32 > , name : String , symbol : String , uri : String , max_tokens : u32 ) -> Address {
3535 let admin: Address = e. storage ( ) . instance ( ) . get ( & DataKey :: Admin ) . unwrap ( ) ;
3636 admin. require_auth ( ) ;
3737
3838 let salt: BytesN < 32 > = e. crypto ( ) . sha256 ( & symbol. to_bytes ( ) ) . into ( ) ;
3939 let deployer = e. deployer ( ) . with_current_contract ( salt) ;
40- let contract_address = deployer. deploy_v2 ( wasm_hash, ( name, symbol, uri, max_tokens) ) ;
40+ let contract_address = deployer. deploy_v2 ( wasm_hash, ( admin , name, symbol, uri, max_tokens) ) ;
4141
4242 let mut collections: Vec < Address > = e. storage ( ) . instance ( ) . get ( & CollectionKey :: Collections ) . unwrap_or ( Vec :: new ( & e) ) ;
4343 collections. push_back ( contract_address. clone ( ) ) ;
44- e. storage ( ) . instance ( ) . set ( & CollectionKey :: Collections , & contract_address) ;
44+ e. storage ( ) . instance ( ) . set ( & CollectionKey :: Collections , & contract_address. clone ( ) ) ;
45+ contract_address
4546 }
4647
4748 fn assign_collectible ( e : & Env , collection : Address , to : Address , token_id : u32 ) {
4849 collection. require_auth ( ) ;
4950
50- let mut collectibles: Vec < ( Address , u32 ) > = e. storage ( ) . instance ( ) . get ( & CollectionKey :: Collectibles ( to. clone ( ) ) ) . unwrap_or ( Vec :: new ( & e) ) ;
51- collectibles. push_back ( ( collection, token_id) ) ;
52- e. storage ( ) . instance ( ) . set ( & CollectionKey :: Collectibles ( to) , & collectibles) ;
51+ let collectible = ( collection. clone ( ) , token_id) ;
52+
53+ let owned_collectible: Option < Address > = e. storage ( ) . instance ( ) . get ( & CollectionKey :: Collectibles ( collection. clone ( ) , token_id. clone ( ) ) ) . unwrap ( ) ;
54+ e. storage ( ) . instance ( ) . set ( & CollectionKey :: Collectibles ( collection. clone ( ) , token_id. clone ( ) ) , & to. clone ( ) ) ;
55+
56+ // transferring the collectible by removing from previous owner if any
57+ if owned_collectible. is_some ( ) {
58+ let mut owner_collectibles: Vec < ( Address , u32 ) > = e. storage ( ) . instance ( ) . get ( & CollectionKey :: OwnerCollectibles ( owned_collectible. unwrap ( ) . clone ( ) ) ) . unwrap_or ( Vec :: new ( & e) ) ;
59+ let idx_collectible = owner_collectibles. first_index_of ( collectible. clone ( ) ) . unwrap ( ) ;
60+ owner_collectibles. remove ( idx_collectible) ;
61+ e. storage ( ) . instance ( ) . set ( & CollectionKey :: OwnerCollectibles ( to. clone ( ) ) , & owner_collectibles) ;
62+ }
63+
64+ let mut owner_collectibles: Vec < ( Address , u32 ) > = e. storage ( ) . instance ( ) . get ( & CollectionKey :: OwnerCollectibles ( to. clone ( ) ) ) . unwrap_or ( Vec :: new ( & e) ) ;
65+ owner_collectibles. push_back ( collectible) ;
66+ e. storage ( ) . instance ( ) . set ( & CollectionKey :: OwnerCollectibles ( to) , & owner_collectibles) ;
5367 }
5468
5569 fn collectibles ( e : & Env , from : Address ) -> Vec < ( Address , u32 ) > {
56- e. storage ( ) . instance ( ) . get ( & CollectionKey :: Collectibles ( from. clone ( ) ) ) . unwrap_or ( Vec :: new ( & e) )
70+ e. storage ( ) . instance ( ) . get ( & CollectionKey :: OwnerCollectibles ( from. clone ( ) ) ) . unwrap_or ( Vec :: new ( & e) )
5771 }
5872
5973}
0 commit comments