olas-operate-middleware 0.10.18__tar.gz → 0.10.20__tar.gz
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.18 → olas_operate_middleware-0.10.20}/PKG-INFO +1 -1
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/bridge/providers/lifi_provider.py +5 -4
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/bridge/providers/native_bridge_provider.py +5 -4
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/bridge/providers/provider.py +2 -54
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/bridge/providers/relay_provider.py +5 -4
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/cli.py +8 -60
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/constants.py +2 -2
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/keys.py +13 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/ledger/__init__.py +55 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/quickstart/run_service.py +5 -9
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/services/agent_runner.py +2 -2
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/services/health_checker.py +4 -4
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/services/manage.py +18 -4
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/utils/__init__.py +0 -29
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/wallet/master.py +8 -5
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/pyproject.toml +1 -1
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/LICENSE +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/README.md +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/__init__.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/account/__init__.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/account/user.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/bridge/bridge_manager.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/README.md +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/__init__.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/__init__.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/dual_staking_token/__init__.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/dual_staking_token/build/DualStakingToken.json +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/dual_staking_token/contract.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/dual_staking_token/contract.yaml +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/foreign_omnibridge/__init__.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/foreign_omnibridge/build/ForeignOmnibridge.json +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/foreign_omnibridge/contract.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/foreign_omnibridge/contract.yaml +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/home_omnibridge/__init__.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/home_omnibridge/build/HomeOmnibridge.json +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/home_omnibridge/contract.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/home_omnibridge/contract.yaml +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/l1_standard_bridge/__init__.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/l1_standard_bridge/build/L1StandardBridge.json +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/l1_standard_bridge/contract.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/l1_standard_bridge/contract.yaml +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/l2_standard_bridge/__init__.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/l2_standard_bridge/build/L2StandardBridge.json +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/l2_standard_bridge/contract.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/l2_standard_bridge/contract.yaml +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/mech_activity/__init__.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/mech_activity/build/MechActivity.json +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/mech_activity/contract.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/mech_activity/contract.yaml +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/optimism_mintable_erc20/__init__.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/optimism_mintable_erc20/build/OptimismMintableERC20.json +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/optimism_mintable_erc20/contract.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/optimism_mintable_erc20/contract.yaml +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/recovery_module/__init__.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/recovery_module/build/RecoveryModule.json +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/recovery_module/contract.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/recovery_module/contract.yaml +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/requester_activity_checker/__init__.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/requester_activity_checker/build/RequesterActivityChecker.json +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/requester_activity_checker/contract.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/requester_activity_checker/contract.yaml +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/staking_token/__init__.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/staking_token/build/StakingToken.json +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/staking_token/contract.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/staking_token/contract.yaml +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/uniswap_v2_erc20/__init__.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/uniswap_v2_erc20/build/IUniswapV2ERC20.json +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/uniswap_v2_erc20/contract.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/uniswap_v2_erc20/contract.yaml +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/uniswap_v2_erc20/tests/__init__.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/contracts/uniswap_v2_erc20/tests/test_contract.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/ledger/profiles.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/migration.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/operate_http/__init__.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/operate_http/exceptions.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/operate_types.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/pearl.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/quickstart/analyse_logs.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/quickstart/claim_staking_rewards.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/quickstart/reset_configs.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/quickstart/reset_password.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/quickstart/reset_staking.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/quickstart/stop_service.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/quickstart/terminate_on_chain_service.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/quickstart/utils.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/resource.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/services/__init__.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/services/deployment_runner.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/services/protocol.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/services/service.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/services/utils/__init__.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/services/utils/mech.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/services/utils/tendermint.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/utils/gnosis.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/utils/ssl.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/wallet/__init__.py +0 -0
- {olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/wallet/wallet_recovery_manager.py +0 -0
|
@@ -38,6 +38,7 @@ from operate.bridge.providers.provider import (
|
|
|
38
38
|
QuoteData,
|
|
39
39
|
)
|
|
40
40
|
from operate.constants import ZERO_ADDRESS
|
|
41
|
+
from operate.ledger import update_tx_with_gas_estimate, update_tx_with_gas_pricing
|
|
41
42
|
from operate.operate_types import Chain
|
|
42
43
|
|
|
43
44
|
|
|
@@ -240,8 +241,8 @@ class LiFiProvider(Provider):
|
|
|
240
241
|
amount=from_amount,
|
|
241
242
|
)
|
|
242
243
|
approve_tx["gas"] = 200_000 # TODO backport to ERC20 contract as default
|
|
243
|
-
|
|
244
|
-
|
|
244
|
+
update_tx_with_gas_pricing(approve_tx, from_ledger_api)
|
|
245
|
+
update_tx_with_gas_estimate(approve_tx, from_ledger_api)
|
|
245
246
|
return approve_tx
|
|
246
247
|
|
|
247
248
|
def _get_bridge_tx(self, provider_request: ProviderRequest) -> t.Optional[t.Dict]:
|
|
@@ -285,8 +286,8 @@ class LiFiProvider(Provider):
|
|
|
285
286
|
transaction_request["from"]
|
|
286
287
|
),
|
|
287
288
|
}
|
|
288
|
-
|
|
289
|
-
|
|
289
|
+
update_tx_with_gas_pricing(bridge_tx, from_ledger_api)
|
|
290
|
+
update_tx_with_gas_estimate(bridge_tx, from_ledger_api)
|
|
290
291
|
return bridge_tx
|
|
291
292
|
|
|
292
293
|
def _get_txs(
|
|
@@ -53,6 +53,7 @@ from operate.data.contracts.l2_standard_bridge.contract import L2StandardBridge
|
|
|
53
53
|
from operate.data.contracts.optimism_mintable_erc20.contract import (
|
|
54
54
|
OptimismMintableERC20,
|
|
55
55
|
)
|
|
56
|
+
from operate.ledger import update_tx_with_gas_estimate, update_tx_with_gas_pricing
|
|
56
57
|
from operate.ledger.profiles import ERC20_TOKENS, EXPLORER_URL
|
|
57
58
|
from operate.operate_types import Chain
|
|
58
59
|
from operate.wallet.master import MasterWalletManager
|
|
@@ -512,8 +513,8 @@ class NativeBridgeProvider(Provider):
|
|
|
512
513
|
amount=to_amount,
|
|
513
514
|
)
|
|
514
515
|
approve_tx["gas"] = 200_000 # TODO backport to ERC20 contract as default
|
|
515
|
-
|
|
516
|
-
|
|
516
|
+
update_tx_with_gas_pricing(approve_tx, from_ledger_api)
|
|
517
|
+
update_tx_with_gas_estimate(approve_tx, from_ledger_api)
|
|
517
518
|
return approve_tx
|
|
518
519
|
|
|
519
520
|
def _get_bridge_tx(self, provider_request: ProviderRequest) -> t.Optional[t.Dict]:
|
|
@@ -534,8 +535,8 @@ class NativeBridgeProvider(Provider):
|
|
|
534
535
|
from_ledger_api=from_ledger_api, provider_request=provider_request
|
|
535
536
|
)
|
|
536
537
|
|
|
537
|
-
|
|
538
|
-
|
|
538
|
+
update_tx_with_gas_pricing(bridge_tx, from_ledger_api)
|
|
539
|
+
update_tx_with_gas_estimate(bridge_tx, from_ledger_api)
|
|
539
540
|
return bridge_tx
|
|
540
541
|
|
|
541
542
|
def _get_txs(
|
|
@@ -28,7 +28,6 @@ import typing as t
|
|
|
28
28
|
import uuid
|
|
29
29
|
from abc import ABC, abstractmethod
|
|
30
30
|
from dataclasses import dataclass
|
|
31
|
-
from math import ceil
|
|
32
31
|
|
|
33
32
|
from aea.crypto.base import LedgerApi
|
|
34
33
|
from autonomy.chain.tx import TxSettler
|
|
@@ -41,16 +40,12 @@ from operate.constants import (
|
|
|
41
40
|
ON_CHAIN_INTERACT_TIMEOUT,
|
|
42
41
|
ZERO_ADDRESS,
|
|
43
42
|
)
|
|
43
|
+
from operate.ledger import update_tx_with_gas_pricing
|
|
44
44
|
from operate.operate_types import Chain
|
|
45
45
|
from operate.resource import LocalResource
|
|
46
46
|
from operate.wallet.master import MasterWalletManager
|
|
47
47
|
|
|
48
48
|
|
|
49
|
-
GAS_ESTIMATE_FALLBACK_ADDRESSES = [
|
|
50
|
-
"0x000000000000000000000000000000000000dEaD",
|
|
51
|
-
"0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", # nosec
|
|
52
|
-
]
|
|
53
|
-
|
|
54
49
|
DEFAULT_MAX_QUOTE_RETRIES = 3
|
|
55
50
|
PROVIDER_REQUEST_PREFIX = "r-"
|
|
56
51
|
MESSAGE_QUOTE_ZERO = "Zero-amount quote requested."
|
|
@@ -66,8 +61,6 @@ MESSAGE_REQUIREMENTS_QUOTE_FAILED = "Cannot compute requirements for failed quot
|
|
|
66
61
|
|
|
67
62
|
ERC20_APPROVE_SELECTOR = "0x095ea7b3" # First 4 bytes of Web3.keccak(text='approve(address,uint256)').hex()[:10]
|
|
68
63
|
|
|
69
|
-
GAS_ESTIMATE_BUFFER = 1.10
|
|
70
|
-
|
|
71
64
|
|
|
72
65
|
@dataclass
|
|
73
66
|
class QuoteData(LocalResource):
|
|
@@ -291,7 +284,7 @@ class Provider(ABC):
|
|
|
291
284
|
self.logger.debug(
|
|
292
285
|
f"[PROVIDER] Processing transaction {tx_label} for request {provider_request.id}."
|
|
293
286
|
)
|
|
294
|
-
|
|
287
|
+
update_tx_with_gas_pricing(tx, from_ledger_api)
|
|
295
288
|
gas_key = "gasPrice" if "gasPrice" in tx else "maxFeePerGas"
|
|
296
289
|
gas_fees = tx.get(gas_key, 0) * tx["gas"]
|
|
297
290
|
tx_value = int(tx.get("value", 0))
|
|
@@ -487,48 +480,3 @@ class Provider(ABC):
|
|
|
487
480
|
receipt = ledger_api.api.eth.get_transaction_receipt(tx_hash)
|
|
488
481
|
block = ledger_api.api.eth.get_block(receipt.blockNumber)
|
|
489
482
|
return block.timestamp
|
|
490
|
-
|
|
491
|
-
# TODO backport to open aea/autonomy
|
|
492
|
-
# TODO This gas pricing management should possibly be done at a lower level in the library
|
|
493
|
-
@staticmethod
|
|
494
|
-
def _update_with_gas_pricing(tx: t.Dict, ledger_api: LedgerApi) -> None:
|
|
495
|
-
tx.pop("maxFeePerGas", None)
|
|
496
|
-
tx.pop("gasPrice", None)
|
|
497
|
-
tx.pop("maxPriorityFeePerGas", None)
|
|
498
|
-
|
|
499
|
-
gas_pricing = ledger_api.try_get_gas_pricing()
|
|
500
|
-
if gas_pricing is None:
|
|
501
|
-
raise RuntimeError("Unable to retrieve gas pricing.")
|
|
502
|
-
|
|
503
|
-
if "maxFeePerGas" in gas_pricing and "maxPriorityFeePerGas" in gas_pricing:
|
|
504
|
-
tx["maxFeePerGas"] = gas_pricing["maxFeePerGas"]
|
|
505
|
-
tx["maxPriorityFeePerGas"] = gas_pricing["maxPriorityFeePerGas"]
|
|
506
|
-
elif "gasPrice" in gas_pricing:
|
|
507
|
-
tx["gasPrice"] = gas_pricing["gasPrice"]
|
|
508
|
-
else:
|
|
509
|
-
raise RuntimeError("Retrieved invalid gas pricing.")
|
|
510
|
-
|
|
511
|
-
# TODO backport to open aea/autonomy
|
|
512
|
-
@staticmethod
|
|
513
|
-
def _update_with_gas_estimate(tx: t.Dict, ledger_api: LedgerApi) -> None:
|
|
514
|
-
print(
|
|
515
|
-
f"[PROVIDER] Trying to update transaction gas {tx['from']=} {tx['gas']=}."
|
|
516
|
-
)
|
|
517
|
-
original_from = tx["from"]
|
|
518
|
-
original_gas = tx.get("gas", 1)
|
|
519
|
-
|
|
520
|
-
for address in [original_from] + GAS_ESTIMATE_FALLBACK_ADDRESSES:
|
|
521
|
-
tx["from"] = address
|
|
522
|
-
tx["gas"] = 1
|
|
523
|
-
ledger_api.update_with_gas_estimate(tx)
|
|
524
|
-
if tx["gas"] > 1:
|
|
525
|
-
print(
|
|
526
|
-
f"[PROVIDER] Gas estimated successfully {tx['from']=} {tx['gas']=}."
|
|
527
|
-
)
|
|
528
|
-
break
|
|
529
|
-
|
|
530
|
-
tx["from"] = original_from
|
|
531
|
-
if tx["gas"] == 1:
|
|
532
|
-
tx["gas"] = original_gas
|
|
533
|
-
print(f"[PROVIDER] Unable to estimate gas. Restored {tx['gas']=}.")
|
|
534
|
-
tx["gas"] = ceil(tx["gas"] * GAS_ESTIMATE_BUFFER)
|
|
@@ -39,6 +39,7 @@ from operate.bridge.providers.provider import (
|
|
|
39
39
|
ProviderRequestStatus,
|
|
40
40
|
QuoteData,
|
|
41
41
|
)
|
|
42
|
+
from operate.ledger import update_tx_with_gas_estimate, update_tx_with_gas_pricing
|
|
42
43
|
from operate.operate_types import Chain
|
|
43
44
|
|
|
44
45
|
|
|
@@ -258,10 +259,10 @@ class RelayProvider(Provider):
|
|
|
258
259
|
timestamp=int(time.time()),
|
|
259
260
|
)
|
|
260
261
|
except requests.RequestException as e:
|
|
262
|
+
response_json = response.json()
|
|
261
263
|
self.logger.warning(
|
|
262
|
-
f"[RELAY PROVIDER] Request failed on attempt {attempt}/{DEFAULT_MAX_QUOTE_RETRIES}: {
|
|
264
|
+
f"[RELAY PROVIDER] Request failed on attempt {attempt}/{DEFAULT_MAX_QUOTE_RETRIES}: {response_json}."
|
|
263
265
|
)
|
|
264
|
-
response_json = response.json()
|
|
265
266
|
quote_data = QuoteData(
|
|
266
267
|
eta=None,
|
|
267
268
|
elapsed_time=time.time() - start,
|
|
@@ -338,8 +339,8 @@ class RelayProvider(Provider):
|
|
|
338
339
|
tx["maxFeePerGas"] = int(tx.get("maxFeePerGas", 0))
|
|
339
340
|
tx["maxPriorityFeePerGas"] = int(tx.get("maxPriorityFeePerGas", 0))
|
|
340
341
|
tx["nonce"] = from_ledger_api.api.eth.get_transaction_count(tx["from"])
|
|
341
|
-
|
|
342
|
-
|
|
342
|
+
update_tx_with_gas_pricing(tx, from_ledger_api)
|
|
343
|
+
update_tx_with_gas_estimate(tx, from_ledger_api)
|
|
343
344
|
txs.append((f"{step['id']}-{i}", tx))
|
|
344
345
|
|
|
345
346
|
return txs
|
|
@@ -36,8 +36,6 @@ import psutil
|
|
|
36
36
|
import requests
|
|
37
37
|
from aea.helpers.logging import setup_logger
|
|
38
38
|
from clea import group, params, run
|
|
39
|
-
from compose.project import ProjectError
|
|
40
|
-
from docker.errors import APIError
|
|
41
39
|
from fastapi import FastAPI, Request
|
|
42
40
|
from fastapi.middleware.cors import CORSMiddleware
|
|
43
41
|
from fastapi.responses import JSONResponse
|
|
@@ -415,37 +413,17 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
415
413
|
allow_methods=["GET", "POST", "PUT", "PATCH", "DELETE"],
|
|
416
414
|
)
|
|
417
415
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
logger.
|
|
424
|
-
retries = 0
|
|
425
|
-
while retries < DEFAULT_MAX_RETRIES:
|
|
426
|
-
try:
|
|
427
|
-
return await f(request)
|
|
428
|
-
except (APIError, ProjectError) as e:
|
|
429
|
-
logger.error(f"Error {e}\n{traceback.format_exc()}")
|
|
430
|
-
if "has active endpoints" in str(e):
|
|
431
|
-
error_msg = "Service is already running."
|
|
432
|
-
else:
|
|
433
|
-
error_msg = "Service deployment failed. Please check the logs."
|
|
434
|
-
return JSONResponse(
|
|
435
|
-
content={"error": error_msg},
|
|
436
|
-
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
437
|
-
)
|
|
438
|
-
except Exception as e: # pylint: disable=broad-except
|
|
439
|
-
logger.error(f"Error {str(e)}\n{traceback.format_exc()}")
|
|
440
|
-
retries += 1
|
|
416
|
+
@app.middleware("http")
|
|
417
|
+
async def handle_internal_server_error(request: Request, call_next):
|
|
418
|
+
try:
|
|
419
|
+
response = await call_next(request)
|
|
420
|
+
except Exception as e: # pylint: disable=broad-except
|
|
421
|
+
logger.error(f"Error {str(e)}\n{traceback.format_exc()}")
|
|
441
422
|
return JSONResponse(
|
|
442
|
-
content={
|
|
443
|
-
"error": "Operation failed after multiple attempts. Please try again later."
|
|
444
|
-
},
|
|
423
|
+
content={"error": str(e)},
|
|
445
424
|
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
446
425
|
)
|
|
447
|
-
|
|
448
|
-
return _call
|
|
426
|
+
return response
|
|
449
427
|
|
|
450
428
|
@app.get(f"/{shutdown_endpoint}")
|
|
451
429
|
async def _kill_server(request: Request) -> JSONResponse:
|
|
@@ -464,19 +442,16 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
464
442
|
return JSONResponse(content={"stopped": True})
|
|
465
443
|
|
|
466
444
|
@app.get("/api")
|
|
467
|
-
@with_retries
|
|
468
445
|
async def _get_api(request: Request) -> JSONResponse:
|
|
469
446
|
"""Get API info."""
|
|
470
447
|
return JSONResponse(content=operate.json)
|
|
471
448
|
|
|
472
449
|
@app.get("/api/account")
|
|
473
|
-
@with_retries
|
|
474
450
|
async def _get_account(request: Request) -> t.Dict:
|
|
475
451
|
"""Get account information."""
|
|
476
452
|
return {"is_setup": operate.user_account is not None}
|
|
477
453
|
|
|
478
454
|
@app.post("/api/account")
|
|
479
|
-
@with_retries
|
|
480
455
|
async def _setup_account(request: Request) -> t.Dict:
|
|
481
456
|
"""Setup account."""
|
|
482
457
|
if operate.user_account is not None:
|
|
@@ -498,7 +473,6 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
498
473
|
return JSONResponse(content={"error": None})
|
|
499
474
|
|
|
500
475
|
@app.put("/api/account")
|
|
501
|
-
@with_retries
|
|
502
476
|
async def _update_password( # pylint: disable=too-many-return-statements
|
|
503
477
|
request: Request,
|
|
504
478
|
) -> t.Dict:
|
|
@@ -568,7 +542,6 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
568
542
|
)
|
|
569
543
|
|
|
570
544
|
@app.post("/api/account/login")
|
|
571
|
-
@with_retries
|
|
572
545
|
async def _validate_password(request: Request) -> t.Dict:
|
|
573
546
|
"""Validate password."""
|
|
574
547
|
if operate.user_account is None:
|
|
@@ -588,7 +561,6 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
588
561
|
)
|
|
589
562
|
|
|
590
563
|
@app.get("/api/wallet")
|
|
591
|
-
@with_retries
|
|
592
564
|
async def _get_wallets(request: Request) -> t.List[t.Dict]:
|
|
593
565
|
"""Get wallets."""
|
|
594
566
|
wallets = []
|
|
@@ -597,7 +569,6 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
597
569
|
return JSONResponse(content=wallets)
|
|
598
570
|
|
|
599
571
|
@app.post("/api/wallet")
|
|
600
|
-
@with_retries
|
|
601
572
|
async def _create_wallet(request: Request) -> t.List[t.Dict]:
|
|
602
573
|
"""Create wallet"""
|
|
603
574
|
if operate.user_account is None:
|
|
@@ -620,7 +591,6 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
620
591
|
return JSONResponse(content={"wallet": wallet.json, "mnemonic": mnemonic})
|
|
621
592
|
|
|
622
593
|
@app.post("/api/wallet/private_key")
|
|
623
|
-
@with_retries
|
|
624
594
|
async def _get_private_key(request: Request) -> t.List[t.Dict]:
|
|
625
595
|
"""Get Master EOA private key."""
|
|
626
596
|
if operate.user_account is None:
|
|
@@ -641,7 +611,6 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
641
611
|
return JSONResponse(content={"private_key": wallet.crypto.private_key})
|
|
642
612
|
|
|
643
613
|
@app.get("/api/extended/wallet")
|
|
644
|
-
@with_retries
|
|
645
614
|
async def _get_wallet_safe(request: Request) -> t.List[t.Dict]:
|
|
646
615
|
"""Get wallets."""
|
|
647
616
|
wallets = []
|
|
@@ -650,7 +619,6 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
650
619
|
return JSONResponse(content=wallets)
|
|
651
620
|
|
|
652
621
|
@app.get("/api/wallet/safe")
|
|
653
|
-
@with_retries
|
|
654
622
|
async def _get_safes(request: Request) -> t.List[t.Dict]:
|
|
655
623
|
"""Create wallet safe"""
|
|
656
624
|
all_safes = []
|
|
@@ -662,7 +630,6 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
662
630
|
return JSONResponse(content=all_safes)
|
|
663
631
|
|
|
664
632
|
@app.get("/api/wallet/safe/{chain}")
|
|
665
|
-
@with_retries
|
|
666
633
|
async def _get_safe(request: Request) -> t.List[t.Dict]:
|
|
667
634
|
"""Get safe address"""
|
|
668
635
|
chain = Chain.from_string(request.path_params["chain"])
|
|
@@ -792,7 +759,6 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
792
759
|
)
|
|
793
760
|
|
|
794
761
|
@app.put("/api/wallet/safe")
|
|
795
|
-
@with_retries
|
|
796
762
|
async def _update_safe(request: Request) -> t.List[t.Dict]:
|
|
797
763
|
"""Update wallet safe"""
|
|
798
764
|
# TODO: Extract login check as decorator
|
|
@@ -845,13 +811,11 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
845
811
|
)
|
|
846
812
|
|
|
847
813
|
@app.get("/api/v2/services")
|
|
848
|
-
@with_retries
|
|
849
814
|
async def _get_services(request: Request) -> JSONResponse:
|
|
850
815
|
"""Get all services."""
|
|
851
816
|
return JSONResponse(content=operate.service_manager().json)
|
|
852
817
|
|
|
853
818
|
@app.get("/api/v2/services/validate")
|
|
854
|
-
@with_retries
|
|
855
819
|
async def _validate_services(request: Request) -> JSONResponse:
|
|
856
820
|
"""Validate all services."""
|
|
857
821
|
service_manager = operate.service_manager()
|
|
@@ -866,7 +830,6 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
866
830
|
)
|
|
867
831
|
|
|
868
832
|
@app.get("/api/v2/services/deployment")
|
|
869
|
-
@with_retries
|
|
870
833
|
async def _get_services_deployment(request: Request) -> JSONResponse:
|
|
871
834
|
"""Get a service deployment."""
|
|
872
835
|
service_manager = operate.service_manager()
|
|
@@ -879,7 +842,6 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
879
842
|
return JSONResponse(content=output)
|
|
880
843
|
|
|
881
844
|
@app.get("/api/v2/service/{service_config_id}")
|
|
882
|
-
@with_retries
|
|
883
845
|
async def _get_service(request: Request) -> JSONResponse:
|
|
884
846
|
"""Get a service."""
|
|
885
847
|
service_config_id = request.path_params["service_config_id"]
|
|
@@ -897,7 +859,6 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
897
859
|
)
|
|
898
860
|
|
|
899
861
|
@app.get("/api/v2/service/{service_config_id}/deployment")
|
|
900
|
-
@with_retries
|
|
901
862
|
async def _get_service_deployment(request: Request) -> JSONResponse:
|
|
902
863
|
"""Get a service deployment."""
|
|
903
864
|
service_config_id = request.path_params["service_config_id"]
|
|
@@ -911,7 +872,6 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
911
872
|
return JSONResponse(content=deployment_json)
|
|
912
873
|
|
|
913
874
|
@app.get("/api/v2/service/{service_config_id}/agent_performance")
|
|
914
|
-
@with_retries
|
|
915
875
|
async def _get_agent_performance(request: Request) -> JSONResponse:
|
|
916
876
|
"""Get the service refill requirements."""
|
|
917
877
|
service_config_id = request.path_params["service_config_id"]
|
|
@@ -926,7 +886,6 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
926
886
|
)
|
|
927
887
|
|
|
928
888
|
@app.get("/api/v2/service/{service_config_id}/refill_requirements")
|
|
929
|
-
@with_retries
|
|
930
889
|
async def _get_refill_requirements(request: Request) -> JSONResponse:
|
|
931
890
|
"""Get the service refill requirements."""
|
|
932
891
|
service_config_id = request.path_params["service_config_id"]
|
|
@@ -941,7 +900,6 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
941
900
|
)
|
|
942
901
|
|
|
943
902
|
@app.post("/api/v2/service")
|
|
944
|
-
@with_retries
|
|
945
903
|
async def _create_services_v2(request: Request) -> JSONResponse:
|
|
946
904
|
"""Create a service."""
|
|
947
905
|
if operate.password is None:
|
|
@@ -953,7 +911,6 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
953
911
|
return JSONResponse(content=output.json)
|
|
954
912
|
|
|
955
913
|
@app.post("/api/v2/service/{service_config_id}")
|
|
956
|
-
@with_retries
|
|
957
914
|
async def _deploy_and_run_service(request: Request) -> JSONResponse:
|
|
958
915
|
"""Deploy a service."""
|
|
959
916
|
if operate.password is None:
|
|
@@ -986,7 +943,6 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
986
943
|
|
|
987
944
|
@app.put("/api/v2/service/{service_config_id}")
|
|
988
945
|
@app.patch("/api/v2/service/{service_config_id}")
|
|
989
|
-
@with_retries
|
|
990
946
|
async def _update_service(request: Request) -> JSONResponse:
|
|
991
947
|
"""Update a service."""
|
|
992
948
|
if operate.password is None:
|
|
@@ -1022,7 +978,6 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
1022
978
|
return JSONResponse(content=output.json)
|
|
1023
979
|
|
|
1024
980
|
@app.post("/api/v2/service/{service_config_id}/deployment/stop")
|
|
1025
|
-
@with_retries
|
|
1026
981
|
async def _stop_service_locally(request: Request) -> JSONResponse:
|
|
1027
982
|
"""Stop a service deployment."""
|
|
1028
983
|
|
|
@@ -1045,7 +1000,6 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
1045
1000
|
return JSONResponse(content=deployment.json)
|
|
1046
1001
|
|
|
1047
1002
|
@app.post("/api/v2/service/{service_config_id}/onchain/withdraw")
|
|
1048
|
-
@with_retries
|
|
1049
1003
|
async def _withdraw_onchain(request: Request) -> JSONResponse:
|
|
1050
1004
|
"""Withdraw all the funds from a service."""
|
|
1051
1005
|
|
|
@@ -1114,7 +1068,6 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
1114
1068
|
return JSONResponse(content={"error": None, "message": "Withdrawal successful"})
|
|
1115
1069
|
|
|
1116
1070
|
@app.post("/api/bridge/bridge_refill_requirements")
|
|
1117
|
-
@with_retries
|
|
1118
1071
|
async def _bridge_refill_requirements(request: Request) -> JSONResponse:
|
|
1119
1072
|
"""Get the bridge refill requirements."""
|
|
1120
1073
|
if operate.password is None:
|
|
@@ -1149,7 +1102,6 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
1149
1102
|
)
|
|
1150
1103
|
|
|
1151
1104
|
@app.post("/api/bridge/execute")
|
|
1152
|
-
@with_retries
|
|
1153
1105
|
async def _bridge_execute(request: Request) -> JSONResponse:
|
|
1154
1106
|
"""Execute bridge transaction."""
|
|
1155
1107
|
if operate.password is None:
|
|
@@ -1179,14 +1131,12 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
1179
1131
|
)
|
|
1180
1132
|
|
|
1181
1133
|
@app.get("/api/bridge/last_executed_bundle_id")
|
|
1182
|
-
@with_retries
|
|
1183
1134
|
async def _bridge_last_executed_bundle_id(request: Request) -> t.List[t.Dict]:
|
|
1184
1135
|
"""Get last executed bundle id."""
|
|
1185
1136
|
content = {"id": operate.bridge_manager.last_executed_bundle_id()}
|
|
1186
1137
|
return JSONResponse(content=content, status_code=HTTPStatus.OK)
|
|
1187
1138
|
|
|
1188
1139
|
@app.get("/api/bridge/status/{id}")
|
|
1189
|
-
@with_retries
|
|
1190
1140
|
async def _bridge_status(request: Request) -> JSONResponse:
|
|
1191
1141
|
"""Get bridge transaction status."""
|
|
1192
1142
|
|
|
@@ -1215,7 +1165,6 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
1215
1165
|
)
|
|
1216
1166
|
|
|
1217
1167
|
@app.post("/api/wallet/recovery/initiate")
|
|
1218
|
-
@with_retries
|
|
1219
1168
|
async def _wallet_recovery_initiate(request: Request) -> JSONResponse:
|
|
1220
1169
|
"""Initiate wallet recovery."""
|
|
1221
1170
|
if operate.user_account is None:
|
|
@@ -1259,7 +1208,6 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
|
|
|
1259
1208
|
)
|
|
1260
1209
|
|
|
1261
1210
|
@app.post("/api/wallet/recovery/complete")
|
|
1262
|
-
@with_retries
|
|
1263
1211
|
async def _wallet_recovery_complete(request: Request) -> JSONResponse:
|
|
1264
1212
|
"""Complete wallet recovery."""
|
|
1265
1213
|
if operate.user_account is None:
|
|
@@ -42,8 +42,8 @@ AGENT_LOG_ENV_VAR = "LOG_DIR"
|
|
|
42
42
|
ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"
|
|
43
43
|
|
|
44
44
|
ON_CHAIN_INTERACT_TIMEOUT = 120.0
|
|
45
|
-
ON_CHAIN_INTERACT_RETRIES =
|
|
46
|
-
ON_CHAIN_INTERACT_SLEEP =
|
|
45
|
+
ON_CHAIN_INTERACT_RETRIES = 12
|
|
46
|
+
ON_CHAIN_INTERACT_SLEEP = 5.0
|
|
47
47
|
MIN_PASSWORD_LENGTH = 8
|
|
48
48
|
|
|
49
49
|
HEALTH_CHECK_URL = "http://127.0.0.1:8716/healthcheck" # possible DNS issues on windows so use IP address
|
|
@@ -76,6 +76,19 @@ class KeysManager(metaclass=SingletonMeta):
|
|
|
76
76
|
)
|
|
77
77
|
)
|
|
78
78
|
|
|
79
|
+
def get_private_key_file(self, address: str) -> Path:
|
|
80
|
+
"""Get the path to the private key file for the given address."""
|
|
81
|
+
path = self.path / f"{address}_private_key"
|
|
82
|
+
|
|
83
|
+
if path.is_file():
|
|
84
|
+
return path
|
|
85
|
+
|
|
86
|
+
key = self.get(address)
|
|
87
|
+
private_key = key.private_key
|
|
88
|
+
path.write_text(private_key, encoding="utf-8")
|
|
89
|
+
os.chmod(path, 0o600)
|
|
90
|
+
return path
|
|
91
|
+
|
|
79
92
|
def get_crypto_instance(self, address: str) -> EthereumCrypto:
|
|
80
93
|
"""Get EthereumCrypto instance for the given address."""
|
|
81
94
|
key: Key = Key.from_json( # type: ignore
|
{olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/ledger/__init__.py
RENAMED
|
@@ -20,6 +20,10 @@
|
|
|
20
20
|
"""Ledger helpers."""
|
|
21
21
|
|
|
22
22
|
import os
|
|
23
|
+
import typing as t
|
|
24
|
+
from math import ceil
|
|
25
|
+
|
|
26
|
+
from aea.crypto.base import LedgerApi
|
|
23
27
|
|
|
24
28
|
from operate.operate_types import Chain
|
|
25
29
|
|
|
@@ -99,3 +103,54 @@ def get_currency_denom(chain: Chain) -> str:
|
|
|
99
103
|
def get_currency_smallest_unit(chain: Chain) -> str:
|
|
100
104
|
"""Get currency denom by chain type."""
|
|
101
105
|
return CURRENCY_SMALLEST_UNITS.get(chain, "Wei")
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
GAS_ESTIMATE_FALLBACK_ADDRESSES = [
|
|
109
|
+
"0x000000000000000000000000000000000000dEaD",
|
|
110
|
+
"0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", # nosec
|
|
111
|
+
]
|
|
112
|
+
GAS_ESTIMATE_BUFFER = 1.10
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
# TODO backport to open aea/autonomy
|
|
116
|
+
# TODO This gas pricing management should be done at a lower level in the library
|
|
117
|
+
def update_tx_with_gas_pricing(tx: t.Dict, ledger_api: LedgerApi) -> None:
|
|
118
|
+
"""Update transaction with gas pricing."""
|
|
119
|
+
tx.pop("maxFeePerGas", None)
|
|
120
|
+
tx.pop("gasPrice", None)
|
|
121
|
+
tx.pop("maxPriorityFeePerGas", None)
|
|
122
|
+
|
|
123
|
+
gas_pricing = ledger_api.try_get_gas_pricing()
|
|
124
|
+
if gas_pricing is None:
|
|
125
|
+
raise RuntimeError("Unable to retrieve gas pricing.")
|
|
126
|
+
|
|
127
|
+
if "maxFeePerGas" in gas_pricing and "maxPriorityFeePerGas" in gas_pricing:
|
|
128
|
+
tx["maxFeePerGas"] = gas_pricing["maxFeePerGas"]
|
|
129
|
+
tx["maxPriorityFeePerGas"] = gas_pricing["maxPriorityFeePerGas"]
|
|
130
|
+
elif "gasPrice" in gas_pricing:
|
|
131
|
+
tx["gasPrice"] = gas_pricing["gasPrice"]
|
|
132
|
+
else:
|
|
133
|
+
raise RuntimeError("Retrieved invalid gas pricing.")
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
# TODO backport to open aea/autonomy
|
|
137
|
+
# TODO This gas management should be done at a lower level in the library
|
|
138
|
+
def update_tx_with_gas_estimate(tx: t.Dict, ledger_api: LedgerApi) -> None:
|
|
139
|
+
"""Update transaction with gas estimate."""
|
|
140
|
+
print(f"[PROVIDER] Trying to update transaction gas {tx['from']=} {tx['gas']=}.")
|
|
141
|
+
original_from = tx["from"]
|
|
142
|
+
original_gas = tx.get("gas", 1)
|
|
143
|
+
|
|
144
|
+
for address in [original_from] + GAS_ESTIMATE_FALLBACK_ADDRESSES:
|
|
145
|
+
tx["from"] = address
|
|
146
|
+
tx["gas"] = 1
|
|
147
|
+
ledger_api.update_with_gas_estimate(tx)
|
|
148
|
+
if tx["gas"] > 1:
|
|
149
|
+
print(f"[PROVIDER] Gas estimated successfully {tx['from']=} {tx['gas']=}.")
|
|
150
|
+
break
|
|
151
|
+
|
|
152
|
+
tx["from"] = original_from
|
|
153
|
+
if tx["gas"] == 1:
|
|
154
|
+
tx["gas"] = original_gas
|
|
155
|
+
print(f"[PROVIDER] Unable to estimate gas. Restored {tx['gas']=}.")
|
|
156
|
+
tx["gas"] = ceil(tx["gas"] * GAS_ESTIMATE_BUFFER)
|
|
@@ -34,12 +34,7 @@ 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
|
|
38
|
-
IPFS_ADDRESS,
|
|
39
|
-
NO_STAKING_PROGRAM_ID,
|
|
40
|
-
OPERATE_HOME,
|
|
41
|
-
USER_JSON,
|
|
42
|
-
)
|
|
37
|
+
from operate.constants import IPFS_ADDRESS, NO_STAKING_PROGRAM_ID, USER_JSON
|
|
43
38
|
from operate.data import DATA_DIR
|
|
44
39
|
from operate.data.contracts.staking_token.contract import StakingTokenContract
|
|
45
40
|
from operate.ledger.profiles import STAKING, get_staking_contract
|
|
@@ -145,7 +140,8 @@ def ask_confirm_password() -> str:
|
|
|
145
140
|
|
|
146
141
|
def load_local_config(operate: "OperateApp", service_name: str) -> QuickstartConfig:
|
|
147
142
|
"""Load the local quickstart configuration."""
|
|
148
|
-
|
|
143
|
+
operate_home = operate._path
|
|
144
|
+
old_path = operate_home / "local_config.json"
|
|
149
145
|
if old_path.exists(): # Migrate to new naming scheme
|
|
150
146
|
config = t.cast(QuickstartConfig, QuickstartConfig.load(old_path))
|
|
151
147
|
service_manager = operate.service_manager()
|
|
@@ -178,13 +174,13 @@ def load_local_config(operate: "OperateApp", service_name: str) -> QuickstartCon
|
|
|
178
174
|
shutil.move(old_path, config.path)
|
|
179
175
|
break
|
|
180
176
|
|
|
181
|
-
for qs_config in
|
|
177
|
+
for qs_config in operate_home.glob("*-quickstart-config.json"):
|
|
182
178
|
if f"{service_name}-quickstart-config.json" == qs_config.name:
|
|
183
179
|
config = t.cast(QuickstartConfig, QuickstartConfig.load(qs_config))
|
|
184
180
|
break
|
|
185
181
|
else:
|
|
186
182
|
config = QuickstartConfig(
|
|
187
|
-
|
|
183
|
+
operate_home / f"{service_name}-quickstart-config.json"
|
|
188
184
|
)
|
|
189
185
|
|
|
190
186
|
return config
|
{olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/services/agent_runner.py
RENAMED
|
@@ -65,10 +65,10 @@ class AgentRelease:
|
|
|
65
65
|
# list of agents releases supported
|
|
66
66
|
AGENTS_SUPPORTED = {
|
|
67
67
|
"valory/trader": AgentRelease(
|
|
68
|
-
owner="valory-xyz", repo="trader", release="v0.
|
|
68
|
+
owner="valory-xyz", repo="trader", release="v0.27.2-rc.1"
|
|
69
69
|
),
|
|
70
70
|
"valory/optimus": AgentRelease(
|
|
71
|
-
owner="valory-xyz", repo="optimus", release="v0.0.
|
|
71
|
+
owner="valory-xyz", repo="optimus", release="v0.0.1051"
|
|
72
72
|
),
|
|
73
73
|
"dvilela/memeooorr": AgentRelease(
|
|
74
74
|
owner="valory-xyz", repo="meme-ooorr", release="v0.0.101"
|
|
@@ -36,10 +36,10 @@ from operate.services.manage import ServiceManager # type: ignore
|
|
|
36
36
|
class HealthChecker:
|
|
37
37
|
"""Health checker manager."""
|
|
38
38
|
|
|
39
|
-
SLEEP_PERIOD_DEFAULT =
|
|
39
|
+
SLEEP_PERIOD_DEFAULT = 5 # seconds
|
|
40
40
|
PORT_UP_TIMEOUT_DEFAULT = 300 # seconds
|
|
41
|
-
REQUEST_TIMEOUT_DEFAULT = 90
|
|
42
|
-
NUMBER_OF_FAILS_DEFAULT =
|
|
41
|
+
REQUEST_TIMEOUT_DEFAULT = 90 # seconds
|
|
42
|
+
NUMBER_OF_FAILS_DEFAULT = 60
|
|
43
43
|
|
|
44
44
|
def __init__(
|
|
45
45
|
self,
|
|
@@ -180,7 +180,7 @@ class HealthChecker:
|
|
|
180
180
|
f"[HEALTH_CHECKER] {service_config_id} not healthy for {fails} time in a row"
|
|
181
181
|
)
|
|
182
182
|
else:
|
|
183
|
-
self.logger.
|
|
183
|
+
self.logger.debug(
|
|
184
184
|
f"[HEALTH_CHECKER] {service_config_id} is HEALTHY"
|
|
185
185
|
)
|
|
186
186
|
# reset fails if comes healty
|
{olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/services/manage.py
RENAMED
|
@@ -415,18 +415,26 @@ class ServiceManager:
|
|
|
415
415
|
and (
|
|
416
416
|
on_chain_hash != service.hash
|
|
417
417
|
or current_agent_id != staking_params["agent_ids"][0]
|
|
418
|
-
or
|
|
418
|
+
or (
|
|
419
|
+
user_params.use_staking
|
|
420
|
+
and current_agent_bond != staking_params["min_staking_deposit"]
|
|
421
|
+
)
|
|
422
|
+
# TODO Missing complete this check for non-staked services it should compare the current_agent_bond from the protocol, now it's only read for the staking contract.
|
|
419
423
|
or on_chain_description != service.description
|
|
420
424
|
)
|
|
421
425
|
)
|
|
422
426
|
current_staking_program = self._get_current_staking_program(service, chain)
|
|
423
427
|
|
|
428
|
+
self.logger.info(f"{chain_data.token=}")
|
|
429
|
+
self.logger.info(f"{user_params.use_staking=}")
|
|
424
430
|
self.logger.info(f"{current_staking_program=}")
|
|
425
431
|
self.logger.info(f"{user_params.staking_program_id=}")
|
|
426
432
|
self.logger.info(f"{on_chain_hash=}")
|
|
427
433
|
self.logger.info(f"{service.hash=}")
|
|
428
434
|
self.logger.info(f"{current_agent_id=}")
|
|
429
|
-
self.logger.info(f"{staking_params['agent_ids']
|
|
435
|
+
self.logger.info(f"{staking_params['agent_ids']=}")
|
|
436
|
+
self.logger.info(f"{current_agent_bond=}")
|
|
437
|
+
self.logger.info(f"{staking_params['min_staking_deposit']=}")
|
|
430
438
|
self.logger.info(f"{is_first_mint=}")
|
|
431
439
|
self.logger.info(f"{is_update=}")
|
|
432
440
|
|
|
@@ -815,7 +823,12 @@ class ServiceManager:
|
|
|
815
823
|
# on_chain_hash != service.hash or # noqa
|
|
816
824
|
current_agent_id != target_staking_params["agent_ids"][0]
|
|
817
825
|
# TODO This has to be removed for Optimus (needs to be properly implemented). Needs to be put back for Trader!
|
|
818
|
-
or
|
|
826
|
+
or (
|
|
827
|
+
user_params.use_staking
|
|
828
|
+
and current_agent_bond
|
|
829
|
+
!= target_staking_params["min_staking_deposit"]
|
|
830
|
+
)
|
|
831
|
+
# TODO Missing complete this check for non-staked services it should compare the current_agent_bond from the protocol, now it's only read for the staking contract.
|
|
819
832
|
or current_staking_params["staking_token"]
|
|
820
833
|
!= target_staking_params["staking_token"]
|
|
821
834
|
or on_chain_description != service.description
|
|
@@ -823,12 +836,13 @@ class ServiceManager:
|
|
|
823
836
|
)
|
|
824
837
|
|
|
825
838
|
self.logger.info(f"{chain_data.token=}")
|
|
839
|
+
self.logger.info(f"{user_params.use_staking=}")
|
|
826
840
|
self.logger.info(f"{current_staking_program=}")
|
|
827
841
|
self.logger.info(f"{user_params.staking_program_id=}")
|
|
828
842
|
self.logger.info(f"{on_chain_hash=}")
|
|
829
843
|
self.logger.info(f"{service.hash=}")
|
|
830
844
|
self.logger.info(f"{current_agent_id=}")
|
|
831
|
-
self.logger.info(f"{target_staking_params['agent_ids']
|
|
845
|
+
self.logger.info(f"{target_staking_params['agent_ids']=}")
|
|
832
846
|
self.logger.info(f"{current_agent_bond=}")
|
|
833
847
|
self.logger.info(f"{target_staking_params['min_staking_deposit']=}")
|
|
834
848
|
self.logger.info(f"{is_first_mint=}")
|
{olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/utils/__init__.py
RENAMED
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
|
|
20
20
|
"""Helper utilities."""
|
|
21
21
|
|
|
22
|
-
import functools
|
|
23
22
|
import shutil
|
|
24
23
|
import time
|
|
25
24
|
import typing as t
|
|
@@ -32,34 +31,6 @@ class SingletonMeta(type):
|
|
|
32
31
|
|
|
33
32
|
_instances: t.Dict[t.Type, t.Any] = {}
|
|
34
33
|
_lock: Lock = Lock()
|
|
35
|
-
_class_locks: t.Dict[t.Type, Lock] = {}
|
|
36
|
-
|
|
37
|
-
def __new__(
|
|
38
|
-
cls, name: str, bases: t.Tuple[type, ...], dct: t.Dict[str, t.Any]
|
|
39
|
-
) -> t.Type:
|
|
40
|
-
"""Create a new class with thread-safe methods."""
|
|
41
|
-
# Wrap all callable methods (except special methods) with thread safety
|
|
42
|
-
for key, value in list(dct.items()):
|
|
43
|
-
if callable(value) and not key.startswith("__"):
|
|
44
|
-
dct[key] = cls._make_thread_safe(value)
|
|
45
|
-
|
|
46
|
-
new_class = super().__new__(cls, name, bases, dct)
|
|
47
|
-
cls._class_locks[new_class] = Lock()
|
|
48
|
-
return new_class
|
|
49
|
-
|
|
50
|
-
@staticmethod
|
|
51
|
-
def _make_thread_safe(func: t.Callable) -> t.Callable:
|
|
52
|
-
"""Wrap a function to make it thread-safe."""
|
|
53
|
-
|
|
54
|
-
@functools.wraps(func)
|
|
55
|
-
def wrapper(self: t.Any, *args: t.Any, **kwargs: t.Any) -> t.Any:
|
|
56
|
-
class_lock = SingletonMeta._class_locks.get(type(self))
|
|
57
|
-
if class_lock:
|
|
58
|
-
with class_lock:
|
|
59
|
-
return func(self, *args, **kwargs)
|
|
60
|
-
return func(self, *args, **kwargs)
|
|
61
|
-
|
|
62
|
-
return wrapper
|
|
63
34
|
|
|
64
35
|
def __call__(cls, *args: t.Any, **kwargs: t.Any) -> t.Any:
|
|
65
36
|
"""Override the __call__ method to control instance creation."""
|
{olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/wallet/master.py
RENAMED
|
@@ -42,7 +42,11 @@ from operate.constants import (
|
|
|
42
42
|
ON_CHAIN_INTERACT_TIMEOUT,
|
|
43
43
|
ZERO_ADDRESS,
|
|
44
44
|
)
|
|
45
|
-
from operate.ledger import
|
|
45
|
+
from operate.ledger import (
|
|
46
|
+
get_default_rpc,
|
|
47
|
+
update_tx_with_gas_estimate,
|
|
48
|
+
update_tx_with_gas_pricing,
|
|
49
|
+
)
|
|
46
50
|
from operate.ledger.profiles import ERC20_TOKENS, OLAS, USDC
|
|
47
51
|
from operate.operate_types import Chain, LedgerType
|
|
48
52
|
from operate.resource import LocalResource
|
|
@@ -357,10 +361,9 @@ class EthereumMasterWallet(MasterWallet):
|
|
|
357
361
|
"nonce": ledger_api.api.eth.get_transaction_count(wallet_address),
|
|
358
362
|
}
|
|
359
363
|
)
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
)
|
|
364
|
+
update_tx_with_gas_pricing(tx, ledger_api)
|
|
365
|
+
update_tx_with_gas_estimate(tx, ledger_api)
|
|
366
|
+
return tx
|
|
364
367
|
|
|
365
368
|
setattr(tx_settler, "build", _build_transfer_tx) # noqa: B010
|
|
366
369
|
tx_receipt = tx_settler.transact(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/account/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/bridge/bridge_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
{olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/data/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/ledger/profiles.py
RENAMED
|
File without changes
|
|
File without changes
|
{olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/operate_http/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/operate_types.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/quickstart/utils.py
RENAMED
|
File without changes
|
|
File without changes
|
{olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/services/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/services/protocol.py
RENAMED
|
File without changes
|
{olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/services/service.py
RENAMED
|
File without changes
|
|
File without changes
|
{olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/services/utils/mech.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{olas_operate_middleware-0.10.18 → olas_operate_middleware-0.10.20}/operate/wallet/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|