@@ -10,11 +10,10 @@ use crate::{
1010 util:: { hash_string, MAX_BUMP } ,
1111 version:: Version ,
1212 Contract ,
13+ WasmRegistry ,
1314} ;
1415
15- use crate :: WasmRegistry ;
16-
17- use super :: { IsDeployable , IsDevDeployable } ;
16+ use super :: { IsClaimable , IsDeployable , IsDevDeployable } ;
1817
1918loam_sdk:: import_contract!( core_riff) ;
2019
@@ -25,9 +24,29 @@ loam_sdk::import_contract!(core_riff);
2524// loam_sdk::soroban_sdk::contractimport!(file = "../../target/loam/core_riff.wasm",);
2625// }
2726
27+ #[ contracttype( export = false ) ]
28+ pub struct ContractRegistry ( pub Map < String , ContractType > ) ;
2829
2930#[ contracttype( export = false ) ]
30- pub struct ContractRegistry ( pub Map < String , Address > ) ;
31+ #[ derive( Clone ) ]
32+ pub enum ContractType {
33+ ContractById ( Address ) ,
34+ ContractByIdAndOwner ( Address , Address ) ,
35+ }
36+
37+ impl ContractType {
38+ pub fn contract_id ( & self ) -> & Address {
39+ match self {
40+ Self :: ContractById ( id) | Self :: ContractByIdAndOwner ( id, _) => id,
41+ }
42+ }
43+ pub fn owner ( & self ) -> Option < & Address > {
44+ match self {
45+ Self :: ContractByIdAndOwner ( _, owner) => Some ( owner) ,
46+ Self :: ContractById ( _) => None ,
47+ }
48+ }
49+ }
3150
3251impl Default for ContractRegistry {
3352 fn default ( ) -> Self {
@@ -52,13 +71,6 @@ impl Lazy for ContractRegistry {
5271}
5372
5473impl IsDeployable for ContractRegistry {
55- fn claim_deployed_contract ( & mut self , deployed_name : String , id : Address ) -> Result < ( ) , Error > {
56- if self . 0 . contains_key ( deployed_name. clone ( ) ) {
57- return Err ( Error :: AlreadyClaimed ) ;
58- }
59- self . 0 . set ( deployed_name, id) ;
60- Ok ( ( ) )
61- }
6274 fn deploy (
6375 & mut self ,
6476 contract_name : String ,
@@ -79,7 +91,7 @@ impl IsDeployable for ContractRegistry {
7991 if let Some ( ( init_fn, args) ) = init {
8092 let _ = env ( ) . invoke_contract :: < Val > ( & address, & init_fn, args) ;
8193 }
82- self . 0 . set ( deployed_name. clone ( ) , address. clone ( ) ) ;
94+ self . 0 . set ( deployed_name. clone ( ) , ContractType :: ContractById ( address. clone ( ) ) ) ;
8395
8496 // Publish a deploy event
8597 let version = version. map_or_else (
@@ -107,6 +119,7 @@ impl IsDeployable for ContractRegistry {
107119 self . 0
108120 . get ( deployed_name)
109121 . ok_or ( Error :: NoSuchContractDeployed )
122+ . map ( |contract| contract. contract_id ( ) . clone ( ) )
110123 }
111124
112125 fn list_deployed_contracts (
@@ -121,12 +134,60 @@ impl IsDeployable for ContractRegistry {
121134 . take ( limit. unwrap_or_else ( || self . 0 . len ( ) ) as usize ) ;
122135 let mut res = vec ! [ env( ) ] ;
123136 for item in items {
124- res. push_back ( item) ;
137+ res. push_back ( ( item. 0 , item . 1 . contract_id ( ) . clone ( ) ) ) ;
125138 }
126139 Ok ( res)
127140 }
128141}
129142
143+ impl IsClaimable for ContractRegistry {
144+ fn claim_already_deployed_contract (
145+ & mut self ,
146+ deployed_name : soroban_sdk:: String ,
147+ id : soroban_sdk:: Address ,
148+ owner : soroban_sdk:: Address ,
149+ ) -> Result < ( ) , Error > {
150+ owner. require_auth ( ) ;
151+ if self . 0 . contains_key ( deployed_name. clone ( ) ) {
152+ return Err ( Error :: AlreadyClaimed ) ;
153+ }
154+ self . 0 . set ( deployed_name, ContractType :: ContractByIdAndOwner ( id, owner) ) ;
155+ Ok ( ( ) )
156+ }
157+
158+ fn get_claimed_owner (
159+ & self ,
160+ deployed_name : soroban_sdk:: String
161+ ) -> Result < Option < Address > , Error > {
162+ self . 0
163+ . get ( deployed_name)
164+ . ok_or ( Error :: NoSuchContractDeployed )
165+ . map ( |contract| contract. owner ( ) . cloned ( ) )
166+ }
167+
168+ fn redeploy_claimed_contract (
169+ & self ,
170+ binary_name : Option < soroban_sdk:: String > ,
171+ version : Option < Version > ,
172+ deployed_name : soroban_sdk:: String ,
173+ redeploy_fn : Option < ( soroban_sdk:: Symbol , soroban_sdk:: Vec < soroban_sdk:: Val > ) > ,
174+ ) -> Result < ( ) , Error > {
175+ self . get_claimed_owner ( deployed_name. clone ( ) ) ?
176+ . ok_or ( Error :: NoOwnerSet ) ?
177+ . require_auth ( ) ;
178+ let contract_id = self . fetch_contract_id ( deployed_name) ?;
179+ if let Some ( binary_name) = binary_name {
180+ let hash = Contract :: fetch_hash ( binary_name, version) ?;
181+ env ( ) . deployer ( ) . update_current_contract_wasm ( hash) ;
182+ } else if let Some ( ( fn_name, args) ) = redeploy_fn {
183+ let _ = env ( ) . invoke_contract :: < Val > ( & contract_id, & fn_name, args) ;
184+ } else {
185+ return Err ( Error :: RedeployDeployedFailed ) ;
186+ }
187+ Ok ( ( ) )
188+ }
189+ }
190+
130191fn deploy_and_init (
131192 owner : & Address ,
132193 salt : BytesN < 32 > ,
@@ -152,14 +213,15 @@ impl IsDevDeployable for ContractRegistry {
152213 wasm : soroban_sdk:: Bytes ,
153214 ) -> Result < soroban_sdk:: Address , Error > {
154215 let wasm_hash = env ( ) . deployer ( ) . upload_contract_wasm ( wasm) ;
155- if let Some ( address) = self . 0 . get ( name. clone ( ) ) {
156- let contract = core_riff:: Client :: new ( env ( ) , & address) ;
216+ if let Some ( contract_state) = self . 0 . get ( name. clone ( ) ) {
217+ let address = contract_state. contract_id ( ) ;
218+ let contract = core_riff:: Client :: new ( env ( ) , address) ;
157219 contract. redeploy ( & wasm_hash) ;
158- return Ok ( address) ;
220+ return Ok ( address. clone ( ) ) ;
159221 }
160222 let salt = hash_string ( & name) ;
161223 let id = deploy_and_init ( & owner, salt, wasm_hash) ?;
162- self . 0 . set ( name, id. clone ( ) ) ;
224+ self . 0 . set ( name, ContractType :: ContractById ( id. clone ( ) ) ) ;
163225 Ok ( id)
164226 }
165227}
0 commit comments