olas-operate-middleware 0.13.11__tar.gz → 0.14.1__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.

Potentially problematic release.


This version of olas-operate-middleware might be problematic. Click here for more details.

Files changed (101) hide show
  1. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/PKG-INFO +1 -1
  2. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/bridge/bridge_manager.py +3 -3
  3. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/bridge/providers/provider.py +9 -8
  4. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/bridge/providers/relay_provider.py +9 -0
  5. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/constants.py +4 -2
  6. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/ledger/profiles.py +17 -16
  7. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/operate_types.py +34 -12
  8. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/quickstart/run_service.py +9 -4
  9. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/resource.py +1 -60
  10. olas_operate_middleware-0.14.1/operate/serialization.py +113 -0
  11. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/services/funding_manager.py +24 -22
  12. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/services/service.py +30 -4
  13. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/settings.py +6 -3
  14. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/utils/__init__.py +2 -1
  15. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/utils/gnosis.py +7 -6
  16. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/wallet/master.py +7 -6
  17. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/wallet/wallet_recovery_manager.py +5 -4
  18. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/pyproject.toml +1 -1
  19. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/LICENSE +0 -0
  20. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/README.md +0 -0
  21. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/__init__.py +0 -0
  22. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/account/__init__.py +0 -0
  23. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/account/user.py +0 -0
  24. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/bridge/providers/lifi_provider.py +0 -0
  25. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/bridge/providers/native_bridge_provider.py +0 -0
  26. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/cli.py +0 -0
  27. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/README.md +0 -0
  28. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/__init__.py +0 -0
  29. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/__init__.py +0 -0
  30. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/dual_staking_token/__init__.py +0 -0
  31. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/dual_staking_token/build/DualStakingToken.json +0 -0
  32. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/dual_staking_token/contract.py +0 -0
  33. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/dual_staking_token/contract.yaml +0 -0
  34. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/foreign_omnibridge/__init__.py +0 -0
  35. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/foreign_omnibridge/build/ForeignOmnibridge.json +0 -0
  36. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/foreign_omnibridge/contract.py +0 -0
  37. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/foreign_omnibridge/contract.yaml +0 -0
  38. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/home_omnibridge/__init__.py +0 -0
  39. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/home_omnibridge/build/HomeOmnibridge.json +0 -0
  40. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/home_omnibridge/contract.py +0 -0
  41. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/home_omnibridge/contract.yaml +0 -0
  42. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/l1_standard_bridge/__init__.py +0 -0
  43. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/l1_standard_bridge/build/L1StandardBridge.json +0 -0
  44. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/l1_standard_bridge/contract.py +0 -0
  45. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/l1_standard_bridge/contract.yaml +0 -0
  46. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/l2_standard_bridge/__init__.py +0 -0
  47. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/l2_standard_bridge/build/L2StandardBridge.json +0 -0
  48. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/l2_standard_bridge/contract.py +0 -0
  49. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/l2_standard_bridge/contract.yaml +0 -0
  50. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/mech_activity/__init__.py +0 -0
  51. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/mech_activity/build/MechActivity.json +0 -0
  52. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/mech_activity/contract.py +0 -0
  53. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/mech_activity/contract.yaml +0 -0
  54. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/optimism_mintable_erc20/__init__.py +0 -0
  55. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/optimism_mintable_erc20/build/OptimismMintableERC20.json +0 -0
  56. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/optimism_mintable_erc20/contract.py +0 -0
  57. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/optimism_mintable_erc20/contract.yaml +0 -0
  58. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/recovery_module/__init__.py +0 -0
  59. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/recovery_module/build/RecoveryModule.json +0 -0
  60. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/recovery_module/contract.py +0 -0
  61. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/recovery_module/contract.yaml +0 -0
  62. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/requester_activity_checker/__init__.py +0 -0
  63. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/requester_activity_checker/build/RequesterActivityChecker.json +0 -0
  64. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/requester_activity_checker/contract.py +0 -0
  65. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/requester_activity_checker/contract.yaml +0 -0
  66. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/staking_token/__init__.py +0 -0
  67. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/staking_token/build/StakingToken.json +0 -0
  68. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/staking_token/contract.py +0 -0
  69. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/staking_token/contract.yaml +0 -0
  70. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/uniswap_v2_erc20/__init__.py +0 -0
  71. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/uniswap_v2_erc20/build/IUniswapV2ERC20.json +0 -0
  72. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/uniswap_v2_erc20/contract.py +0 -0
  73. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/uniswap_v2_erc20/contract.yaml +0 -0
  74. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/uniswap_v2_erc20/tests/__init__.py +0 -0
  75. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/data/contracts/uniswap_v2_erc20/tests/test_contract.py +0 -0
  76. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/keys.py +0 -0
  77. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/ledger/__init__.py +0 -0
  78. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/migration.py +0 -0
  79. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/operate_http/__init__.py +0 -0
  80. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/operate_http/exceptions.py +0 -0
  81. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/pearl.py +0 -0
  82. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/quickstart/analyse_logs.py +0 -0
  83. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/quickstart/claim_staking_rewards.py +0 -0
  84. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/quickstart/reset_configs.py +0 -0
  85. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/quickstart/reset_password.py +0 -0
  86. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/quickstart/reset_staking.py +0 -0
  87. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/quickstart/stop_service.py +0 -0
  88. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/quickstart/terminate_on_chain_service.py +0 -0
  89. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/quickstart/utils.py +0 -0
  90. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/services/__init__.py +0 -0
  91. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/services/agent_runner.py +0 -0
  92. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/services/deployment_runner.py +0 -0
  93. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/services/health_checker.py +0 -0
  94. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/services/manage.py +0 -0
  95. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/services/protocol.py +0 -0
  96. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/services/utils/__init__.py +0 -0
  97. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/services/utils/mech.py +0 -0
  98. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/services/utils/tendermint.py +0 -0
  99. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/utils/single_instance.py +0 -0
  100. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/utils/ssl.py +0 -0
  101. {olas_operate_middleware-0.13.11 → olas_operate_middleware-0.14.1}/operate/wallet/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: olas-operate-middleware
3
- Version: 0.13.11
3
+ Version: 0.14.1
4
4
  Summary:
5
5
  License-File: LICENSE
6
6
  Author: David Vilela
@@ -369,9 +369,9 @@ class BridgeManager:
369
369
  status_json = self.get_status_json(bundle.id)
370
370
  status_json.update(
371
371
  {
372
- "balances": balances,
373
- "bridge_refill_requirements": bridge_refill_requirements,
374
- "bridge_total_requirements": bridge_total_requirements,
372
+ "balances": balances.json,
373
+ "bridge_refill_requirements": bridge_refill_requirements.json,
374
+ "bridge_total_requirements": bridge_total_requirements.json,
375
375
  "expiration_timestamp": bundle.timestamp + self.bundle_validity_period,
376
376
  "is_refill_required": is_refill_required,
377
377
  }
@@ -44,6 +44,7 @@ from operate.constants import (
44
44
  from operate.ledger import get_default_ledger_api, update_tx_with_gas_pricing
45
45
  from operate.operate_types import Chain, ChainAmounts
46
46
  from operate.resource import LocalResource
47
+ from operate.serialization import BigInt
47
48
  from operate.wallet.master import MasterWalletManager
48
49
 
49
50
 
@@ -256,16 +257,16 @@ class Provider(ABC):
256
257
  {
257
258
  from_chain: {
258
259
  from_address: {
259
- ZERO_ADDRESS: 0,
260
- from_token: 0,
260
+ ZERO_ADDRESS: BigInt(0),
261
+ from_token: BigInt(0),
261
262
  }
262
263
  }
263
264
  }
264
265
  )
265
266
 
266
- total_native = 0
267
- total_gas_fees = 0
268
- total_token = 0
267
+ total_native = BigInt(0)
268
+ total_gas_fees = BigInt(0)
269
+ total_token = BigInt(0)
269
270
 
270
271
  for tx_label, tx in txs:
271
272
  self.logger.debug(
@@ -273,8 +274,8 @@ class Provider(ABC):
273
274
  )
274
275
  update_tx_with_gas_pricing(tx, from_ledger_api)
275
276
  gas_key = "gasPrice" if "gasPrice" in tx else "maxFeePerGas"
276
- gas_fees = tx.get(gas_key, 0) * tx["gas"]
277
- tx_value = int(tx.get("value", 0))
277
+ gas_fees = BigInt(tx.get(gas_key, 0) * tx["gas"])
278
+ tx_value = BigInt(int(tx.get("value", 0)))
278
279
  total_gas_fees += gas_fees
279
280
  total_native += tx_value + gas_fees
280
281
 
@@ -290,7 +291,7 @@ class Provider(ABC):
290
291
  "data", ""
291
292
  ).startswith(ERC20_APPROVE_SELECTOR):
292
293
  try:
293
- amount = int(tx["data"][-64:], 16)
294
+ amount = BigInt(tx["data"][-64:], 16)
294
295
  total_token += amount
295
296
  except Exception as e:
296
297
  raise RuntimeError("Malformed ERC20 approve transaction.") from e
@@ -101,6 +101,15 @@ RELAY_DEFAULT_GAS = {
101
101
  "swap": 400_000,
102
102
  "send": 1,
103
103
  },
104
+ Chain.ARBITRUM_ONE: {
105
+ "deposit": 50_000,
106
+ "approve": 200_000,
107
+ "authorize": 1,
108
+ "authorize1": 1,
109
+ "authorize2": 1,
110
+ "swap": 400_000,
111
+ "send": 1,
112
+ },
104
113
  }
105
114
 
106
115
 
@@ -21,6 +21,8 @@
21
21
 
22
22
  from pathlib import Path
23
23
 
24
+ from operate.serialization import BigInt
25
+
24
26
 
25
27
  OPERATE = ".operate"
26
28
  OPERATE_HOME = Path.cwd() / OPERATE
@@ -54,8 +56,8 @@ AGENT_RUNNER_PREFIX = "agent_runner"
54
56
  ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"
55
57
 
56
58
  DEFAULT_TIMEOUT = 30
57
- MIN_AGENT_BOND = 1
58
- MIN_SECURITY_DEPOSIT = 1
59
+ MIN_AGENT_BOND = BigInt(1)
60
+ MIN_SECURITY_DEPOSIT = BigInt(1)
59
61
 
60
62
  ON_CHAIN_INTERACT_TIMEOUT = 120.0
61
63
  ON_CHAIN_INTERACT_RETRIES = 12
@@ -33,6 +33,7 @@ from operate.ledger import (
33
33
  get_default_ledger_api,
34
34
  )
35
35
  from operate.operate_types import Chain, ContractAddresses
36
+ from operate.serialization import BigInt
36
37
 
37
38
 
38
39
  # TODO: Refactor, remove the usage of CONTRACTS and use CHAIN_PROFILES from Open Autonomy instead.
@@ -234,14 +235,14 @@ DEFAULT_NEW_SAFE_FUNDS: t.Dict[Chain, t.Dict[str, int]] = {
234
235
  }
235
236
 
236
237
  DEFAULT_EOA_TOPUPS = {
237
- Chain.ARBITRUM_ONE: {ZERO_ADDRESS: 2_500_000_000_000_000},
238
- Chain.BASE: {ZERO_ADDRESS: 2_500_000_000_000_000},
239
- Chain.CELO: {ZERO_ADDRESS: 750_000_000_000_000_000},
240
- Chain.ETHEREUM: {ZERO_ADDRESS: 10_000_000_000_000_000},
241
- Chain.GNOSIS: {ZERO_ADDRESS: 750_000_000_000_000_000},
242
- Chain.MODE: {ZERO_ADDRESS: 250_000_000_000_000},
243
- Chain.OPTIMISM: {ZERO_ADDRESS: 2_500_000_000_000_000},
244
- Chain.POLYGON: {ZERO_ADDRESS: 750_000_000_000_000_000},
238
+ Chain.ARBITRUM_ONE: {ZERO_ADDRESS: BigInt(2_500_000_000_000_000)},
239
+ Chain.BASE: {ZERO_ADDRESS: BigInt(2_500_000_000_000_000)},
240
+ Chain.CELO: {ZERO_ADDRESS: BigInt(750_000_000_000_000_000)},
241
+ Chain.ETHEREUM: {ZERO_ADDRESS: BigInt(10_000_000_000_000_000)},
242
+ Chain.GNOSIS: {ZERO_ADDRESS: BigInt(750_000_000_000_000_000)},
243
+ Chain.MODE: {ZERO_ADDRESS: BigInt(250_000_000_000_000)},
244
+ Chain.OPTIMISM: {ZERO_ADDRESS: BigInt(2_500_000_000_000_000)},
245
+ Chain.POLYGON: {ZERO_ADDRESS: BigInt(750_000_000_000_000_000)},
245
246
  }
246
247
 
247
248
  DEFAULT_EOA_TOPUPS_WITHOUT_SAFE = {
@@ -250,14 +251,14 @@ DEFAULT_EOA_TOPUPS_WITHOUT_SAFE = {
250
251
  }
251
252
 
252
253
  DEFAULT_RECOVERY_TOPUPS = {
253
- Chain.ARBITRUM_ONE: {ZERO_ADDRESS: 625_000_000_000_000},
254
- Chain.BASE: {ZERO_ADDRESS: 625_000_000_000_000},
255
- Chain.CELO: {ZERO_ADDRESS: 187_500_000_000_000_000},
256
- Chain.ETHEREUM: {ZERO_ADDRESS: 2_500_000_000_000_000},
257
- Chain.GNOSIS: {ZERO_ADDRESS: 187_500_000_000_000_000},
258
- Chain.MODE: {ZERO_ADDRESS: 62_500_000_000_000},
259
- Chain.OPTIMISM: {ZERO_ADDRESS: 625_000_000_000_000},
260
- Chain.POLYGON: {ZERO_ADDRESS: 187_500_000_000_000_000},
254
+ Chain.ARBITRUM_ONE: {ZERO_ADDRESS: BigInt(625_000_000_000_000)},
255
+ Chain.BASE: {ZERO_ADDRESS: BigInt(625_000_000_000_000)},
256
+ Chain.CELO: {ZERO_ADDRESS: BigInt(187_500_000_000_000_000)},
257
+ Chain.ETHEREUM: {ZERO_ADDRESS: BigInt(2_500_000_000_000_000)},
258
+ Chain.GNOSIS: {ZERO_ADDRESS: BigInt(187_500_000_000_000_000)},
259
+ Chain.MODE: {ZERO_ADDRESS: BigInt(62_500_000_000_000)},
260
+ Chain.OPTIMISM: {ZERO_ADDRESS: BigInt(625_000_000_000_000)},
261
+ Chain.POLYGON: {ZERO_ADDRESS: BigInt(187_500_000_000_000_000)},
261
262
  }
262
263
 
263
264
  DEFAULT_EOA_THRESHOLD = 0.5
@@ -36,6 +36,7 @@ from typing_extensions import TypedDict
36
36
 
37
37
  from operate.constants import FERNET_KEY_LENGTH, NO_STAKING_PROGRAM_ID
38
38
  from operate.resource import LocalResource
39
+ from operate.serialization import BigInt, serialize
39
40
 
40
41
 
41
42
  LedgerType = LedgerTypeOA
@@ -178,8 +179,8 @@ class DeployedNodes(LocalResource):
178
179
  class OnChainFundRequirements(LocalResource):
179
180
  """On-chain fund requirements."""
180
181
 
181
- agent: float
182
- safe: float
182
+ agent: BigInt
183
+ safe: BigInt
183
184
 
184
185
 
185
186
  OnChainTokenRequirements = t.Dict[str, OnChainFundRequirements]
@@ -192,7 +193,7 @@ class OnChainUserParams(LocalResource):
192
193
  staking_program_id: str
193
194
  nft: str
194
195
  agent_id: int
195
- cost_of_bond: int
196
+ cost_of_bond: BigInt
196
197
  fund_requirements: OnChainTokenRequirements
197
198
 
198
199
  @property
@@ -296,35 +297,54 @@ class Version:
296
297
  return self.patch < other.patch
297
298
 
298
299
 
299
- class ChainAmounts(dict[str, dict[str, dict[str, int]]]):
300
+ class ChainAmounts(dict[str, dict[str, dict[str, BigInt]]]):
300
301
  """
301
302
  Class that represents chain amounts as a dictionary
302
303
 
303
304
  The standard format follows the convention {chain: {address: {token: amount}}}
304
305
  """
305
306
 
307
+ @property
308
+ def json(self) -> dict:
309
+ """Return JSON representation with amounts as strings."""
310
+ return serialize(self)
311
+
312
+ @staticmethod
313
+ def from_json(obj: dict) -> "ChainAmounts":
314
+ """Create ChainAmounts from JSON representation."""
315
+ result: dict[str, dict[str, dict[str, BigInt]]] = {}
316
+
317
+ for chain, addresses in obj.items():
318
+ for address, assets in addresses.items():
319
+ for asset, amount in assets.items():
320
+ result.setdefault(chain, {}).setdefault(address, {})[asset] = (
321
+ BigInt(amount)
322
+ )
323
+
324
+ return ChainAmounts(result)
325
+
306
326
  @classmethod
307
327
  def shortfalls(
308
328
  cls, requirements: "ChainAmounts", balances: "ChainAmounts"
309
329
  ) -> "ChainAmounts":
310
330
  """Return the shortfalls between requirements and balances."""
311
- result: dict[str, dict[str, dict[str, int]]] = {}
331
+ result: dict[str, dict[str, dict[str, BigInt]]] = {}
312
332
 
313
333
  for chain, addresses in requirements.items():
314
334
  for address, assets in addresses.items():
315
335
  for asset, required_amount in assets.items():
316
336
  available = balances.get(chain, {}).get(address, {}).get(asset, 0)
317
337
  shortfall = max(required_amount - available, 0)
318
- result.setdefault(chain, {}).setdefault(address, {})[
319
- asset
320
- ] = shortfall
338
+ result.setdefault(chain, {}).setdefault(address, {})[asset] = (
339
+ BigInt(shortfall)
340
+ )
321
341
 
322
342
  return cls(result)
323
343
 
324
344
  @classmethod
325
345
  def add(cls, *chainamounts: "ChainAmounts") -> "ChainAmounts":
326
346
  """Add multiple ChainAmounts"""
327
- result: dict[str, dict[str, dict[str, int]]] = {}
347
+ result: dict[str, dict[str, dict[str, BigInt]]] = {}
328
348
 
329
349
  for ca in chainamounts:
330
350
  for chain, addresses in ca.items():
@@ -332,7 +352,9 @@ class ChainAmounts(dict[str, dict[str, dict[str, int]]]):
332
352
  for address, assets in addresses.items():
333
353
  result_assets = result_addresses.setdefault(address, {})
334
354
  for asset, amount in assets.items():
335
- result_assets[asset] = result_assets.get(asset, 0) + amount
355
+ result_assets[asset] = BigInt(
356
+ result_assets.get(asset, 0) + amount
357
+ )
336
358
 
337
359
  return cls(result)
338
360
 
@@ -346,7 +368,7 @@ class ChainAmounts(dict[str, dict[str, dict[str, int]]]):
346
368
  for _, addresses in output.items():
347
369
  for _, balances in addresses.items():
348
370
  for asset, amount in balances.items():
349
- balances[asset] = int(amount * multiplier)
371
+ balances[asset] = BigInt(int(amount * multiplier))
350
372
  return output
351
373
 
352
374
  def __sub__(self, other: "ChainAmounts") -> "ChainAmounts":
@@ -362,7 +384,7 @@ class ChainAmounts(dict[str, dict[str, dict[str, int]]]):
362
384
  for _, addresses in output.items():
363
385
  for _, balances in addresses.items():
364
386
  for asset, amount in balances.items():
365
- balances[asset] = int(amount // divisor)
387
+ balances[asset] = BigInt(int(amount // divisor))
366
388
  return output
367
389
 
368
390
  def __lt__(self, other: "ChainAmounts") -> bool:
@@ -46,6 +46,7 @@ from operate.ledger import DEFAULT_RPCS
46
46
  from operate.ledger.profiles import STAKING, get_staking_contract
47
47
  from operate.operate_types import (
48
48
  Chain,
49
+ ChainAmounts,
49
50
  LedgerType,
50
51
  ServiceEnvProvisionType,
51
52
  ServiceTemplate,
@@ -649,7 +650,9 @@ def _ask_funds_from_requirements(
649
650
  )
650
651
 
651
652
  if not requirements["is_refill_required"] and requirements["allow_start_agent"]:
652
- for chain_name, balances in requirements["balances"].items():
653
+ for chain_name, balances in ChainAmounts.from_json(
654
+ requirements["balances"]
655
+ ).items():
653
656
  ledger_api = wallet.ledger_api(
654
657
  chain=Chain(chain_name),
655
658
  rpc=service.chain_configs[chain_name].ledger_config.rpc,
@@ -662,17 +665,19 @@ def _ask_funds_from_requirements(
662
665
 
663
666
  return True
664
667
 
665
- for chain_name, chain_requirements in requirements["refill_requirements"].items():
668
+ for chain_name, chain_requirements in ChainAmounts.from_json(
669
+ requirements["refill_requirements"]
670
+ ).items():
666
671
  chain = Chain(chain_name)
667
672
  ledger_api = wallet.ledger_api(
668
673
  chain=chain,
669
674
  rpc=service.chain_configs[chain_name].ledger_config.rpc,
670
675
  )
671
- for wallet_address, requirements in chain_requirements.items():
676
+ for wallet_address, _requirements in chain_requirements.items():
672
677
  if wallet_address in ("master_safe", "service_safe"):
673
678
  continue # we can't ask funds in placeholder addresses
674
679
 
675
- for asset_address, requirement in requirements.items():
680
+ for asset_address, requirement in _requirements.items():
676
681
  ask_funds_in_address(
677
682
  ledger_api=ledger_api,
678
683
  chain=chain_name,
@@ -19,16 +19,14 @@
19
19
 
20
20
  """Local resource representation."""
21
21
 
22
- import enum
23
22
  import json
24
23
  import os
25
24
  import platform
26
25
  import shutil
27
- import types
28
26
  import typing as t
29
- from dataclasses import asdict, is_dataclass
30
27
  from pathlib import Path
31
28
 
29
+ from operate.serialization import deserialize, serialize
32
30
  from operate.utils import safe_file_operation
33
31
 
34
32
 
@@ -38,63 +36,6 @@ from operate.utils import safe_file_operation
38
36
  N_BACKUPS = 5
39
37
 
40
38
 
41
- def serialize(obj: t.Any) -> t.Any:
42
- """Serialize object."""
43
- if is_dataclass(obj) and not isinstance(obj, type):
44
- return serialize(asdict(obj))
45
- if isinstance(obj, Path):
46
- return str(obj)
47
- if isinstance(obj, dict):
48
- return {serialize(key): serialize(obj=value) for key, value in obj.items()}
49
- if isinstance(obj, list):
50
- return [serialize(obj=value) for value in obj]
51
- if isinstance(obj, enum.Enum):
52
- return obj.value
53
- if isinstance(obj, bytes):
54
- return obj.hex()
55
- return obj
56
-
57
-
58
- def deserialize(obj: t.Any, otype: t.Any) -> t.Any:
59
- """Desrialize a json object."""
60
-
61
- origin = getattr(otype, "__origin__", None)
62
-
63
- # Handle Union and Optional
64
- if origin is t.Union or isinstance(otype, types.UnionType):
65
- for arg in t.get_args(otype):
66
- if arg is type(None): # noqa: E721
67
- continue
68
- try:
69
- return deserialize(obj, arg)
70
- except Exception: # pylint: disable=broad-except # nosec
71
- continue
72
- return None
73
-
74
- base = getattr(otype, "__class__") # noqa: B009
75
- if base.__name__ == "_GenericAlias": # type: ignore
76
- args = otype.__args__ # type: ignore
77
- if len(args) == 1:
78
- (atype,) = args
79
- return [deserialize(arg, atype) for arg in obj]
80
- if len(args) == 2:
81
- (ktype, vtype) = args
82
- return {
83
- deserialize(key, ktype): deserialize(val, vtype)
84
- for key, val in obj.items()
85
- }
86
- return obj
87
- if base is enum.EnumMeta:
88
- return otype(obj)
89
- if otype is Path:
90
- return Path(obj)
91
- if is_dataclass(otype) and hasattr(otype, "from_json"):
92
- return otype.from_json(obj)
93
- if otype is bytes:
94
- return bytes.fromhex(obj)
95
- return obj
96
-
97
-
98
39
  class LocalResource:
99
40
  """Initialize local resource."""
100
41
 
@@ -0,0 +1,113 @@
1
+ # -*- coding: utf-8 -*-
2
+ # ------------------------------------------------------------------------------
3
+ #
4
+ # Copyright 2026 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
+ """Serialization utilities."""
21
+
22
+ import enum
23
+ import types
24
+ import typing as t
25
+ from dataclasses import asdict, is_dataclass
26
+ from pathlib import Path
27
+
28
+
29
+ class BigInt(int):
30
+ """BigInt class for large integers that serialize as strings."""
31
+
32
+ def __iadd__(self, other: t.Union[int, str]) -> "BigInt":
33
+ """In-place addition."""
34
+ return BigInt(int(self) + int(other))
35
+
36
+ def __isub__(self, other: t.Union[int, str]) -> "BigInt":
37
+ """In-place subtraction."""
38
+ return BigInt(int(self) - int(other))
39
+
40
+ def __imul__(self, other: t.Union[int, str]) -> "BigInt":
41
+ """In-place multiplication."""
42
+ return BigInt(int(self) * int(other))
43
+
44
+ def __ifloordiv__(self, other: t.Union[int, str]) -> "BigInt":
45
+ """In-place floor division."""
46
+ return BigInt(int(self) // int(other))
47
+
48
+ def __itruediv__(self, other: t.Union[int, str]) -> "BigInt":
49
+ """In-place true division."""
50
+ return BigInt(int(self) / int(other))
51
+
52
+
53
+ def serialize(obj: t.Any) -> t.Any: # pylint: disable=too-many-return-statements
54
+ """Serialize object."""
55
+ if is_dataclass(obj) and not isinstance(obj, type):
56
+ return serialize(asdict(obj))
57
+ if isinstance(obj, Path):
58
+ return str(obj)
59
+ if isinstance(obj, dict):
60
+ return {serialize(key): serialize(obj=value) for key, value in obj.items()}
61
+ if isinstance(obj, list):
62
+ return [serialize(obj=value) for value in obj]
63
+ if isinstance(obj, enum.Enum):
64
+ return obj.value
65
+ if isinstance(obj, bytes):
66
+ return obj.hex()
67
+ if hasattr(obj, "__class__") and obj.__class__.__name__ == "BigInt":
68
+ return str(obj)
69
+ return obj
70
+
71
+
72
+ def deserialize( # pylint: disable=too-many-return-statements
73
+ obj: t.Any, otype: t.Any
74
+ ) -> t.Any:
75
+ """Deserialize a json object."""
76
+
77
+ origin = getattr(otype, "__origin__", None)
78
+
79
+ # Handle Union and Optional
80
+ if origin is t.Union or isinstance(otype, types.UnionType):
81
+ for arg in t.get_args(otype):
82
+ if arg is type(None): # noqa: E721
83
+ continue
84
+ try:
85
+ return deserialize(obj, arg)
86
+ except Exception: # pylint: disable=broad-except # nosec
87
+ continue
88
+ return None
89
+
90
+ base = getattr(otype, "__class__") # noqa: B009
91
+ if base.__name__ == "_GenericAlias": # type: ignore
92
+ args = otype.__args__ # type: ignore
93
+ if len(args) == 1:
94
+ (atype,) = args
95
+ return [deserialize(arg, atype) for arg in obj]
96
+ if len(args) == 2:
97
+ (ktype, vtype) = args
98
+ return {
99
+ deserialize(key, ktype): deserialize(val, vtype)
100
+ for key, val in obj.items()
101
+ }
102
+ return obj
103
+ if base is enum.EnumMeta:
104
+ return otype(obj)
105
+ if otype is Path:
106
+ return Path(obj)
107
+ if is_dataclass(otype) and hasattr(otype, "from_json"):
108
+ return otype.from_json(obj)
109
+ if otype is bytes:
110
+ return bytes.fromhex(obj)
111
+ if hasattr(otype, "__name__") and otype.__name__ == "BigInt":
112
+ return BigInt(obj)
113
+ return obj
@@ -58,6 +58,7 @@ from operate.ledger.profiles import (
58
58
  get_asset_name,
59
59
  )
60
60
  from operate.operate_types import Chain, ChainAmounts, LedgerType, OnChainState
61
+ from operate.serialization import BigInt
61
62
  from operate.services.protocol import EthSafeTxBuilder, StakingManager, StakingState
62
63
  from operate.services.service import NON_EXISTENT_TOKEN, Service
63
64
  from operate.utils import concurrent_execute
@@ -253,23 +254,23 @@ class FundingManager:
253
254
  user_params = chain_config.chain_data.user_params
254
255
  number_of_agents = len(service.agent_addresses)
255
256
 
256
- requirements: defaultdict = defaultdict(int)
257
+ requirements: defaultdict = defaultdict(BigInt)
257
258
 
258
259
  if (
259
260
  not user_params.use_staking
260
261
  or not user_params.staking_program_id
261
262
  or user_params.staking_program_id == NO_STAKING_PROGRAM_ID
262
263
  ):
263
- protocol_agent_bonds = (
264
+ protocol_agent_bonds = BigInt(
264
265
  max(MIN_AGENT_BOND, user_params.cost_of_bond) * number_of_agents
265
266
  )
266
267
  protocol_security_deposit = max(
267
268
  MIN_SECURITY_DEPOSIT, user_params.cost_of_bond
268
269
  )
269
- staking_agent_bonds = 0
270
- staking_security_deposit = 0
270
+ staking_agent_bonds = BigInt(0)
271
+ staking_security_deposit = BigInt(0)
271
272
  else:
272
- protocol_agent_bonds = MIN_AGENT_BOND * number_of_agents
273
+ protocol_agent_bonds = BigInt(MIN_AGENT_BOND * number_of_agents)
273
274
  protocol_security_deposit = MIN_SECURITY_DEPOSIT
274
275
 
275
276
  staking_manager = StakingManager(chain=Chain(chain))
@@ -279,10 +280,10 @@ class FundingManager:
279
280
  ),
280
281
  )
281
282
 
282
- staking_agent_bonds = (
283
+ staking_agent_bonds = BigInt(
283
284
  staking_params["min_staking_deposit"] * number_of_agents
284
285
  )
285
- staking_security_deposit = staking_params["min_staking_deposit"]
286
+ staking_security_deposit = BigInt(staking_params["min_staking_deposit"])
286
287
  staking_token = staking_params["staking_token"]
287
288
  requirements[staking_token] += staking_agent_bonds
288
289
  requirements[staking_token] += staking_security_deposit
@@ -290,7 +291,7 @@ class FundingManager:
290
291
  for token, amount in staking_params[
291
292
  "additional_staking_tokens"
292
293
  ].items():
293
- requirements[token] = amount
294
+ requirements[token] = BigInt(amount)
294
295
 
295
296
  requirements[ZERO_ADDRESS] += protocol_agent_bonds
296
297
  requirements[ZERO_ADDRESS] += protocol_security_deposit
@@ -316,7 +317,7 @@ class FundingManager:
316
317
  protocol_bonded_assets = ChainAmounts()
317
318
 
318
319
  for chain, chain_config in service.chain_configs.items():
319
- bonded_assets: defaultdict = defaultdict(int)
320
+ bonded_assets: defaultdict = defaultdict(BigInt)
320
321
  ledger_config = chain_config.ledger_config
321
322
  user_params = chain_config.chain_data.user_params
322
323
 
@@ -366,7 +367,8 @@ class FundingManager:
366
367
  )
367
368
 
368
369
  # Determine bonded native amount
369
- security_deposit = service_info[0]
370
+ operator_balance = BigInt(operator_balance)
371
+ security_deposit = BigInt(service_info[0])
370
372
  service_state = service_info[6]
371
373
  agent_ids = service_info[7]
372
374
 
@@ -449,25 +451,25 @@ class FundingManager:
449
451
  ),
450
452
  )
451
453
 
452
- agent_bonds = 0
454
+ agent_bonds = BigInt(0)
453
455
  for agent_instances, agent_bond in zip(
454
456
  agent_instances_and_bonds[: len(agent_ids)],
455
457
  agent_instances_and_bonds[len(agent_ids) :],
456
458
  ):
457
459
  num_agent_instances = agent_instances[0]
458
- agent_bonds += num_agent_instances * agent_bond
460
+ agent_bonds += BigInt(num_agent_instances * agent_bond)
459
461
 
460
462
  if service_state == OnChainState.TERMINATED_BONDED:
461
463
  num_agent_instances = service_info[5]
462
- agent_bonds += num_agent_instances * token_bond
464
+ agent_bonds += BigInt(num_agent_instances * token_bond)
463
465
 
464
- security_deposit = 0
466
+ security_deposit = BigInt(0)
465
467
  if (
466
468
  OnChainState.ACTIVE_REGISTRATION
467
469
  <= service_state
468
470
  < OnChainState.TERMINATED_BONDED
469
471
  ):
470
- security_deposit = security_deposits[1]
472
+ security_deposit = BigInt(security_deposits[1])
471
473
 
472
474
  bonded_assets[staking_params["staking_token"]] += agent_bonds
473
475
  bonded_assets[staking_params["staking_token"]] += security_deposit
@@ -476,7 +478,7 @@ class FundingManager:
476
478
  for token, amount in staking_params[
477
479
  "additional_staking_tokens"
478
480
  ].items():
479
- bonded_assets[token] += amount
481
+ bonded_assets[token] += BigInt(amount)
480
482
 
481
483
  protocol_bonded_assets[chain] = {master_safe: dict(bonded_assets)}
482
484
 
@@ -871,14 +873,14 @@ class FundingManager:
871
873
  allow_start_agent = False
872
874
 
873
875
  return {
874
- "balances": balances,
875
- "bonded_assets": protocol_bonded_assets,
876
- "total_requirements": total_requirements,
877
- "refill_requirements": refill_requirements,
878
- "protocol_asset_requirements": protocol_asset_requirements,
876
+ "balances": balances.json,
877
+ "bonded_assets": protocol_bonded_assets.json,
878
+ "total_requirements": total_requirements.json,
879
+ "refill_requirements": refill_requirements.json,
880
+ "protocol_asset_requirements": protocol_asset_requirements.json,
879
881
  "is_refill_required": is_refill_required,
880
882
  "allow_start_agent": allow_start_agent,
881
- "agent_funding_requests": funding_requests,
883
+ "agent_funding_requests": funding_requests.json,
882
884
  "agent_funding_requests_cooldown": funding_requests_cooldown,
883
885
  "agent_funding_in_progress": funding_in_progress,
884
886
  }