olas-operate-middleware 0.10.6__py3-none-any.whl → 0.10.8__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.
- {olas_operate_middleware-0.10.6.dist-info → olas_operate_middleware-0.10.8.dist-info}/METADATA +1 -1
- {olas_operate_middleware-0.10.6.dist-info → olas_operate_middleware-0.10.8.dist-info}/RECORD +24 -19
- operate/__init__.py +12 -0
- operate/cli.py +145 -23
- operate/constants.py +9 -0
- operate/data/contracts/recovery_module/__init__.py +20 -0
- operate/data/contracts/recovery_module/build/RecoveryModule.json +811 -0
- operate/data/contracts/recovery_module/contract.py +61 -0
- operate/data/contracts/recovery_module/contract.yaml +23 -0
- operate/keys.py +9 -3
- operate/ledger/__init__.py +38 -24
- operate/ledger/profiles.py +73 -59
- operate/migration.py +73 -14
- operate/operate_types.py +2 -0
- operate/quickstart/reset_password.py +3 -2
- operate/quickstart/run_service.py +7 -2
- operate/services/manage.py +189 -19
- operate/services/protocol.py +153 -76
- operate/services/service.py +40 -58
- operate/wallet/master.py +7 -4
- operate/wallet/wallet_recovery_manager.py +210 -0
- {olas_operate_middleware-0.10.6.dist-info → olas_operate_middleware-0.10.8.dist-info}/LICENSE +0 -0
- {olas_operate_middleware-0.10.6.dist-info → olas_operate_middleware-0.10.8.dist-info}/WHEEL +0 -0
- {olas_operate_middleware-0.10.6.dist-info → olas_operate_middleware-0.10.8.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# ------------------------------------------------------------------------------
|
|
3
|
+
#
|
|
4
|
+
# Copyright 2025 Valory AG
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
#
|
|
18
|
+
# ------------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
"""This module contains the class to connect to the `RecoveryModule` contract."""
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
from typing import Any, Dict
|
|
24
|
+
|
|
25
|
+
from aea.configurations.base import PublicId
|
|
26
|
+
from aea.contracts.base import Contract
|
|
27
|
+
from aea.crypto.base import LedgerApi
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
PUBLIC_ID = PublicId.from_str("valory/recovery_module:0.1.0")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class RecoveryModule(Contract):
|
|
34
|
+
"""The RecoveryModule contract"""
|
|
35
|
+
|
|
36
|
+
contract_id = PUBLIC_ID
|
|
37
|
+
|
|
38
|
+
@classmethod
|
|
39
|
+
def get_recover_access_transaction(
|
|
40
|
+
cls,
|
|
41
|
+
ledger_api: LedgerApi,
|
|
42
|
+
contract_address: str,
|
|
43
|
+
owner: str,
|
|
44
|
+
service_id: int,
|
|
45
|
+
raise_on_try: bool = False,
|
|
46
|
+
) -> Dict[str, Any]:
|
|
47
|
+
"""Get the recover access transaction."""
|
|
48
|
+
|
|
49
|
+
tx_params = ledger_api.build_transaction(
|
|
50
|
+
contract_instance=cls.get_instance(
|
|
51
|
+
ledger_api=ledger_api, contract_address=contract_address
|
|
52
|
+
),
|
|
53
|
+
method_name="recoverAccess",
|
|
54
|
+
method_args={
|
|
55
|
+
"serviceId": service_id,
|
|
56
|
+
},
|
|
57
|
+
tx_args={"sender_address": owner},
|
|
58
|
+
raise_on_try=raise_on_try,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
return tx_params
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: recovery_module
|
|
2
|
+
author: valory
|
|
3
|
+
version: 0.1.0
|
|
4
|
+
type: contract
|
|
5
|
+
description: Recovery module
|
|
6
|
+
license: Apache-2.0
|
|
7
|
+
aea_version: '>=1.0.0, <2.0.0'
|
|
8
|
+
fingerprint:
|
|
9
|
+
__init__.py: bafybeicjlkmxs5ikpgdtgndifstpmmpaixwcbgouvmt6gowuhf5dy3dpgu
|
|
10
|
+
build/RecoveryModule.json: bafybeifsyjdbprcp4kxpijlpqfovxcf7cv2ujapt3d5zn34wby26ldv4ky
|
|
11
|
+
contract.py: bafybeifihpwb3etbrnn2hqdizsp5zolis3ur23slt3q5zctcykm5nlvv7q
|
|
12
|
+
fingerprint_ignore_patterns: []
|
|
13
|
+
contracts: []
|
|
14
|
+
class_name: RecoveryModule
|
|
15
|
+
contract_interface_paths:
|
|
16
|
+
ethereum: build/RecoveryModule.json
|
|
17
|
+
dependencies:
|
|
18
|
+
open-aea-ledger-ethereum:
|
|
19
|
+
version: ==1.60.0
|
|
20
|
+
open-aea-test-autonomy:
|
|
21
|
+
version: ==0.18.3
|
|
22
|
+
web3:
|
|
23
|
+
version: <7,>=6.0.0
|
operate/keys.py
CHANGED
|
@@ -92,16 +92,22 @@ class KeysManager(metaclass=SingletonMeta):
|
|
|
92
92
|
suffix=".txt",
|
|
93
93
|
delete=False, # Handle cleanup manually
|
|
94
94
|
) as temp_file:
|
|
95
|
+
temp_file_name = temp_file.name
|
|
95
96
|
temp_file.write(key.private_key)
|
|
96
97
|
temp_file.flush()
|
|
97
98
|
temp_file.close() # Close the file before reading
|
|
98
99
|
|
|
99
100
|
# Set proper file permissions (readable by owner only)
|
|
100
|
-
os.chmod(
|
|
101
|
-
crypto = EthereumCrypto(private_key_path=
|
|
101
|
+
os.chmod(temp_file_name, 0o600)
|
|
102
|
+
crypto = EthereumCrypto(private_key_path=temp_file_name)
|
|
102
103
|
|
|
103
104
|
try:
|
|
104
|
-
|
|
105
|
+
with open(temp_file_name, "r+", encoding="utf-8") as f:
|
|
106
|
+
f.seek(0)
|
|
107
|
+
f.write("\0" * len(key.private_key))
|
|
108
|
+
f.flush()
|
|
109
|
+
f.close()
|
|
110
|
+
os.unlink(temp_file_name) # Clean up the temporary file
|
|
105
111
|
except OSError as e:
|
|
106
112
|
self.logger.error(f"Failed to delete temp file {temp_file.name}: {e}")
|
|
107
113
|
|
operate/ledger/__init__.py
CHANGED
|
@@ -24,62 +24,76 @@ import os
|
|
|
24
24
|
from operate.operate_types import Chain
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
ARBITRUM_ONE_PUBLIC_RPC = os.environ.get(
|
|
28
|
+
"ARBITRUM_ONE_RPC", "https://arb1.arbitrum.io/rpc"
|
|
29
|
+
)
|
|
30
30
|
BASE_PUBLIC_RPC = os.environ.get("BASE_RPC", "https://mainnet.base.org")
|
|
31
31
|
CELO_PUBLIC_RPC = os.environ.get("CELO_RPC", "https://forno.celo.org")
|
|
32
|
-
|
|
32
|
+
ETHEREUM_PUBLIC_RPC = os.environ.get("ETHEREUM_RPC", "https://ethereum.publicnode.com")
|
|
33
|
+
GNOSIS_PUBLIC_RPC = os.environ.get("GNOSIS_RPC", "https://gnosis-rpc.publicnode.com")
|
|
33
34
|
MODE_PUBLIC_RPC = os.environ.get("MODE_RPC", "https://mainnet.mode.network/")
|
|
35
|
+
OPTIMISM_PUBLIC_RPC = os.environ.get("OPTIMISM_RPC", "https://mainnet.optimism.io")
|
|
36
|
+
POLYGON_PUBLIC_RPC = os.environ.get("POLYGON_RPC", "https://polygon-rpc.com")
|
|
37
|
+
SOLANA_PUBLIC_RPC = os.environ.get("SOLANA_RPC", "https://api.mainnet-beta.solana.com")
|
|
34
38
|
|
|
35
|
-
|
|
36
|
-
GNOSIS_RPC = os.environ.get("GNOSIS_RPC", "https://rpc-gate.autonolas.tech/gnosis-rpc/")
|
|
37
|
-
SOLANA_RPC = os.environ.get("SOLANA_RPC", "https://api.mainnet-beta.solana.com")
|
|
39
|
+
ARBITRUM_ONE_RPC = os.environ.get("ARBITRUM_ONE_RPC", "https://arb1.arbitrum.io/rpc")
|
|
38
40
|
BASE_RPC = os.environ.get("BASE_RPC", "https://mainnet.base.org")
|
|
39
41
|
CELO_RPC = os.environ.get("CELO_RPC", "https://forno.celo.org")
|
|
40
|
-
|
|
42
|
+
ETHEREUM_RPC = os.environ.get("ETHEREUM_RPC", "https://ethereum.publicnode.com")
|
|
43
|
+
GNOSIS_RPC = os.environ.get("GNOSIS_RPC", "https://rpc-gate.autonolas.tech/gnosis-rpc/")
|
|
41
44
|
MODE_RPC = os.environ.get("MODE_RPC", "https://mainnet.mode.network/")
|
|
45
|
+
OPTIMISM_RPC = os.environ.get("OPTIMISM_RPC", "https://mainnet.optimism.io")
|
|
46
|
+
POLYGON_RPC = os.environ.get("POLYGON_RPC", "https://polygon-rpc.com")
|
|
47
|
+
SOLANA_RPC = os.environ.get("SOLANA_RPC", "https://api.mainnet-beta.solana.com")
|
|
42
48
|
|
|
43
49
|
PUBLIC_RPCS = {
|
|
44
|
-
Chain.
|
|
45
|
-
Chain.GNOSIS: GNOSIS_PUBLIC_RPC,
|
|
46
|
-
Chain.SOLANA: SOLANA_PUBLIC_RPC,
|
|
50
|
+
Chain.ARBITRUM_ONE: ARBITRUM_ONE_PUBLIC_RPC,
|
|
47
51
|
Chain.BASE: BASE_PUBLIC_RPC,
|
|
48
52
|
Chain.CELO: CELO_PUBLIC_RPC,
|
|
49
|
-
Chain.
|
|
53
|
+
Chain.ETHEREUM: ETHEREUM_PUBLIC_RPC,
|
|
54
|
+
Chain.GNOSIS: GNOSIS_PUBLIC_RPC,
|
|
50
55
|
Chain.MODE: MODE_PUBLIC_RPC,
|
|
56
|
+
Chain.OPTIMISM: OPTIMISM_PUBLIC_RPC,
|
|
57
|
+
Chain.POLYGON: POLYGON_PUBLIC_RPC,
|
|
58
|
+
Chain.SOLANA: SOLANA_PUBLIC_RPC,
|
|
51
59
|
}
|
|
52
60
|
|
|
53
61
|
DEFAULT_RPCS = {
|
|
54
|
-
Chain.
|
|
55
|
-
Chain.GNOSIS: GNOSIS_RPC,
|
|
56
|
-
Chain.SOLANA: SOLANA_RPC,
|
|
62
|
+
Chain.ARBITRUM_ONE: ARBITRUM_ONE_RPC,
|
|
57
63
|
Chain.BASE: BASE_RPC,
|
|
58
64
|
Chain.CELO: CELO_RPC,
|
|
59
|
-
Chain.
|
|
65
|
+
Chain.ETHEREUM: ETHEREUM_RPC,
|
|
66
|
+
Chain.GNOSIS: GNOSIS_RPC,
|
|
60
67
|
Chain.MODE: MODE_RPC,
|
|
68
|
+
Chain.OPTIMISM: OPTIMISM_RPC,
|
|
69
|
+
Chain.POLYGON: POLYGON_RPC,
|
|
70
|
+
Chain.SOLANA: SOLANA_RPC,
|
|
61
71
|
}
|
|
62
72
|
|
|
63
73
|
# Base currency for each chain
|
|
64
74
|
CURRENCY_DENOMS = {
|
|
65
|
-
Chain.
|
|
66
|
-
Chain.GNOSIS: "xDAI",
|
|
67
|
-
Chain.SOLANA: "SOL",
|
|
75
|
+
Chain.ARBITRUM_ONE: "ETH",
|
|
68
76
|
Chain.BASE: "ETH",
|
|
69
77
|
Chain.CELO: "CELO",
|
|
70
|
-
Chain.
|
|
78
|
+
Chain.ETHEREUM: "ETH",
|
|
79
|
+
Chain.GNOSIS: "xDAI",
|
|
71
80
|
Chain.MODE: "ETH",
|
|
81
|
+
Chain.OPTIMISM: "ETH",
|
|
82
|
+
Chain.POLYGON: "POL",
|
|
83
|
+
Chain.SOLANA: "SOL",
|
|
72
84
|
}
|
|
73
85
|
|
|
74
86
|
# Smallest denomination for each chain
|
|
75
87
|
CURRENCY_SMALLEST_UNITS = {
|
|
76
|
-
Chain.
|
|
77
|
-
Chain.GNOSIS: "Wei",
|
|
78
|
-
Chain.SOLANA: "Lamport",
|
|
88
|
+
Chain.ARBITRUM_ONE: "Wei",
|
|
79
89
|
Chain.BASE: "Wei",
|
|
80
90
|
Chain.CELO: "Wei",
|
|
81
|
-
Chain.
|
|
91
|
+
Chain.ETHEREUM: "Wei",
|
|
92
|
+
Chain.GNOSIS: "Wei",
|
|
82
93
|
Chain.MODE: "Wei",
|
|
94
|
+
Chain.OPTIMISM: "Wei",
|
|
95
|
+
Chain.POLYGON: "Wei",
|
|
96
|
+
Chain.SOLANA: "Lamport",
|
|
83
97
|
}
|
|
84
98
|
|
|
85
99
|
|
operate/ledger/profiles.py
CHANGED
|
@@ -21,64 +21,46 @@
|
|
|
21
21
|
|
|
22
22
|
import typing as t
|
|
23
23
|
|
|
24
|
+
from autonomy.chain.constants import CHAIN_PROFILES, DEFAULT_MULTISEND
|
|
25
|
+
|
|
24
26
|
from operate.constants import NO_STAKING_PROGRAM_ID, ZERO_ADDRESS
|
|
25
27
|
from operate.operate_types import Chain, ContractAddresses
|
|
26
28
|
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
"gnosis_safe_proxy_factory": "0x5953f21495BD9aF1D78e87bb42AcCAA55C1e896C",
|
|
45
|
-
"gnosis_safe_same_address_multisig": "0xb09CcF0Dbf0C178806Aaee28956c74bd66d21f73",
|
|
46
|
-
"multisend": "0x40A2aCCbd92BCA938b02010E17A5b8929b49130D",
|
|
47
|
-
}
|
|
48
|
-
),
|
|
49
|
-
Chain.ETHEREUM: ContractAddresses(
|
|
50
|
-
{
|
|
51
|
-
"service_manager": "0x2EA682121f815FBcF86EA3F3CaFdd5d67F2dB143",
|
|
52
|
-
"service_registry": "0x48b6af7B12C71f09e2fC8aF4855De4Ff54e775cA",
|
|
53
|
-
"service_registry_token_utility": "0x3Fb926116D454b95c669B6Bf2E7c3bad8d19affA",
|
|
54
|
-
"gnosis_safe_proxy_factory": "0x46C0D07F55d4F9B5Eed2Fc9680B5953e5fd7b461",
|
|
55
|
-
"gnosis_safe_same_address_multisig": "0xfa517d01DaA100cB1932FA4345F68874f7E7eF46",
|
|
56
|
-
"multisend": "0x40A2aCCbd92BCA938b02010E17A5b8929b49130D",
|
|
57
|
-
}
|
|
58
|
-
),
|
|
59
|
-
Chain.BASE: ContractAddresses(
|
|
60
|
-
{
|
|
61
|
-
"service_manager": "0x63e66d7ad413C01A7b49C7FF4e3Bb765C4E4bd1b",
|
|
62
|
-
"service_registry": "0x3C1fF68f5aa342D296d4DEe4Bb1cACCA912D95fE",
|
|
63
|
-
"service_registry_token_utility": "0x34C895f302D0b5cf52ec0Edd3945321EB0f83dd5",
|
|
64
|
-
"gnosis_safe_proxy_factory": "0x22bE6fDcd3e29851B29b512F714C328A00A96B83",
|
|
65
|
-
"gnosis_safe_same_address_multisig": "0xFbBEc0C8b13B38a9aC0499694A69a10204c5E2aB",
|
|
66
|
-
"multisend": "0x40A2aCCbd92BCA938b02010E17A5b8929b49130D",
|
|
67
|
-
}
|
|
68
|
-
),
|
|
69
|
-
Chain.MODE: ContractAddresses(
|
|
30
|
+
# TODO: Refactor, remove the usage of CONTRACTS and use CHAIN_PROFILES from Open Autonomy instead.
|
|
31
|
+
CHAINS = [
|
|
32
|
+
Chain.ARBITRUM_ONE,
|
|
33
|
+
Chain.BASE,
|
|
34
|
+
Chain.CELO,
|
|
35
|
+
Chain.ETHEREUM,
|
|
36
|
+
Chain.GNOSIS,
|
|
37
|
+
Chain.MODE,
|
|
38
|
+
Chain.OPTIMISM,
|
|
39
|
+
Chain.POLYGON,
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
CONTRACTS: t.Dict[Chain, ContractAddresses] = {}
|
|
43
|
+
for _chain in CHAINS:
|
|
44
|
+
profile = CHAIN_PROFILES[_chain.value]
|
|
45
|
+
CONTRACTS[_chain] = ContractAddresses(
|
|
70
46
|
{
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"gnosis_safe_proxy_factory": "
|
|
75
|
-
"gnosis_safe_same_address_multisig":
|
|
76
|
-
|
|
47
|
+
"service_registry": profile["service_registry"],
|
|
48
|
+
"service_registry_token_utility": profile["service_registry_token_utility"],
|
|
49
|
+
"service_manager": profile["service_manager_token"],
|
|
50
|
+
"gnosis_safe_proxy_factory": profile["gnosis_safe_proxy_factory"],
|
|
51
|
+
"gnosis_safe_same_address_multisig": profile[
|
|
52
|
+
"gnosis_safe_same_address_multisig"
|
|
53
|
+
],
|
|
54
|
+
"safe_multisig_with_recovery_module": profile[
|
|
55
|
+
"safe_multisig_with_recovery_module"
|
|
56
|
+
],
|
|
57
|
+
"recovery_module": profile["recovery_module"],
|
|
58
|
+
"multisend": DEFAULT_MULTISEND,
|
|
77
59
|
}
|
|
78
|
-
)
|
|
79
|
-
}
|
|
60
|
+
)
|
|
80
61
|
|
|
81
62
|
STAKING: t.Dict[Chain, t.Dict[str, str]] = {
|
|
63
|
+
Chain.ARBITRUM_ONE: {},
|
|
82
64
|
Chain.GNOSIS: {
|
|
83
65
|
"pearl_alpha": "0xEE9F19b5DF06c7E8Bfc7B28745dcf944C504198A",
|
|
84
66
|
"pearl_beta": "0xeF44Fb0842DDeF59D37f85D61A1eF492bbA6135d",
|
|
@@ -150,6 +132,7 @@ STAKING: t.Dict[Chain, t.Dict[str, str]] = {
|
|
|
150
132
|
"modius_alpha_3": "0x9034D0413D122015710f1744A19eFb1d7c2CEB13",
|
|
151
133
|
"modius_alpha_4": "0x8BcAdb2c291C159F9385964e5eD95a9887302862",
|
|
152
134
|
},
|
|
135
|
+
Chain.POLYGON: {},
|
|
153
136
|
}
|
|
154
137
|
|
|
155
138
|
|
|
@@ -167,37 +150,50 @@ DEFAULT_PRIORITY_MECH = { # maps mech marketplace address to its default priori
|
|
|
167
150
|
|
|
168
151
|
# ERC20 token addresses
|
|
169
152
|
OLAS: t.Dict[Chain, str] = {
|
|
170
|
-
Chain.
|
|
171
|
-
Chain.OPTIMISM: "0xFC2E6e6BCbd49ccf3A5f029c79984372DcBFE527",
|
|
153
|
+
Chain.ARBITRUM_ONE: "0x064F8B858C2A603e1b106a2039f5446D32dc81c1",
|
|
172
154
|
Chain.BASE: "0x54330d28ca3357F294334BDC454a032e7f353416",
|
|
155
|
+
Chain.CELO: "0xaCFfAe8e57Ec6E394Eb1b41939A8CF7892DbDc51",
|
|
173
156
|
Chain.ETHEREUM: "0x0001A500A6B18995B03f44bb040A5fFc28E45CB0",
|
|
157
|
+
Chain.GNOSIS: "0xcE11e14225575945b8E6Dc0D4F2dD4C570f79d9f",
|
|
174
158
|
Chain.MODE: "0xcfD1D50ce23C46D3Cf6407487B2F8934e96DC8f9",
|
|
159
|
+
Chain.OPTIMISM: "0xFC2E6e6BCbd49ccf3A5f029c79984372DcBFE527",
|
|
160
|
+
Chain.POLYGON: "0xFEF5d947472e72Efbb2E388c730B7428406F2F95",
|
|
175
161
|
}
|
|
176
162
|
|
|
177
163
|
USDC: t.Dict[Chain, str] = {
|
|
178
|
-
Chain.
|
|
179
|
-
Chain.OPTIMISM: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",
|
|
164
|
+
Chain.ARBITRUM_ONE: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
|
|
180
165
|
Chain.BASE: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
166
|
+
Chain.CELO: "0xcebA9300f2b948710d2653dD7B07f33A8B32118C",
|
|
181
167
|
Chain.ETHEREUM: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
168
|
+
Chain.GNOSIS: "0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83",
|
|
182
169
|
Chain.MODE: "0xd988097fb8612cc24eeC14542bC03424c656005f",
|
|
170
|
+
Chain.OPTIMISM: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",
|
|
171
|
+
Chain.POLYGON: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
|
|
183
172
|
}
|
|
184
173
|
|
|
185
174
|
WRAPPED_NATIVE_ASSET = {
|
|
186
|
-
Chain.
|
|
187
|
-
Chain.OPTIMISM: "0x4200000000000000000000000000000000000006",
|
|
175
|
+
Chain.ARBITRUM_ONE: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
|
|
188
176
|
Chain.BASE: "0x4200000000000000000000000000000000000006",
|
|
177
|
+
Chain.CELO: "0x471EcE3750Da237f93B8E339c536989b8978a438", # Dual token
|
|
189
178
|
Chain.ETHEREUM: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
|
179
|
+
Chain.GNOSIS: "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d",
|
|
190
180
|
Chain.MODE: "0x4200000000000000000000000000000000000006",
|
|
181
|
+
Chain.OPTIMISM: "0x4200000000000000000000000000000000000006",
|
|
191
182
|
Chain.POLYGON: "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",
|
|
192
|
-
Chain.ARBITRUM_ONE: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
|
|
193
183
|
}
|
|
194
184
|
|
|
195
185
|
ERC20_TOKENS = [OLAS, USDC, WRAPPED_NATIVE_ASSET]
|
|
196
186
|
|
|
197
187
|
DEFAULT_NEW_SAFE_FUNDS: t.Dict[Chain, t.Dict[str, int]] = {
|
|
188
|
+
Chain.ARBITRUM_ONE: {
|
|
189
|
+
ZERO_ADDRESS: int(1e15 / 4),
|
|
190
|
+
},
|
|
198
191
|
Chain.BASE: {
|
|
199
192
|
ZERO_ADDRESS: int(1e15 / 4),
|
|
200
193
|
},
|
|
194
|
+
Chain.CELO: {
|
|
195
|
+
ZERO_ADDRESS: int(1e18),
|
|
196
|
+
},
|
|
201
197
|
Chain.ETHEREUM: {
|
|
202
198
|
ZERO_ADDRESS: int(1e15 / 4),
|
|
203
199
|
},
|
|
@@ -210,21 +206,35 @@ DEFAULT_NEW_SAFE_FUNDS: t.Dict[Chain, t.Dict[str, int]] = {
|
|
|
210
206
|
Chain.OPTIMISM: {
|
|
211
207
|
ZERO_ADDRESS: int(1e15 / 4),
|
|
212
208
|
},
|
|
209
|
+
Chain.POLYGON: {
|
|
210
|
+
ZERO_ADDRESS: int(1e18),
|
|
211
|
+
},
|
|
213
212
|
}
|
|
214
213
|
|
|
215
214
|
DEFAULT_MASTER_EOA_FUNDS = {
|
|
215
|
+
Chain.ARBITRUM_ONE: {ZERO_ADDRESS: 5_000_000_000_000_000},
|
|
216
216
|
Chain.BASE: {ZERO_ADDRESS: 5_000_000_000_000_000},
|
|
217
|
+
Chain.CELO: {ZERO_ADDRESS: 1_500_000_000_000_000_000},
|
|
217
218
|
Chain.ETHEREUM: {ZERO_ADDRESS: 20_000_000_000_000_000},
|
|
218
219
|
Chain.GNOSIS: {ZERO_ADDRESS: 1_500_000_000_000_000_000},
|
|
219
220
|
Chain.MODE: {ZERO_ADDRESS: 500_000_000_000_000},
|
|
220
221
|
Chain.OPTIMISM: {ZERO_ADDRESS: 5_000_000_000_000_000},
|
|
222
|
+
Chain.POLYGON: {ZERO_ADDRESS: 1_500_000_000_000_000_000},
|
|
221
223
|
}
|
|
222
224
|
|
|
223
225
|
EXPLORER_URL = {
|
|
226
|
+
Chain.ARBITRUM_ONE: {
|
|
227
|
+
"tx": "https://arbiscan.io/tx/{tx_hash}",
|
|
228
|
+
"address": "https://arbiscan.io/address/{address}",
|
|
229
|
+
},
|
|
224
230
|
Chain.BASE: {
|
|
225
231
|
"tx": "https://basescan.org/tx/{tx_hash}",
|
|
226
232
|
"address": "https://basescan.org/address/{address}",
|
|
227
233
|
},
|
|
234
|
+
Chain.CELO: {
|
|
235
|
+
"tx": "https://celoscan.io/tx/{tx_hash}",
|
|
236
|
+
"address": "https://celoscan.io/address/{address}",
|
|
237
|
+
},
|
|
228
238
|
Chain.ETHEREUM: {
|
|
229
239
|
"tx": "https://etherscan.io/tx/{tx_hash}",
|
|
230
240
|
"address": "https://etherscan.io/address/{address}",
|
|
@@ -234,13 +244,17 @@ EXPLORER_URL = {
|
|
|
234
244
|
"address": "https://gnosisscan.io/address/{address}",
|
|
235
245
|
},
|
|
236
246
|
Chain.MODE: {
|
|
237
|
-
"tx": "https://
|
|
238
|
-
"address": "https://
|
|
247
|
+
"tx": "https://explorer.mode.network/tx/{tx_hash}",
|
|
248
|
+
"address": "https://explorer.mode.network/address/{address}",
|
|
239
249
|
},
|
|
240
250
|
Chain.OPTIMISM: {
|
|
241
251
|
"tx": "https://optimistic.etherscan.io/tx/{tx_hash}",
|
|
242
252
|
"address": "https://optimistic.etherscan.io/address/{address}",
|
|
243
253
|
},
|
|
254
|
+
Chain.POLYGON: {
|
|
255
|
+
"tx": "https://polygonscan.com/tx/{tx_hash}",
|
|
256
|
+
"address": "https://polygonscan.com/address/{address}",
|
|
257
|
+
},
|
|
244
258
|
}
|
|
245
259
|
|
|
246
260
|
|
operate/migration.py
CHANGED
|
@@ -29,11 +29,10 @@ from time import time
|
|
|
29
29
|
|
|
30
30
|
from aea_cli_ipfs.ipfs_utils import IPFSTool
|
|
31
31
|
|
|
32
|
-
from operate.constants import ZERO_ADDRESS
|
|
32
|
+
from operate.constants import USER_JSON, ZERO_ADDRESS
|
|
33
33
|
from operate.operate_types import Chain, LedgerType
|
|
34
34
|
from operate.services.manage import ServiceManager
|
|
35
35
|
from operate.services.service import (
|
|
36
|
-
DEFAULT_TRADER_ENV_VARS,
|
|
37
36
|
NON_EXISTENT_MULTISIG,
|
|
38
37
|
SERVICE_CONFIG_PREFIX,
|
|
39
38
|
SERVICE_CONFIG_VERSION,
|
|
@@ -43,11 +42,67 @@ from operate.utils import create_backup
|
|
|
43
42
|
from operate.wallet.master import LEDGER_TYPE_TO_WALLET_CLASS, MasterWalletManager
|
|
44
43
|
|
|
45
44
|
|
|
45
|
+
DEFAULT_TRADER_ENV_VARS = {
|
|
46
|
+
"GNOSIS_LEDGER_RPC": {
|
|
47
|
+
"name": "Gnosis ledger RPC",
|
|
48
|
+
"description": "",
|
|
49
|
+
"value": "",
|
|
50
|
+
"provision_type": "computed",
|
|
51
|
+
},
|
|
52
|
+
"STAKING_CONTRACT_ADDRESS": {
|
|
53
|
+
"name": "Staking contract address",
|
|
54
|
+
"description": "",
|
|
55
|
+
"value": "",
|
|
56
|
+
"provision_type": "computed",
|
|
57
|
+
},
|
|
58
|
+
"MECH_MARKETPLACE_CONFIG": {
|
|
59
|
+
"name": "Mech marketplace configuration",
|
|
60
|
+
"description": "",
|
|
61
|
+
"value": "",
|
|
62
|
+
"provision_type": "computed",
|
|
63
|
+
},
|
|
64
|
+
"MECH_ACTIVITY_CHECKER_CONTRACT": {
|
|
65
|
+
"name": "Mech activity checker contract",
|
|
66
|
+
"description": "",
|
|
67
|
+
"value": "",
|
|
68
|
+
"provision_type": "computed",
|
|
69
|
+
},
|
|
70
|
+
"MECH_CONTRACT_ADDRESS": {
|
|
71
|
+
"name": "Mech contract address",
|
|
72
|
+
"description": "",
|
|
73
|
+
"value": "",
|
|
74
|
+
"provision_type": "computed",
|
|
75
|
+
},
|
|
76
|
+
"MECH_REQUEST_PRICE": {
|
|
77
|
+
"name": "Mech request price",
|
|
78
|
+
"description": "",
|
|
79
|
+
"value": "10000000000000000",
|
|
80
|
+
"provision_type": "computed",
|
|
81
|
+
},
|
|
82
|
+
"USE_MECH_MARKETPLACE": {
|
|
83
|
+
"name": "Use Mech marketplace",
|
|
84
|
+
"description": "",
|
|
85
|
+
"value": "False",
|
|
86
|
+
"provision_type": "computed",
|
|
87
|
+
},
|
|
88
|
+
"REQUESTER_STAKING_INSTANCE_ADDRESS": {
|
|
89
|
+
"name": "Requester staking instance address",
|
|
90
|
+
"description": "",
|
|
91
|
+
"value": "",
|
|
92
|
+
"provision_type": "computed",
|
|
93
|
+
},
|
|
94
|
+
"PRIORITY_MECH_ADDRESS": {
|
|
95
|
+
"name": "Priority Mech address",
|
|
96
|
+
"description": "",
|
|
97
|
+
"value": "",
|
|
98
|
+
"provision_type": "computed",
|
|
99
|
+
},
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
|
|
46
103
|
class MigrationManager:
|
|
47
104
|
"""MigrationManager"""
|
|
48
105
|
|
|
49
|
-
# TODO Backport here migration for services/config.json, etc.
|
|
50
|
-
|
|
51
106
|
def __init__(
|
|
52
107
|
self,
|
|
53
108
|
home: Path,
|
|
@@ -62,12 +117,12 @@ class MigrationManager:
|
|
|
62
117
|
"""Log directories present in `path`."""
|
|
63
118
|
directories = [f" - {str(p)}" for p in path.iterdir() if p.is_dir()]
|
|
64
119
|
directories_str = "\n".join(directories)
|
|
65
|
-
self.logger.info(f"Directories in {path}
|
|
120
|
+
self.logger.info(f"Directories in {path}:\n{directories_str}")
|
|
66
121
|
|
|
67
122
|
def migrate_user_account(self) -> None:
|
|
68
123
|
"""Migrates user.json"""
|
|
69
124
|
|
|
70
|
-
path = self._path /
|
|
125
|
+
path = self._path / USER_JSON
|
|
71
126
|
if not path.exists():
|
|
72
127
|
return
|
|
73
128
|
|
|
@@ -102,18 +157,22 @@ class MigrationManager:
|
|
|
102
157
|
|
|
103
158
|
self.logger.info("Migrating wallet configs done.")
|
|
104
159
|
|
|
105
|
-
@staticmethod
|
|
106
160
|
def _migrate_service( # pylint: disable=too-many-statements,too-many-locals
|
|
161
|
+
self,
|
|
107
162
|
path: Path,
|
|
108
163
|
) -> bool:
|
|
109
164
|
"""Migrate the JSON file format if needed."""
|
|
110
165
|
|
|
111
166
|
if not path.is_dir():
|
|
167
|
+
self.logger.warning(f"Service config path {path} is not a directory.")
|
|
112
168
|
return False
|
|
113
169
|
|
|
114
170
|
if not path.name.startswith(SERVICE_CONFIG_PREFIX) and not path.name.startswith(
|
|
115
171
|
"bafybei"
|
|
116
172
|
):
|
|
173
|
+
self.logger.warning(
|
|
174
|
+
f"Service config path {path} is not a valid service config."
|
|
175
|
+
)
|
|
117
176
|
return False
|
|
118
177
|
|
|
119
178
|
if path.name.startswith("bafybei"):
|
|
@@ -155,6 +214,10 @@ class MigrationManager:
|
|
|
155
214
|
if version == SERVICE_CONFIG_VERSION:
|
|
156
215
|
return False
|
|
157
216
|
|
|
217
|
+
self.logger.info(
|
|
218
|
+
f"Migrating service config in {path} from version {version} to {SERVICE_CONFIG_VERSION}..."
|
|
219
|
+
)
|
|
220
|
+
|
|
158
221
|
# Migration steps for older versions
|
|
159
222
|
if version == 0:
|
|
160
223
|
new_data = {
|
|
@@ -344,13 +407,9 @@ class MigrationManager:
|
|
|
344
407
|
paths = list(service_manager.path.iterdir())
|
|
345
408
|
for path in paths:
|
|
346
409
|
try:
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
self.logger.info(f"migrate_service_configs {str(path)}")
|
|
351
|
-
migrated = self._migrate_service(path)
|
|
352
|
-
if migrated:
|
|
353
|
-
self.logger.info(f"Folder {str(path)} has been migrated.")
|
|
410
|
+
migrated = self._migrate_service(path)
|
|
411
|
+
if migrated:
|
|
412
|
+
self.logger.info(f"Folder {str(path)} has been migrated.")
|
|
354
413
|
except Exception as e: # pylint: disable=broad-except
|
|
355
414
|
self.logger.error(
|
|
356
415
|
f"Failed to migrate service: {path.name}. Exception {e}: {traceback.format_exc()}"
|
operate/operate_types.py
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
from typing import TYPE_CHECKING
|
|
22
22
|
|
|
23
23
|
from operate.account.user import UserAccount
|
|
24
|
+
from operate.constants import USER_JSON
|
|
24
25
|
from operate.operate_types import LedgerType
|
|
25
26
|
from operate.quickstart.run_service import ask_confirm_password
|
|
26
27
|
from operate.quickstart.utils import ask_or_get_from_env, print_section, print_title
|
|
@@ -36,7 +37,7 @@ def reset_password(operate: "OperateApp") -> None:
|
|
|
36
37
|
print_title("Reset your password")
|
|
37
38
|
|
|
38
39
|
# check if agent was started before
|
|
39
|
-
if not (operate._path /
|
|
40
|
+
if not (operate._path / USER_JSON).exists():
|
|
40
41
|
print("No previous agent setup found. Exiting.")
|
|
41
42
|
return
|
|
42
43
|
|
|
@@ -57,7 +58,7 @@ def reset_password(operate: "OperateApp") -> None:
|
|
|
57
58
|
print("Resetting password of user account...")
|
|
58
59
|
UserAccount.new(
|
|
59
60
|
password=old_password,
|
|
60
|
-
path=operate._path /
|
|
61
|
+
path=operate._path / USER_JSON,
|
|
61
62
|
).update(
|
|
62
63
|
old_password=old_password,
|
|
63
64
|
new_password=new_password,
|
|
@@ -34,7 +34,12 @@ from halo import Halo # type: ignore[import]
|
|
|
34
34
|
from web3.exceptions import Web3Exception
|
|
35
35
|
|
|
36
36
|
from operate.account.user import UserAccount
|
|
37
|
-
from operate.constants import
|
|
37
|
+
from operate.constants import (
|
|
38
|
+
IPFS_ADDRESS,
|
|
39
|
+
NO_STAKING_PROGRAM_ID,
|
|
40
|
+
OPERATE_HOME,
|
|
41
|
+
USER_JSON,
|
|
42
|
+
)
|
|
38
43
|
from operate.data import DATA_DIR
|
|
39
44
|
from operate.data.contracts.staking_token.contract import StakingTokenContract
|
|
40
45
|
from operate.ledger.profiles import STAKING, get_staking_contract
|
|
@@ -453,7 +458,7 @@ def ask_password_if_needed(operate: "OperateApp") -> None:
|
|
|
453
458
|
password = ask_confirm_password()
|
|
454
459
|
UserAccount.new(
|
|
455
460
|
password=password,
|
|
456
|
-
path=operate._path /
|
|
461
|
+
path=operate._path / USER_JSON,
|
|
457
462
|
)
|
|
458
463
|
else:
|
|
459
464
|
_password = None
|