20
20
21
21
import json
22
22
import os
23
+ import shutil
23
24
import textwrap
24
25
import time
25
26
import typing as t
26
27
import warnings
27
- from dataclasses import dataclass
28
- from pathlib import Path
29
28
30
29
import requests
31
30
from aea .crypto .registries import make_ledger_api
47
46
)
48
47
from operate .quickstart .utils import (
49
48
CHAIN_TO_METADATA ,
49
+ QuickstartConfig ,
50
50
ask_or_get_from_env ,
51
51
check_rpc ,
52
52
print_box ,
53
53
print_section ,
54
54
print_title ,
55
55
wei_to_token ,
56
56
)
57
- from operate .resource import LocalResource , deserialize
58
57
from operate .services .manage import ServiceManager
59
58
from operate .services .service import NON_EXISTENT_MULTISIG , Service
60
59
from operate .utils .gnosis import get_asset_balance
107
106
}
108
107
109
108
110
- @dataclass
111
- class QuickstartConfig (LocalResource ):
112
- """Local configuration."""
113
-
114
- path : Path
115
- rpc : t .Optional [t .Dict [str , str ]] = None
116
- password_migrated : t .Optional [bool ] = None
117
- staking_program_id : t .Optional [str ] = None
118
- principal_chain : t .Optional [str ] = None
119
- user_provided_args : t .Optional [t .Dict [str , str ]] = None
120
-
121
- @classmethod
122
- def from_json (cls , obj : t .Dict ) -> "LocalResource" :
123
- """Load LocalResource from json."""
124
- kwargs = {}
125
- for pname , ptype in cls .__annotations__ .items ():
126
- if pname .startswith ("_" ):
127
- continue
128
-
129
- # allow for optional types
130
- is_optional_type = t .get_origin (ptype ) is t .Union and type (
131
- None
132
- ) in t .get_args (ptype )
133
- value = obj .get (pname , None )
134
- if is_optional_type and value is None :
135
- continue
136
-
137
- kwargs [pname ] = deserialize (obj = obj [pname ], otype = ptype )
138
- return cls (** kwargs )
139
-
140
-
141
109
def ask_confirm_password () -> str :
142
110
"""Ask for password confirmation."""
143
111
while True :
@@ -154,20 +122,64 @@ def ask_confirm_password() -> str:
154
122
print ("Passwords do not match!" )
155
123
156
124
157
- def load_local_config () -> QuickstartConfig :
125
+ def load_local_config (operate : "OperateApp" , service_name : str ) -> QuickstartConfig :
158
126
"""Load the local quickstart configuration."""
159
- path = OPERATE_HOME / "local_config.json"
160
- if path .exists ():
161
- config = QuickstartConfig .load (path )
127
+ old_path = OPERATE_HOME / "local_config.json"
128
+ if old_path .exists (): # Migrate to new naming scheme
129
+ config = t .cast (QuickstartConfig , QuickstartConfig .load (old_path ))
130
+ service_manager = operate .service_manager ()
131
+ services = service_manager .json
132
+ if config .staking_program_id == NO_STAKING_PROGRAM_ID :
133
+ for service in services :
134
+ if service ["name" ] == service_name :
135
+ config .path = (
136
+ config .path .parent / f"{ service_name } -quickstart-config.json"
137
+ )
138
+ shutil .move (old_path , config .path )
139
+ break
140
+ else :
141
+ for staking_program , agent_id in QS_STAKING_PROGRAMS [
142
+ Chain .from_string (config .principal_chain )
143
+ ].items ():
144
+ if staking_program == config .staking_program_id :
145
+ staking_agent_id = agent_id
146
+ break
147
+ else :
148
+ raise ValueError (
149
+ f"Staking program { config .staking_program_id } not found in { QS_STAKING_PROGRAMS [config .principal_chain ]} .\n "
150
+ "Please resolve manually!"
151
+ )
152
+
153
+ for service in services :
154
+ if (
155
+ staking_agent_id
156
+ == service ["chain_configs" ][config .principal_chain ]["chain_data" ][
157
+ "user_params"
158
+ ]["agent_id" ]
159
+ ):
160
+ config .path = (
161
+ config .path .parent / f"{ service ['name' ]} -quickstart-config.json"
162
+ )
163
+ shutil .move (old_path , config .path )
164
+ break
165
+
166
+ for qs_config in OPERATE_HOME .glob ("*-quickstart-config.json" ):
167
+ if f"{ service_name } -quickstart-config.json" == qs_config .name :
168
+ config = t .cast (QuickstartConfig , QuickstartConfig .load (qs_config ))
169
+ break
162
170
else :
163
- config = QuickstartConfig (path )
171
+ config = QuickstartConfig (
172
+ OPERATE_HOME / f"{ service_name } -quickstart-config.json"
173
+ )
164
174
165
- return config # type: ignore[return-value]
175
+ return config
166
176
167
177
168
- def configure_local_config (template : ServiceTemplate ) -> QuickstartConfig :
178
+ def configure_local_config (
179
+ template : ServiceTemplate , operate : "OperateApp"
180
+ ) -> QuickstartConfig :
169
181
"""Configure local quickstart configuration."""
170
- config = load_local_config ()
182
+ config = load_local_config (operate = operate , service_name = template [ "name" ] )
171
183
172
184
if config .rpc is None :
173
185
config .rpc = {}
@@ -184,8 +196,7 @@ def configure_local_config(template: ServiceTemplate) -> QuickstartConfig:
184
196
if config .password_migrated is None :
185
197
config .password_migrated = False
186
198
187
- if config .principal_chain is None :
188
- config .principal_chain = template ["home_chain" ]
199
+ config .principal_chain = template ["home_chain" ]
189
200
190
201
agent_id = template ["configurations" ][config .principal_chain ]["agent_id" ]
191
202
home_chain = Chain .from_string (config .principal_chain )
@@ -197,7 +208,7 @@ def configure_local_config(template: ServiceTemplate) -> QuickstartConfig:
197
208
)
198
209
ledger_api = make_ledger_api (
199
210
LedgerType .ETHEREUM .lower (),
200
- address = config .rpc [config .principal_chain ],
211
+ address = config .rpc [config .principal_chain ], # type: ignore[index]
201
212
chain_id = home_chain .id ,
202
213
)
203
214
@@ -391,22 +402,25 @@ def ask_password_if_needed(operate: "OperateApp", config: QuickstartConfig) -> N
391
402
392
403
def get_service (manager : ServiceManager , template : ServiceTemplate ) -> Service :
393
404
"""Get service."""
394
- if len (manager .json ) > 0 :
395
- old_hash = manager .json [0 ]["hash" ]
396
- if old_hash == template ["hash" ]:
397
- print (f'Loading service { template ["hash" ]} ' )
398
- service = manager .load (
399
- service_config_id = manager .json [0 ]["service_config_id" ],
400
- )
401
- else :
402
- print (f"Updating service from { old_hash } to " + template ["hash" ])
403
- service = manager .update (
404
- service_config_id = manager .json [0 ]["service_config_id" ],
405
- service_template = template ,
406
- )
405
+ for service in manager .json :
406
+ if service ["name" ] == template ["name" ]:
407
+ old_hash = service ["hash" ]
408
+ if old_hash == template ["hash" ]:
409
+ print (f'Loading service { template ["hash" ]} ' )
410
+ service = manager .load (
411
+ service_config_id = service ["service_config_id" ],
412
+ )
413
+ else :
414
+ print (f"Updating service from { old_hash } to " + template ["hash" ])
415
+ service = manager .update (
416
+ service_config_id = service ["service_config_id" ],
417
+ service_template = template ,
418
+ )
407
419
408
- service .env_variables = template ["env_variables" ]
409
- service .store ()
420
+ service .env_variables = template ["env_variables" ]
421
+ service .update_user_params_from_template (service_template = template )
422
+ service .store ()
423
+ break
410
424
else :
411
425
print (f'Creating service { template ["hash" ]} ' )
412
426
service = manager .load_or_create (
@@ -475,7 +489,7 @@ def ensure_enough_funds(operate: "OperateApp", service: Service) -> None:
475
489
wallet = operate .wallet_manager .load (ledger_type = LedgerType .ETHEREUM )
476
490
477
491
manager = operate .service_manager ()
478
- config = load_local_config ()
492
+ config = load_local_config (operate = operate , service_name = t . cast ( str , service . name ) )
479
493
480
494
for chain_name , chain_config in service .chain_configs .items ():
481
495
print_section (f"[{ chain_name } ] Set up the service in the Olas Protocol" )
@@ -636,19 +650,17 @@ def run_service(
636
650
637
651
print_title (f"{ template ['name' ]} quickstart" )
638
652
639
- operate .service_manager ().log_directories ()
640
653
operate .service_manager ().migrate_service_configs ()
641
- operate .service_manager ().log_directories ()
642
654
operate .wallet_manager .migrate_wallet_configs ()
643
655
644
- config = configure_local_config (template )
656
+ config = configure_local_config (template , operate )
645
657
manager = operate .service_manager ()
646
658
service = get_service (manager , template )
647
659
ask_password_if_needed (operate , config )
648
660
649
661
# reload manger and config after setting operate.password
650
662
manager = operate .service_manager ()
651
- config = load_local_config ()
663
+ config = load_local_config (operate = operate , service_name = t . cast ( str , service . name ) )
652
664
ensure_enough_funds (operate , service )
653
665
654
666
print_box ("PLEASE, DO NOT INTERRUPT THIS PROCESS." )
0 commit comments