olas-operate-middleware 0.10.6__py3-none-any.whl → 0.10.7__py3-none-any.whl

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.
@@ -41,12 +41,14 @@ from autonomy.chain.constants import (
41
41
  GNOSIS_SAFE_PROXY_FACTORY_CONTRACT,
42
42
  GNOSIS_SAFE_SAME_ADDRESS_MULTISIG_CONTRACT,
43
43
  MULTISEND_CONTRACT,
44
+ RECOVERY_MODULE_CONTRACT,
45
+ SAFE_MULTISIG_WITH_RECOVERY_MODULE_CONTRACT,
44
46
  )
45
47
  from autonomy.chain.metadata import publish_metadata
46
48
  from autonomy.chain.service import (
47
49
  get_agent_instances,
48
50
  get_deployment_payload,
49
- get_reuse_multisig_payload,
51
+ get_deployment_with_recovery_payload,
50
52
  get_service_info,
51
53
  get_token_deposit_amount,
52
54
  )
@@ -65,6 +67,7 @@ from operate.constants import (
65
67
  )
66
68
  from operate.data import DATA_DIR
67
69
  from operate.data.contracts.dual_staking_token.contract import DualStakingTokenContract
70
+ from operate.data.contracts.recovery_module.contract import RecoveryModule
68
71
  from operate.data.contracts.staking_token.contract import StakingTokenContract
69
72
  from operate.operate_types import Chain as OperateChain
70
73
  from operate.operate_types import ContractAddresses
@@ -1151,9 +1154,21 @@ class OnChainManager(_ChainUtil):
1151
1154
  class EthSafeTxBuilder(_ChainUtil):
1152
1155
  """Safe Transaction builder."""
1153
1156
 
1154
- def new_tx(self) -> GnosisSafeTransaction:
1157
+ @classmethod
1158
+ def _new_tx(
1159
+ cls, ledger_api: LedgerApi, crypto: Crypto, chain_type: ChainType, safe: str
1160
+ ) -> GnosisSafeTransaction:
1155
1161
  """Create a new GnosisSafeTransaction instance."""
1156
1162
  return GnosisSafeTransaction(
1163
+ ledger_api=ledger_api,
1164
+ crypto=crypto,
1165
+ chain_type=chain_type,
1166
+ safe=safe,
1167
+ )
1168
+
1169
+ def new_tx(self) -> GnosisSafeTransaction:
1170
+ """Create a new GnosisSafeTransaction instance."""
1171
+ return EthSafeTxBuilder._new_tx(
1157
1172
  ledger_api=self.wallet.ledger_api(
1158
1173
  chain=OperateChain.from_string(self.chain_type.value),
1159
1174
  rpc=self.rpc,
@@ -1307,55 +1322,12 @@ class EthSafeTxBuilder(_ChainUtil):
1307
1322
  "value": cost_of_bond,
1308
1323
  }
1309
1324
 
1310
- def get_deploy_data(
1311
- self,
1312
- service_id: int,
1313
- reuse_multisig: bool = False,
1314
- ) -> t.Dict:
1315
- """Get deploy tx data."""
1316
- instance = registry_contracts.service_manager.get_instance(
1317
- ledger_api=self.ledger_api,
1318
- contract_address=self.contracts["service_manager"],
1319
- )
1320
- if reuse_multisig:
1321
- _deployment_payload, error = get_reuse_multisig_payload(
1322
- ledger_api=self.ledger_api,
1323
- crypto=self.crypto,
1324
- chain_type=self.chain_type,
1325
- service_id=service_id,
1326
- )
1327
- if _deployment_payload is None:
1328
- raise ValueError(error)
1329
- deployment_payload = _deployment_payload
1330
- gnosis_safe_multisig = ContractConfigs.get(
1331
- GNOSIS_SAFE_SAME_ADDRESS_MULTISIG_CONTRACT.name
1332
- ).contracts[self.chain_type]
1333
- else:
1334
- deployment_payload = get_deployment_payload()
1335
- gnosis_safe_multisig = ContractConfigs.get(
1336
- GNOSIS_SAFE_PROXY_FACTORY_CONTRACT.name
1337
- ).contracts[self.chain_type]
1338
-
1339
- txd = instance.encodeABI(
1340
- fn_name="deploy",
1341
- args=[
1342
- service_id,
1343
- gnosis_safe_multisig,
1344
- deployment_payload,
1345
- ],
1346
- )
1347
- return {
1348
- "to": self.contracts["service_manager"],
1349
- "data": txd[2:],
1350
- "operation": MultiSendOperation.CALL,
1351
- "value": 0,
1352
- }
1353
-
1354
1325
  def get_deploy_data_from_safe(
1355
1326
  self,
1356
1327
  service_id: int,
1357
1328
  master_safe: str,
1358
1329
  reuse_multisig: bool = False,
1330
+ use_recovery_module: bool = True,
1359
1331
  ) -> t.List[t.Dict[str, t.Any]]:
1360
1332
  """Get the deploy data instructions for a safe"""
1361
1333
  registry_instance = registry_contracts.service_manager.get_instance(
@@ -1364,27 +1336,50 @@ class EthSafeTxBuilder(_ChainUtil):
1364
1336
  )
1365
1337
  approve_hash_message = None
1366
1338
  if reuse_multisig:
1367
- (
1368
- _deployment_payload,
1369
- approve_hash_message,
1370
- error,
1371
- ) = get_reuse_multisig_from_safe_payload(
1372
- ledger_api=self.ledger_api,
1373
- chain_type=self.chain_type,
1374
- service_id=service_id,
1375
- master_safe=master_safe,
1376
- )
1377
- if _deployment_payload is None:
1378
- raise ValueError(error)
1379
- deployment_payload = _deployment_payload
1380
- gnosis_safe_multisig = ContractConfigs.get(
1381
- GNOSIS_SAFE_SAME_ADDRESS_MULTISIG_CONTRACT.name
1382
- ).contracts[self.chain_type]
1383
- else:
1384
- deployment_payload = get_deployment_payload()
1385
- gnosis_safe_multisig = ContractConfigs.get(
1386
- GNOSIS_SAFE_PROXY_FACTORY_CONTRACT.name
1387
- ).contracts[self.chain_type]
1339
+ if not use_recovery_module:
1340
+ (
1341
+ _deployment_payload,
1342
+ approve_hash_message,
1343
+ error,
1344
+ ) = get_reuse_multisig_from_safe_payload(
1345
+ ledger_api=self.ledger_api,
1346
+ chain_type=self.chain_type,
1347
+ service_id=service_id,
1348
+ master_safe=master_safe,
1349
+ )
1350
+ if _deployment_payload is None:
1351
+ raise ValueError(error)
1352
+ deployment_payload = _deployment_payload
1353
+ gnosis_safe_multisig = ContractConfigs.get(
1354
+ GNOSIS_SAFE_SAME_ADDRESS_MULTISIG_CONTRACT.name
1355
+ ).contracts[self.chain_type]
1356
+ else:
1357
+ (
1358
+ _deployment_payload,
1359
+ error,
1360
+ ) = get_reuse_multisig_with_recovery_from_safe_payload(
1361
+ ledger_api=self.ledger_api,
1362
+ chain_type=self.chain_type,
1363
+ service_id=service_id,
1364
+ master_safe=master_safe,
1365
+ )
1366
+ if _deployment_payload is None:
1367
+ raise ValueError(error)
1368
+ deployment_payload = _deployment_payload
1369
+ gnosis_safe_multisig = ContractConfigs.get(
1370
+ RECOVERY_MODULE_CONTRACT.name
1371
+ ).contracts[self.chain_type]
1372
+ else: # Deploy a new multisig
1373
+ if not use_recovery_module:
1374
+ deployment_payload = get_deployment_payload()
1375
+ gnosis_safe_multisig = ContractConfigs.get(
1376
+ GNOSIS_SAFE_PROXY_FACTORY_CONTRACT.name
1377
+ ).contracts[self.chain_type]
1378
+ else:
1379
+ deployment_payload = get_deployment_with_recovery_payload()
1380
+ gnosis_safe_multisig = ContractConfigs.get(
1381
+ SAFE_MULTISIG_WITH_RECOVERY_MODULE_CONTRACT.name
1382
+ ).contracts[self.chain_type]
1388
1383
 
1389
1384
  deploy_data = registry_instance.encodeABI(
1390
1385
  fn_name="deploy",
@@ -1571,6 +1566,56 @@ class EthSafeTxBuilder(_ChainUtil):
1571
1566
  # TODO: Discuss implementation
1572
1567
  raise NotImplementedError()
1573
1568
 
1569
+ def get_recover_access_data(self, service_id: int) -> t.Dict:
1570
+ """Get recover access tx data."""
1571
+ instance = t.cast(
1572
+ RecoveryModule,
1573
+ RecoveryModule.from_dir(
1574
+ directory=str(DATA_DIR / "contracts" / "recovery_module"),
1575
+ ),
1576
+ ).get_instance(
1577
+ ledger_api=self.ledger_api,
1578
+ contract_address=self.contracts["recovery_module"],
1579
+ )
1580
+ # TODO Replace the line above by this one once the recovery_module is
1581
+ # included in the release of OpenAutonomy.
1582
+ # instance = registry_contracts.recovery_module.get_instance( # noqa: E800
1583
+ # ledger_api=self.ledger_api, # noqa: E800
1584
+ # contract_address=self.contracts["recovery_module"], # noqa: E800
1585
+ # ) # noqa: E800
1586
+ txd = instance.encodeABI(
1587
+ fn_name="recoverAccess",
1588
+ args=[service_id],
1589
+ )
1590
+ return {
1591
+ "to": self.contracts["recovery_module"],
1592
+ "data": txd[2:],
1593
+ "operation": MultiSendOperation.CALL,
1594
+ "value": 0,
1595
+ }
1596
+
1597
+ def get_enable_module_data(
1598
+ self,
1599
+ safe_address: str,
1600
+ module_address: str,
1601
+ ) -> t.Dict:
1602
+ """Get enable module tx data"""
1603
+ self._patch()
1604
+ instance = registry_contracts.gnosis_safe.get_instance(
1605
+ ledger_api=self.ledger_api,
1606
+ contract_address=safe_address,
1607
+ )
1608
+ txd = instance.encodeABI(
1609
+ fn_name="enableModule",
1610
+ args=[module_address],
1611
+ )
1612
+ return {
1613
+ "to": safe_address,
1614
+ "data": txd[2:],
1615
+ "operation": MultiSendOperation.CALL,
1616
+ "value": 0,
1617
+ }
1618
+
1574
1619
 
1575
1620
  def get_packed_signature_for_approved_hash(owners: t.Tuple[str]) -> bytes:
1576
1621
  """Get the packed signatures."""
@@ -1730,3 +1775,37 @@ def get_reuse_multisig_from_safe_payload( # pylint: disable=too-many-locals
1730
1775
  )
1731
1776
  payload = multisig_address + safe_exec_data[2:]
1732
1777
  return payload, approve_hash_message, None
1778
+
1779
+
1780
+ def get_reuse_multisig_with_recovery_from_safe_payload( # pylint: disable=too-many-locals
1781
+ ledger_api: LedgerApi,
1782
+ chain_type: ChainType,
1783
+ service_id: int,
1784
+ master_safe: str,
1785
+ ) -> t.Tuple[Optional[str], Optional[str]]:
1786
+ """Reuse multisig."""
1787
+ _, multisig_address, _, _, *_ = get_service_info(
1788
+ ledger_api=ledger_api,
1789
+ chain_type=chain_type,
1790
+ token_id=service_id,
1791
+ )
1792
+ if multisig_address == ZERO_ADDRESS:
1793
+ return None, "Cannot reuse multisig, No previous deployment exist!"
1794
+
1795
+ service_owner = master_safe
1796
+
1797
+ multisig_instance = registry_contracts.gnosis_safe.get_instance(
1798
+ ledger_api=ledger_api,
1799
+ contract_address=multisig_address,
1800
+ )
1801
+
1802
+ # Verify if the service was terminated properly or not
1803
+ old_owners = multisig_instance.functions.getOwners().call()
1804
+ if len(old_owners) != 1 or service_owner not in old_owners:
1805
+ return (
1806
+ None,
1807
+ "Service was not terminated properly, the service owner should be the only owner of the safe",
1808
+ )
1809
+
1810
+ payload = "0x" + int(service_id).to_bytes(32, "big").hex()
1811
+ return payload, None
@@ -153,6 +153,18 @@ DEFAULT_TRADER_ENV_VARS = {
153
153
  "value": "",
154
154
  "provision_type": "computed",
155
155
  },
156
+ "TOOLS_ACCURACY_HASH": {
157
+ "name": "Tools accuracy hash",
158
+ "description": "",
159
+ "value": "QmWgsqncF22hPLNTyWtDzVoKPJ9gmgR1jcuLL5t31xyzzr",
160
+ "provision_type": "fixed",
161
+ },
162
+ "ACC_INFO_FIELDS_REQUESTS": {
163
+ "name": "Acc info fields requests",
164
+ "description": "",
165
+ "value": "nr_responses",
166
+ "provision_type": "fixed",
167
+ },
156
168
  }
157
169
 
158
170
  AGENT_TYPE_IDS = {"mech": 37, "optimus": 40, "modius": 40, "trader": 25}