diff --git a/docs/api.md b/docs/api.md index 381c6897..f90c9407 100644 --- a/docs/api.md +++ b/docs/api.md @@ -850,6 +850,200 @@ The refill requirements are computed based on the fund requirements present on t --- +## Bridge + +### `POST /api/bridge/bridge_refill_requirements` + +Creates a quote bundle to fulfill the bridge requests and returns + +- the refill requirements on the source chain for bridging assets to target chains, +- the quote bundle id to execute the request. + +
+ Request + +```json + { + "bridge_requests": [ + { + "from": { + "chain": "ethereum", + "address": "0xDe6B572A049B27D349e89aD0cBEF102227e31473", + "token": "0x0000000000000000000000000000000000000000" + }, + "to": { + "chain": "gnosis", + "address": "0xDe6B572A049B27D349e89aD0cBEF102227e31473", + "token": "0x0000000000000000000000000000000000000000", + "amount": 10000000000000000000 + }, + }, + { + "from": { + "chain": "ethereum", + "address": "0xDe6B572A049B27D349e89aD0cBEF102227e31473", + "token": "0x0000000000000000000000000000000000000000" + }, + "to": { + "chain": "gnosis", + "address": "0x28580196F52DB3C95C3d40Df88426e251d115842", + "token": "0x0000000000000000000000000000000000000000", + "amount": 10000000000000000000 + } + } + ], + "force_update": false + } +``` + +
+ +
+ Response + + ```json + { + "id": "qb-bdaafd7f-0698-4e10-83dd-d742cc0e656d", + "balances": { + "ethereum": { + "0xDe6B572A049B27D349e89aD0cBEF102227e31473": { + "0x0000000000000000000000000000000000000000": 0, + "0x0001A500A6B18995B03f44bb040A5fFc28E45CB0": 0 + } + } + }, + "bridge_total_requirements": { + "ethereum": { + "0x0000000000000000000000000000000000000000": 10073082159280405, + "0x0001A500A6B18995B03f44bb040A5fFc28E45CB0": 61944358967139717502 + } + }, + "bridge_refill_requirements": { + "ethereum": { + "0xDe6B572A049B27D349e89aD0cBEF102227e31473": { + "0x0000000000000000000000000000000000000000": 10073082159280405, + "0x0001A500A6B18995B03f44bb040A5fFc28E45CB0": 61944358967139717502 + } + } + }, + "expiration_timestamp": 1743000251, + "is_refill_required": true, + "bridge_request_status": [ + { + "message": "", + "status": "QUOTE_DONE", + }, + { + "message": "", + "status": "QUOTE_DONE", + } + ], + "error": false + } + ``` + +
+ +--- + +### `POST /api/bridge/execute` + +Executes a quote bundle. See [GET /api/bridge/status/{quote_bundle_id}](#get-apibridgestatusquote_bundle_id) for status values. + +
+ Request + +```json + { + "id": "qb-bdaafd7f-0698-4e10-83dd-d742cc0e656d" + } +``` + +
+ +
+ Response + + ```json + { + "id": "qb-bdaafd7f-0698-4e10-83dd-d742cc0e656d", + "bridge_request_status": [ + { + "explorer_link": "https://scan.li.fi/tx/0x3795206347eae1537d852bea05e36c3e76b08cefdfa2d772e24bac2e24f31db3", + "message": null, + "status": "EXECUTION_DONE", + "tx_hash": "0x3795206347eae1537d852bea05e36c3e76b08cefdfa2d772e24bac2e24f31db3", + }, + { + "explorer_link": "https://scan.li.fi/tx/0x0e53f1b6aa5552f2d4cfe8e623dd95e54ca079c4b23b89d0c0aa6ed4a6442384", + "message": null, + "status": "EXECUTION_PENDING", + "tx_hash": "0x0e53f1b6aa5552f2d4cfe8e623dd95e54ca079c4b23b89d0c0aa6ed4a6442384", + } + ], + "error": false + } + ``` + +
+ +--- + +### `GET /api/bridge/status/{quote_bundle_id}` + +Gets the status of a quote bundle. Individual bridge request status: + +- `QUOTE_DONE`: A quote is available. +- `QUOTE_FAILED`: Failed to request a quote. +- `EXECUTION_PENDING`: Execution submitted and pending to be finalized. +- `EXECUTION_DONE`: Execution finalized successfully. +- `EXECUTION_FAILED`: Execution failed. + +
+ Response + + ```json + { + "id": "qb-bdaafd7f-0698-4e10-83dd-d742cc0e656d", + "bridge_request_status": [ + { + "explorer_link": "https://scan.li.fi/tx/0x3795206347eae1537d852bea05e36c3e76b08cefdfa2d772e24bac2e24f31db3", + "message": null, + "status": "EXECUTION_DONE", + "tx_hash": "0x3795206347eae1537d852bea05e36c3e76b08cefdfa2d772e24bac2e24f31db3", + }, + { + "explorer_link": "https://scan.li.fi/tx/0x0e53f1b6aa5552f2d4cfe8e623dd95e54ca079c4b23b89d0c0aa6ed4a6442384", + "message": null, + "status": "EXECUTION_PENDING", + "tx_hash": "0x0e53f1b6aa5552f2d4cfe8e623dd95e54ca079c4b23b89d0c0aa6ed4a6442384", + } + ], + "error": false + } + ``` + +
+ +--- + +### `GET /api/bridge/last_executed_bundle_id` + +Gets the last executed quote bundle id. + +
+ Response + + ```json + { + "id": "br-52e3f945-b495-49bd-8ea2-cafa67468ed3" + } + ``` + +
+ +--- + ## Unused endpoints ### `POST /api/services/{service}/onchain/deploy` diff --git a/operate/bridge/bridge.py b/operate/bridge/bridge.py new file mode 100644 index 00000000..3649d31b --- /dev/null +++ b/operate/bridge/bridge.py @@ -0,0 +1,426 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2024 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ +"""Bridge manager.""" + + +import json +import logging +import time +import typing as t +import uuid +from dataclasses import dataclass +from pathlib import Path +from typing import cast + +from aea.helpers.logging import setup_logger +from deepdiff import DeepDiff + +from operate.bridge.providers.bridge_provider import BridgeProvider, BridgeRequest +from operate.bridge.providers.lifi_bridge_provider import LiFiBridgeProvider +from operate.bridge.providers.native_bridge_provider import ( + NativeBridgeProvider, + OmnibridgeContractAdaptor, + OptimismContractAdaptor, +) +from operate.constants import ZERO_ADDRESS +from operate.operate_types import Chain +from operate.resource import LocalResource +from operate.services.manage import get_assets_balances +from operate.utils import merge_sum_dicts, subtract_dicts +from operate.wallet.master import MasterWalletManager + + +DEFAULT_BUNDLE_VALIDITY_PERIOD = 3 * 60 +EXECUTED_BUNDLES_PATH = "executed" +BRIDGE_REQUEST_BUNDLE_PREFIX = "rb-" + + +NATIVE_BRIDGE_CONFIGS: t.Dict[str, t.Any] = { + "native-ethereum-to-base": { + "from_chain": "ethereum", + "from_bridge": "0x3154Cf16ccdb4C6d922629664174b904d80F2C35", + "to_chain": "base", + "to_bridge": "0x4200000000000000000000000000000000000010", + "bridge_eta": 300, + "bridge_contract_adaptor_class": OptimismContractAdaptor, + }, + "native-ethereum-to-mode": { + "from_chain": "ethereum", + "from_bridge": "0x735aDBbE72226BD52e818E7181953f42E3b0FF21", + "to_chain": "mode", + "to_bridge": "0x4200000000000000000000000000000000000010", + "bridge_eta": 300, + "bridge_contract_adaptor_class": OptimismContractAdaptor, + }, + "native-ethereum-to-optimism": { + "from_chain": "ethereum", + "from_bridge": "0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1", + "to_chain": "optimistic", + "to_bridge": "0x4200000000000000000000000000000000000010", + "bridge_eta": 300, + "bridge_contract_adaptor_class": OptimismContractAdaptor, + }, + "native-ethereum-to-gnosis": { + "from_chain": "ethereum", + "from_bridge": "0x88ad09518695c6c3712AC10a214bE5109a655671", + "to_chain": "gnosis", + "to_bridge": "0xf6A78083ca3e2a662D6dd1703c939c8aCE2e268d", + "bridge_eta": 1800, + "bridge_contract_adaptor_class": OmnibridgeContractAdaptor, + }, +} + + +@dataclass +class BridgeRequestBundle(LocalResource): + """BridgeRequestBundle""" + + requests_params: t.List[t.Dict] + bridge_requests: t.List[BridgeRequest] + timestamp: int + id: str + + def get_from_chains(self) -> set[Chain]: + """Get 'from' chains.""" + return { + Chain(request.params["from"]["chain"]) for request in self.bridge_requests + } + + def get_from_addresses(self, chain: Chain) -> set[str]: + """Get 'from' addresses.""" + chain_str = chain.value + return { + request.params["from"]["address"] + for request in self.bridge_requests + if request.params["from"]["chain"] == chain_str + } + + def get_from_tokens(self, chain: Chain) -> set[str]: + """Get 'from' tokens.""" + chain_str = chain.value + return { + request.params["from"]["token"] + for request in self.bridge_requests + if request.params["from"]["chain"] == chain_str + } + + +@dataclass +class BridgeManagerData(LocalResource): + """BridgeManagerData""" + + path: Path + version: int = 1 + last_requested_bundle: t.Optional[BridgeRequestBundle] = None + last_executed_bundle_id: t.Optional[str] = None + + _file = "bridge.json" + + # TODO Migrate to LocalResource? + # It can be inconvenient that all local resources create an empty resource + # if the file is corrupted. For example, if a service configuration is + # corrupted, we might want to halt execution, because otherwise, the application + # could continue as if the user is creating a service from scratch. + # For the bridge manager data, it's harmless, because its memory + # is limited to the process of getting and executing a quote. + @classmethod # Overrides from LocalResource + def load(cls, path: Path) -> "LocalResource": + """Load local resource.""" + + file = path / cls._file + if not file.exists(): + BridgeManagerData(path=path).store() + + try: + super().load(path=file) + except (json.JSONDecodeError, KeyError): + new_file = path / f"invalid_{int(time.time())}_{cls._file}" + file.rename(new_file) + BridgeManagerData(path=path).store() + + return super().load(path) + + +class BridgeManager: + """BridgeManager""" + + def __init__( + self, + path: Path, + wallet_manager: MasterWalletManager, + logger: t.Optional[logging.Logger] = None, + quote_validity_period: int = DEFAULT_BUNDLE_VALIDITY_PERIOD, + ) -> None: + """Initialize bridge manager.""" + self.path = path + self.wallet_manager = wallet_manager + self.logger = logger or setup_logger(name="operate.bridge.BridgeManager") + self.quote_validity_period = quote_validity_period + self.path.mkdir(exist_ok=True) + (self.path / EXECUTED_BUNDLES_PATH).mkdir(exist_ok=True) + self.data: BridgeManagerData = cast( + BridgeManagerData, BridgeManagerData.load(path) + ) + self._fallback_bridge_provider = LiFiBridgeProvider( + provider_id="LiFiBridgeProvider", + wallet_manager=wallet_manager, + logger=logger, + ) + + self._native_bridge_providers = { + bridge_id: NativeBridgeProvider( + config["bridge_contract_adaptor_class"]( + from_chain=config["from_chain"], + to_chain=config["to_chain"], + from_bridge=config["from_bridge"], + to_bridge=config["to_bridge"], + bridge_eta=config["bridge_eta"], + ), + bridge_id, + wallet_manager, + logger, + ) + for bridge_id, config in NATIVE_BRIDGE_CONFIGS.items() + } + + def _store_data(self) -> None: + self.logger.info("[BRIDGE MANAGER] Storing data to file.") + self.data.store() + + def _get_updated_bundle( + self, requests_params: t.List[t.Dict], force_update: bool + ) -> BridgeRequestBundle: + """Ensures to return a valid (non expired) bundle for the given inputs.""" + + now = int(time.time()) + bundle = self.data.last_requested_bundle + create_new_bundle = False + + if not bundle: + self.logger.info("[BRIDGE MANAGER] No last bundle.") + create_new_bundle = True + elif DeepDiff(requests_params, bundle.requests_params): + self.logger.info("[BRIDGE MANAGER] Different requests params.") + create_new_bundle = True + elif force_update: + self.logger.info("[BRIDGE MANAGER] Force bundle update.") + self.quote_bundle(bundle) + self._store_data() + elif now > bundle.timestamp + self.quote_validity_period: + self.logger.info("[BRIDGE MANAGER] Bundle expired.") + self.quote_bundle(bundle) + self._store_data() + + if not bundle or create_new_bundle: + self.logger.info("[BRIDGE MANAGER] Creating new bridge request bundle.") + + bridge_requests = [] + for params in requests_params: + for bridge_provider in self._native_bridge_providers.values(): + if bridge_provider.can_handle_request(params): + bridge_requests.append( + bridge_provider.create_request(params=params) + ) + break + else: + bridge_requests.append( + self._fallback_bridge_provider.create_request(params=params) + ) + + bundle = BridgeRequestBundle( + id=f"{BRIDGE_REQUEST_BUNDLE_PREFIX}{uuid.uuid4()}", + requests_params=requests_params, + bridge_requests=bridge_requests, + timestamp=now, + ) + + self.data.last_requested_bundle = bundle + self.quote_bundle(bundle) + self._store_data() + + return bundle + + def _raise_if_invalid(self, requests_params: t.List) -> None: + """Preprocess quote requests.""" + + for params in requests_params: + from_chain = params["from"]["chain"] + from_address = params["from"]["address"] + + wallet = self.wallet_manager.load(Chain(from_chain).ledger_type) + wallet_address = wallet.address + safe_address = wallet.safes.get(Chain(from_chain)) + + if from_address is None or not ( + from_address == wallet_address or from_address == safe_address + ): + raise ValueError( + f"Invalid input: 'from' address {from_address} does not match Master EOA nor Master Safe on chain {Chain(from_chain).name}." + ) + + def bridge_refill_requirements( + self, requests_params: t.List[t.Dict], force_update: bool = False + ) -> t.Dict: + """Get bridge refill requirements.""" + + self._raise_if_invalid(requests_params) + self.logger.info( + f"[BRIDGE MANAGER] Quote requests count: {len(requests_params)}." + ) + + bundle = self._get_updated_bundle(requests_params, force_update) + + balances = {} + for chain in bundle.get_from_chains(): + ledger_api = self.wallet_manager.load(chain.ledger_type).ledger_api(chain) + balances[chain.value] = get_assets_balances( + ledger_api=ledger_api, + asset_addresses={ZERO_ADDRESS} | bundle.get_from_tokens(chain), + addresses=bundle.get_from_addresses(chain), + ) + + bridge_total_requirements = self.bridge_total_requirements(bundle) + + bridge_refill_requirements = cast( + t.Dict[str, t.Dict[str, t.Dict[str, int]]], + subtract_dicts(bridge_total_requirements, balances), + ) + + is_refill_required = any( + amount > 0 + for from_addresses in bridge_refill_requirements.values() + for from_tokens in from_addresses.values() + for amount in from_tokens.values() + ) + + status_json = self.get_status_json(bundle.id) + status_json.update( + { + "balances": balances, + "bridge_refill_requirements": bridge_refill_requirements, + "bridge_total_requirements": bridge_total_requirements, + "expiration_timestamp": bundle.timestamp + self.quote_validity_period, + "is_refill_required": is_refill_required, + } + ) + return status_json + + def execute_bundle(self, bundle_id: str) -> t.Dict: + """Execute the bundle""" + + bundle = self.data.last_requested_bundle + + if not bundle: + raise RuntimeError("[BRIDGE MANAGER] No bundle.") + + if bundle.id != bundle_id: + raise RuntimeError( + f"Quote bundle id {bundle_id} does not match last requested bundle id {bundle.id}." + ) + + requirements = self.bridge_refill_requirements(bundle.requests_params) + self.data.last_requested_bundle = None + self.data.last_executed_bundle_id = bundle_id + bundle_path = self.path / EXECUTED_BUNDLES_PATH / f"{bundle.id}.json" + bundle.path = bundle_path + self._store_data() + bundle.store() + + if requirements["is_refill_required"]: + self.logger.warning( + f"[BRIDGE MANAGER] Refill requirements not satisfied for bundle id {bundle_id}." + ) + + self.logger.info("[BRIDGE MANAGER] Executing quotes.") + + for request in bundle.bridge_requests: + bridge = self._get_bridge_provider(request) + bridge.execute(request) + self._store_data() + + self._store_data() + bundle.store() + self.logger.info(f"[BRIDGE MANAGER] Bundle id {bundle_id} executed.") + return self.get_status_json(bundle_id) + + def get_status_json(self, bundle_id: str) -> t.Dict: + """Get execution status of bundle.""" + bundle = self.data.last_requested_bundle + + if bundle is not None and bundle.id == bundle_id: + pass + else: + bundle_path = self.path / EXECUTED_BUNDLES_PATH / f"{bundle_id}.json" + if bundle_path.exists(): + bundle = cast( + BridgeRequestBundle, BridgeRequestBundle.load(bundle_path) + ) + bundle.path = bundle_path # TODO backport to resource.py ? + else: + raise FileNotFoundError(f"Bundle with ID {bundle_id} does not exist.") + + initial_status = [request.status for request in bundle.bridge_requests] + + bridge_request_status = [] + for request in bundle.bridge_requests: + bridge = self._get_bridge_provider(request) + bridge_request_status.append(bridge.status_json(request)) + + updated_status = [request.status for request in bundle.bridge_requests] + + if initial_status != updated_status and bundle.path is not None: + bundle.store() + + return { + "id": bundle.id, + "bridge_request_status": bridge_request_status, + } + + def _get_bridge_provider(self, request: BridgeRequest) -> BridgeProvider: + bridge = self._native_bridge_providers.get(request.bridge_provider_id, None) + if bridge: + return bridge + + if request.bridge_provider_id == self._fallback_bridge_provider.provider_id: + return self._fallback_bridge_provider + + raise RuntimeError( + f"Bridge request {request.id} does not have a valid provider." + ) + + def bridge_total_requirements(self, bundle: BridgeRequestBundle) -> t.Dict: + """Sum bridge requirements.""" + requirements = [] + for bridge_request in bundle.bridge_requests: + bridge = self._get_bridge_provider(bridge_request) + requirements.append(bridge.bridge_requirements(bridge_request)) + + return merge_sum_dicts(*requirements) + + def quote_bundle(self, bundle: BridgeRequestBundle) -> None: + """Update the bundle with the quotes.""" + for bridge_request in bundle.bridge_requests: + bridge = self._get_bridge_provider(bridge_request) + bridge.quote(bridge_request) + bundle.timestamp = int(time.time()) + + def last_executed_bundle_id(self) -> t.Optional[str]: + """Get the last executed bundle id.""" + return self.data.last_executed_bundle_id diff --git a/operate/bridge/providers/bridge_provider.py b/operate/bridge/providers/bridge_provider.py new file mode 100644 index 00000000..ceb2bc3c --- /dev/null +++ b/operate/bridge/providers/bridge_provider.py @@ -0,0 +1,553 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2024 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ +"""Bridge provider.""" + + +import copy +import enum +import logging +import time +import typing as t +import uuid +from abc import ABC, abstractmethod +from dataclasses import dataclass + +from aea.crypto.base import LedgerApi +from aea.helpers.logging import setup_logger +from autonomy.chain.tx import TxSettler +from web3 import Web3 +from web3.middleware import geth_poa_middleware + +from operate.constants import ( + ON_CHAIN_INTERACT_RETRIES, + ON_CHAIN_INTERACT_SLEEP, + ON_CHAIN_INTERACT_TIMEOUT, + ZERO_ADDRESS, +) +from operate.operate_types import Chain +from operate.resource import LocalResource +from operate.wallet.master import MasterWalletManager + + +PLACEHOLDER_NATIVE_TOKEN_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" # nosec + +DEFAULT_MAX_QUOTE_RETRIES = 3 +BRIDGE_REQUEST_PREFIX = "r-" +MESSAGE_QUOTE_ZERO = "Zero-amount quote requested." +MESSAGE_EXECUTION_SKIPPED = "Execution skipped." +MESSAGE_EXECUTION_FAILED = "Execution failed:" +MESSAGE_EXECUTION_FAILED_ETA = f"{MESSAGE_EXECUTION_FAILED} bridge ETA exceeded." +MESSAGE_EXECUTION_FAILED_QUOTE_FAILED = f"{MESSAGE_EXECUTION_FAILED} quote failed." +MESSAGE_EXECUTION_FAILED_REVERTED = ( + f"{MESSAGE_EXECUTION_FAILED} bridge transaction reverted." +) +MESSAGE_EXECUTION_FAILED_SETTLEMENT = ( + f"{MESSAGE_EXECUTION_FAILED} transaction settlement failed." +) + +ERC20_APPROVE_SELECTOR = "0x095ea7b3" # First 4 bytes of Web3.keccak(text='approve(address,uint256)').hex()[:10] + +GAS_ESTIMATE_BUFFER = 1.10 + + +@dataclass +class QuoteData(LocalResource): + """QuoteData""" + + bridge_eta: t.Optional[int] + elapsed_time: float + message: t.Optional[str] + timestamp: int + provider_data: t.Optional[t.Dict] # Provider-specific data + + +@dataclass +class ExecutionData(LocalResource): + """ExecutionData""" + + elapsed_time: float + message: t.Optional[str] + timestamp: int + from_tx_hash: t.Optional[str] + to_tx_hash: t.Optional[str] + provider_data: t.Optional[t.Dict] # Provider-specific data + + +class BridgeRequestStatus(str, enum.Enum): + """BridgeRequestStatus""" + + CREATED = "CREATED" + QUOTE_DONE = "QUOTE_DONE" + QUOTE_FAILED = "QUOTE_FAILED" + EXECUTION_PENDING = "EXECUTION_PENDING" + EXECUTION_DONE = "EXECUTION_DONE" + EXECUTION_FAILED = "EXECUTION_FAILED" + EXECUTION_UNKNOWN = "EXECUTION_UNKNOWN" + + def __str__(self) -> str: + """__str__""" + return self.value + + +@dataclass +class BridgeRequest(LocalResource): + """BridgeRequest""" + + params: t.Dict + bridge_provider_id: str + id: str + status: BridgeRequestStatus + quote_data: t.Optional[QuoteData] + execution_data: t.Optional[ExecutionData] + + +class BridgeProvider(ABC): + """(Abstract) BridgeProvider. + + Expected usage: + params = {...} + + 1. request = bridge.create_request(params) + 2. bridge.quote(request) + 3. bridge.requirements(request) + 4. bridge.execute(request) + 5. bridge.status_json(request) + + Derived classes must implement the following methods: + - description + - quote + - _update_execution_status + - _get_approve_tx + - _get_bridge_tx + - _get_explorer_link + """ + + def __init__( + self, + wallet_manager: MasterWalletManager, + provider_id: str, + logger: t.Optional[logging.Logger] = None, + ) -> None: + """Initialize the bridge provider.""" + self.wallet_manager = wallet_manager + self.provider_id = provider_id + self.logger = logger or setup_logger(name="operate.bridge.BridgeProvider") + + def description(self) -> str: + """Get a human-readable description of the bridge provider.""" + return self.__class__.__name__ + + def _validate(self, bridge_request: BridgeRequest) -> None: + """Validate theat the bridge request was created by this bridge.""" + if bridge_request.bridge_provider_id != self.provider_id: + raise ValueError( + f"Bridge request provider id {bridge_request.bridge_provider_id} does not match the bridge provider id {self.provider_id}" + ) + + def can_handle_request(self, params: t.Dict) -> bool: + """Returns 'true' if the bridge can handle a request for 'params'.""" + + if "from" not in params or "to" not in params: + self.logger.error( + "[BRIDGE PROVIDER] Invalid input: All requests must contain exactly one 'from' and one 'to' sender." + ) + return False + + from_ = params["from"] + to = params["to"] + + if ( + not isinstance(from_, t.Dict) + or "chain" not in from_ + or "address" not in from_ + or "token" not in from_ + ): + self.logger.error( + "[BRIDGE PROVIDER] Invalid input: 'from' must contain 'chain', 'address', and 'token'." + ) + return False + + if ( + not isinstance(to, t.Dict) + or "chain" not in to + or "address" not in to + or "token" not in to + or "amount" not in to + ): + self.logger.error( + "[BRIDGE PROVIDER] Invalid input: 'to' must contain 'chain', 'address', 'token', and 'amount'." + ) + return False + + return True + + def create_request(self, params: t.Dict) -> BridgeRequest: + """Create a bridge request.""" + + if not self.can_handle_request(params): + raise ValueError("Invalid input: Cannot process bridge request.") + + w3 = Web3() + params = copy.deepcopy(params) + params["from"]["address"] = w3.to_checksum_address(params["from"]["address"]) + params["from"]["token"] = w3.to_checksum_address(params["from"]["token"]) + params["to"]["address"] = w3.to_checksum_address(params["to"]["address"]) + params["to"]["token"] = w3.to_checksum_address(params["to"]["token"]) + params["to"]["amount"] = int(params["to"]["amount"]) + + return BridgeRequest( + params=params, + bridge_provider_id=self.provider_id, + id=f"{BRIDGE_REQUEST_PREFIX}{uuid.uuid4()}", + quote_data=None, + execution_data=None, + status=BridgeRequestStatus.CREATED, + ) + + def _from_ledger_api(self, bridge_request: BridgeRequest) -> LedgerApi: + """Get the from ledger api.""" + from_chain = bridge_request.params["from"]["chain"] + chain = Chain(from_chain) + wallet = self.wallet_manager.load(chain.ledger_type) + ledger_api = wallet.ledger_api(chain) + + # TODO: Backport to open aea/autonomy + if chain == Chain.OPTIMISTIC: + ledger_api.api.middleware_onion.inject(geth_poa_middleware, layer=0) + + return ledger_api + + def _to_ledger_api(self, bridge_request: BridgeRequest) -> LedgerApi: + """Get the from ledger api.""" + from_chain = bridge_request.params["to"]["chain"] + chain = Chain(from_chain) + wallet = self.wallet_manager.load(chain.ledger_type) + ledger_api = wallet.ledger_api(chain) + + # TODO: Backport to open aea/autonomy + if chain == Chain.OPTIMISTIC: + ledger_api.api.middleware_onion.inject(geth_poa_middleware, layer=0) + + return ledger_api + + @abstractmethod + def quote(self, bridge_request: BridgeRequest) -> None: + """Update the request with the quote.""" + raise NotImplementedError() + + @abstractmethod + def _get_approve_tx(self, bridge_request: BridgeRequest) -> t.Optional[t.Dict]: + """Get the approve transaction.""" + raise NotImplementedError() + + @abstractmethod + def _get_bridge_tx(self, bridge_request: BridgeRequest) -> t.Optional[t.Dict]: + """Get the bridge transaction.""" + raise NotImplementedError() + + def bridge_requirements(self, bridge_request: BridgeRequest) -> t.Dict: + """Gets the bridge requirements to execute the quote, with updated gas estimation.""" + self.logger.info( + f"[BRIDGE PROVIDER] Bridge requirements for request {bridge_request.id}." + ) + + self._validate(bridge_request) + + from_chain = bridge_request.params["from"]["chain"] + from_address = bridge_request.params["from"]["address"] + from_token = bridge_request.params["from"]["token"] + from_ledger_api = self._from_ledger_api(bridge_request) + + txs = [] + + approve_tx = self._get_approve_tx(bridge_request) + if approve_tx: + txs.append(("approve_tx", approve_tx)) + bridge_tx = self._get_bridge_tx(bridge_request) + if bridge_tx: + txs.append(("bridge_tx", bridge_tx)) + + if not txs: + return { + from_chain: { + from_address: { + ZERO_ADDRESS: 0, + from_token: 0, + } + } + } + + total_native = 0 + total_gas_fees = 0 + total_token = 0 + + for tx_label, tx in txs: + self.logger.debug( + f"[BRIDGE PROVIDER] Processing transaction {tx_label} for bridge request {bridge_request.id}." + ) + self._update_with_gas_pricing(tx, from_ledger_api) + gas_key = "gasPrice" if "gasPrice" in tx else "maxFeePerGas" + gas_fees = tx.get(gas_key, 0) * tx["gas"] + tx_value = int(tx.get("value", 0)) + total_gas_fees += gas_fees + total_native += tx_value + gas_fees + + self.logger.debug( + f"[BRIDGE PROVIDER] Transaction {gas_key}={tx.get(gas_key, 0)} maxPriorityFeePerGas={tx.get('maxPriorityFeePerGas', -1)} gas={tx['gas']} {gas_fees=} {tx_value=}" + ) + self.logger.debug(f"[BRIDGE PROVIDER] {from_ledger_api.api.eth.gas_price=}") + self.logger.debug( + f"[BRIDGE PROVIDER] {from_ledger_api.api.eth.get_block('latest').baseFeePerGas=}" + ) + + if tx.get("to", "").lower() == from_token.lower() and tx.get( + "data", "" + ).startswith(ERC20_APPROVE_SELECTOR): + try: + amount = int(tx["data"][-64:], 16) + total_token += amount + except Exception as e: + raise RuntimeError("Malformed ERC20 approve transaction.") from e + + self.logger.info( + f"[BRIDGE PROVIDER] Total gas fees for bridge request {bridge_request.id}: {total_gas_fees} native units." + ) + + result = { + from_chain: { + from_address: { + ZERO_ADDRESS: total_native, + } + } + } + + if from_token != ZERO_ADDRESS: + result[from_chain][from_address][from_token] = total_token + + return result + + def execute(self, bridge_request: BridgeRequest) -> None: + """Execute the request.""" + self.logger.info( + f"[BRIDGE PROVIDER] Executing bridge request {bridge_request.id}." + ) + + self._validate(bridge_request) + + if bridge_request.status in (BridgeRequestStatus.QUOTE_FAILED): + self.logger.info( + f"[BRIDGE PROVIDER] {MESSAGE_EXECUTION_FAILED_QUOTE_FAILED}." + ) + execution_data = ExecutionData( + elapsed_time=0, + message=f"{MESSAGE_EXECUTION_FAILED_QUOTE_FAILED}", + timestamp=int(time.time()), + from_tx_hash=None, + to_tx_hash=None, + provider_data=None, + ) + bridge_request.execution_data = execution_data + bridge_request.status = BridgeRequestStatus.EXECUTION_FAILED + return + + if bridge_request.status not in (BridgeRequestStatus.QUOTE_DONE,): + raise RuntimeError( + f"Cannot execute bridge request {bridge_request.id} with status {bridge_request.status}." + ) + if not bridge_request.quote_data: + raise RuntimeError( + f"Cannot execute bridge request {bridge_request.id}: quote data not present." + ) + if bridge_request.execution_data: + raise RuntimeError( + f"Cannot execute bridge request {bridge_request.id}: execution data already present." + ) + + txs = [] + + approve_tx = self._get_approve_tx(bridge_request) + if approve_tx: + txs.append(("approve_tx", approve_tx)) + bridge_tx = self._get_bridge_tx(bridge_request) + if bridge_tx: + txs.append(("bridge_tx", bridge_tx)) + + if not txs: + self.logger.info( + f"[BRIDGE PROVIDER] {MESSAGE_EXECUTION_SKIPPED} ({bridge_request.status=})" + ) + execution_data = ExecutionData( + elapsed_time=0, + message=f"{MESSAGE_EXECUTION_SKIPPED} ({bridge_request.status=})", + timestamp=int(time.time()), + from_tx_hash=None, + to_tx_hash=None, + provider_data=None, + ) + bridge_request.execution_data = execution_data + bridge_request.status = BridgeRequestStatus.EXECUTION_DONE + return + + try: + self.logger.info( + f"[BRIDGE PROVIDER] Executing bridge request {bridge_request.id}." + ) + timestamp = time.time() + chain = Chain(bridge_request.params["from"]["chain"]) + from_address = bridge_request.params["from"]["address"] + wallet = self.wallet_manager.load(chain.ledger_type) + from_ledger_api = self._from_ledger_api(bridge_request) + tx_settler = TxSettler( + ledger_api=from_ledger_api, + crypto=wallet.crypto, + chain_type=Chain(bridge_request.params["from"]["chain"]), + timeout=ON_CHAIN_INTERACT_TIMEOUT, + retries=ON_CHAIN_INTERACT_RETRIES, + sleep=ON_CHAIN_INTERACT_SLEEP, + ) + tx_hashes = [] + + for tx_label, tx in txs: + self.logger.info(f"[BRIDGE] Executing transaction {tx_label}.") + nonce = from_ledger_api.api.eth.get_transaction_count(from_address) + tx["nonce"] = nonce # TODO: backport to TxSettler + setattr( # noqa: B010 + tx_settler, "build", lambda *args, **kwargs: tx # noqa: B023 + ) + tx_receipt = tx_settler.transact( + method=lambda: {}, + contract="", + kwargs={}, + dry_run=False, + ) + self.logger.info(f"[BRIDGE] Transaction {tx_label} settled.") + tx_hashes.append(tx_receipt.get("transactionHash", "").hex()) + + execution_data = ExecutionData( + elapsed_time=time.time() - timestamp, + message=None, + timestamp=int(timestamp), + from_tx_hash=tx_hashes[-1], + to_tx_hash=None, + provider_data=None, + ) + bridge_request.execution_data = execution_data + if len(tx_hashes) == len(txs): + bridge_request.status = BridgeRequestStatus.EXECUTION_PENDING + else: + bridge_request.execution_data.message = ( + MESSAGE_EXECUTION_FAILED_SETTLEMENT + ) + bridge_request.status = BridgeRequestStatus.EXECUTION_FAILED + + except Exception as e: # pylint: disable=broad-except + self.logger.error(f"[BRIDGE PROVIDER] Error executing bridge request: {e}") + execution_data = ExecutionData( + elapsed_time=time.time() - timestamp, + message=f"{MESSAGE_EXECUTION_FAILED} {str(e)}", + timestamp=int(time.time()), + from_tx_hash=None, + to_tx_hash=None, + provider_data=None, + ) + bridge_request.execution_data = execution_data + bridge_request.status = BridgeRequestStatus.EXECUTION_FAILED + + @abstractmethod + def _update_execution_status(self, bridge_request: BridgeRequest) -> None: + """Update the execution status.""" + raise NotImplementedError() + + @abstractmethod + def _get_explorer_link(self, bridge_request: BridgeRequest) -> t.Optional[str]: + """Get the explorer link for a transaction.""" + raise NotImplementedError() + + def status_json(self, bridge_request: BridgeRequest) -> t.Dict: + """JSON representation of the status.""" + self._validate(bridge_request) + + if bridge_request.execution_data and bridge_request.quote_data: + self._update_execution_status(bridge_request) + tx_hash = None + if bridge_request.execution_data.from_tx_hash: + tx_hash = bridge_request.execution_data.from_tx_hash + + return { + "eta": bridge_request.quote_data.bridge_eta, + "explorer_link": self._get_explorer_link(bridge_request), + "message": bridge_request.execution_data.message, + "status": bridge_request.status.value, + "tx_hash": tx_hash, + } + if bridge_request.quote_data: + return { + "eta": bridge_request.quote_data.bridge_eta, + "message": bridge_request.quote_data.message, + "status": bridge_request.status.value, + } + + return {"message": None, "status": bridge_request.status.value} + + @staticmethod + def _tx_timestamp(tx_hash: str, ledger_api: LedgerApi) -> int: + receipt = ledger_api.api.eth.get_transaction_receipt(tx_hash) + block = ledger_api.api.eth.get_block(receipt.blockNumber) + return block.timestamp + + # TODO backport to open aea/autonomy + # TODO This gas pricing management should possibly be done at a lower level in the library + @staticmethod + def _update_with_gas_pricing(tx: t.Dict, ledger_api: LedgerApi) -> None: + tx.pop("maxFeePerGas", None) + tx.pop("gasPrice", None) + tx.pop("maxPriorityFeePerGas", None) + + gas_pricing = ledger_api.try_get_gas_pricing() + if gas_pricing is None: + raise RuntimeError("Unable to retrieve gas pricing.") + + if "maxFeePerGas" in gas_pricing and "maxPriorityFeePerGas" in gas_pricing: + tx["maxFeePerGas"] = gas_pricing["maxFeePerGas"] + tx["maxPriorityFeePerGas"] = gas_pricing["maxPriorityFeePerGas"] + elif "gasPrice" in gas_pricing: + tx["gasPrice"] = gas_pricing["gasPrice"] + else: + raise RuntimeError("Retrieved invalid gas pricing.") + + # TODO backport to open aea/autonomy + @staticmethod + def _update_with_gas_estimate(tx: t.Dict, ledger_api: LedgerApi) -> None: + original_gas = tx.get("gas", 1) + tx["gas"] = 1 + ledger_api.update_with_gas_estimate(tx) + + if tx["gas"] > 1: + return + + original_from = tx["from"] + tx["from"] = PLACEHOLDER_NATIVE_TOKEN_ADDRESS + ledger_api.update_with_gas_estimate(tx) + tx["from"] = original_from + + if tx["gas"] > 1: + return + + tx["gas"] = original_gas diff --git a/operate/bridge/providers/lifi_bridge_provider.py b/operate/bridge/providers/lifi_bridge_provider.py new file mode 100644 index 00000000..75647885 --- /dev/null +++ b/operate/bridge/providers/lifi_bridge_provider.py @@ -0,0 +1,363 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2024 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ +"""LI.FI Bridge provider.""" + + +import enum +import time +import typing as t +from http import HTTPStatus +from math import ceil +from urllib.parse import urlencode + +import requests +from autonomy.chain.base import registry_contracts + +from operate.bridge.providers.bridge_provider import ( + BridgeProvider, + BridgeRequest, + BridgeRequestStatus, + DEFAULT_MAX_QUOTE_RETRIES, + GAS_ESTIMATE_BUFFER, + MESSAGE_QUOTE_ZERO, + QuoteData, +) +from operate.constants import ZERO_ADDRESS +from operate.operate_types import Chain + + +LIFI_DEFAULT_ETA = 5 * 60 + + +class LiFiTransactionStatus(str, enum.Enum): + """LI.FI transaction status.""" + + NOT_FOUND = "NOT_FOUND" + INVALID = "INVALID" + PENDING = "PENDING" + DONE = "DONE" + FAILED = "FAILED" + UNKNOWN = "UNKNOWN" + + def __str__(self) -> str: + """__str__""" + return self.value + + +class LiFiBridgeProvider(BridgeProvider): + """LI.FI Bridge provider.""" + + def description(self) -> str: + """Get a human-readable description of the bridge provider.""" + return "LI.FI Bridge & DEX Aggregation Protocol https://li.fi/" + + def quote(self, bridge_request: BridgeRequest) -> None: + """Update the request with the quote.""" + self._validate(bridge_request) + + if bridge_request.status not in ( + BridgeRequestStatus.CREATED, + BridgeRequestStatus.QUOTE_DONE, + BridgeRequestStatus.QUOTE_FAILED, + ): + raise RuntimeError( + f"Cannot quote bridge request {bridge_request.id} with status {bridge_request.status}." + ) + + if bridge_request.execution_data: + raise RuntimeError( + f"Cannot quote bridge request {bridge_request.id}: execution already present." + ) + + from_chain = bridge_request.params["from"]["chain"] + from_address = bridge_request.params["from"]["address"] + from_token = bridge_request.params["from"]["token"] + to_chain = bridge_request.params["to"]["chain"] + to_address = bridge_request.params["to"]["address"] + to_token = bridge_request.params["to"]["token"] + to_amount = bridge_request.params["to"]["amount"] + + if to_amount == 0: + self.logger.info(f"[LI.FI BRIDGE] {MESSAGE_QUOTE_ZERO}") + quote_data = QuoteData( + bridge_eta=0, + elapsed_time=0, + message=MESSAGE_QUOTE_ZERO, + provider_data=None, + timestamp=int(time.time()), + ) + bridge_request.quote_data = quote_data + bridge_request.status = BridgeRequestStatus.QUOTE_DONE + return + + url = "https://li.quest/v1/quote/toAmount" + headers = {"accept": "application/json"} + params = { + "fromChain": Chain(from_chain).id, + "fromAddress": from_address, + "fromToken": from_token, + "toChain": Chain(to_chain).id, + "toAddress": to_address, + "toToken": to_token, + "toAmount": to_amount, + "maxPriceImpact": 0.50, # TODO determine correct value + } + for attempt in range(1, DEFAULT_MAX_QUOTE_RETRIES + 1): + start = time.time() + try: + self.logger.info(f"[LI.FI BRIDGE] GET {url}?{urlencode(params)}") + response = requests.get( + url=url, headers=headers, params=params, timeout=30 + ) + response.raise_for_status() + response_json = response.json() + quote_data = QuoteData( + bridge_eta=LIFI_DEFAULT_ETA, + elapsed_time=time.time() - start, + message=None, + provider_data={ + "attempts": attempt, + "response": response_json, + "response_status": response.status_code, + }, + timestamp=int(time.time()), + ) + bridge_request.quote_data = quote_data + bridge_request.status = BridgeRequestStatus.QUOTE_DONE + return + except requests.Timeout as e: + self.logger.warning( + f"[LI.FI BRIDGE] Timeout request on attempt {attempt}/{DEFAULT_MAX_QUOTE_RETRIES}: {e}." + ) + quote_data = QuoteData( + bridge_eta=None, + elapsed_time=time.time() - start, + message=str(e), + provider_data={ + "attempts": attempt, + "response": None, + "response_status": HTTPStatus.GATEWAY_TIMEOUT, + }, + timestamp=int(time.time()), + ) + except requests.RequestException as e: + self.logger.warning( + f"[LI.FI BRIDGE] Request failed on attempt {attempt}/{DEFAULT_MAX_QUOTE_RETRIES}: {e}." + ) + response_json = response.json() + quote_data = QuoteData( + bridge_eta=None, + elapsed_time=time.time() - start, + message=response_json.get("message") or str(e), + provider_data={ + "attempts": attempt, + "response": response_json, + "response_status": getattr( + response, "status_code", HTTPStatus.BAD_GATEWAY + ), + }, + timestamp=int(time.time()), + ) + except Exception as e: # pylint:disable=broad-except + self.logger.warning( + f"[LI.FI BRIDGE] Request failed on attempt {attempt}/{DEFAULT_MAX_QUOTE_RETRIES}: {e}." + ) + quote_data = QuoteData( + bridge_eta=None, + elapsed_time=time.time() - start, + message=str(e), + provider_data={ + "attempts": attempt, + "response": None, + "response_status": HTTPStatus.INTERNAL_SERVER_ERROR, + }, + timestamp=int(time.time()), + ) + if attempt >= DEFAULT_MAX_QUOTE_RETRIES: + self.logger.error( + f"[LI.FI BRIDGE] Request failed after {DEFAULT_MAX_QUOTE_RETRIES} attempts." + ) + bridge_request.quote_data = quote_data + bridge_request.status = BridgeRequestStatus.QUOTE_FAILED + return + + time.sleep(2) + + def _get_approve_tx(self, bridge_request: BridgeRequest) -> t.Optional[t.Dict]: + """Get the approve transaction.""" + self.logger.info( + f"[LI.FI BRIDGE] Get appprove transaction for bridge request {bridge_request.id}." + ) + + if bridge_request.params["to"]["amount"] == 0: + return None + + quote_data = bridge_request.quote_data + if not quote_data: + return None + + if not quote_data.provider_data: + return None + + quote = quote_data.provider_data.get("response") + if not quote: + return None + + if "action" not in quote: + return None + + from_token = quote["action"]["fromToken"]["address"] + if from_token == ZERO_ADDRESS: + return None + + transaction_request = quote.get("transactionRequest") + if not transaction_request: + return None + + from_amount = int(quote["action"]["fromAmount"]) + from_ledger_api = self._from_ledger_api(bridge_request) + + approve_tx = registry_contracts.erc20.get_approve_tx( + ledger_api=from_ledger_api, + contract_address=from_token, + spender=transaction_request["to"], + sender=transaction_request["from"], + amount=from_amount, + ) + approve_tx["gas"] = 200_000 # TODO backport to ERC20 contract as default + BridgeProvider._update_with_gas_pricing(approve_tx, from_ledger_api) + BridgeProvider._update_with_gas_estimate(approve_tx, from_ledger_api) + approve_tx["gas"] = ceil(approve_tx["gas"] * GAS_ESTIMATE_BUFFER) + return approve_tx + + def _get_bridge_tx(self, bridge_request: BridgeRequest) -> t.Optional[t.Dict]: + """Get the bridge transaction.""" + self.logger.info( + f"[LI.FI BRIDGE] Get bridge transaction for bridge request {bridge_request.id}." + ) + + if bridge_request.params["to"]["amount"] == 0: + return None + + quote_data = bridge_request.quote_data + if not quote_data: + return None + + if not quote_data.provider_data: + return None + + quote = quote_data.provider_data.get("response") + if not quote: + return None + + if "action" not in quote: + return None + + transaction_request = quote.get("transactionRequest") + if not transaction_request: + return None + + from_ledger_api = self._from_ledger_api(bridge_request) + + bridge_tx = { + "value": int(transaction_request["value"], 16), + "to": transaction_request["to"], + "data": transaction_request["data"], # TODO remove bytes? + "from": transaction_request["from"], + "chainId": transaction_request["chainId"], + "gasPrice": int(transaction_request["gasPrice"], 16), + "gas": int(transaction_request["gasLimit"], 16), + "nonce": from_ledger_api.api.eth.get_transaction_count( + transaction_request["from"] + ), + } + BridgeProvider._update_with_gas_pricing(bridge_tx, from_ledger_api) + BridgeProvider._update_with_gas_estimate(bridge_tx, from_ledger_api) + return bridge_tx + + def _update_execution_status(self, bridge_request: BridgeRequest) -> None: + """Update the execution status.""" + + if bridge_request.status not in ( + BridgeRequestStatus.EXECUTION_PENDING, + BridgeRequestStatus.EXECUTION_UNKNOWN, + ): + return + + execution_data = bridge_request.execution_data + if not execution_data: + raise RuntimeError( + f"Cannot update bridge request {bridge_request.id}: execution data not present." + ) + + if not execution_data.from_tx_hash: + return + + url = "https://li.quest/v1/status" + headers = {"accept": "application/json"} + params = { + "txHash": execution_data.from_tx_hash, + } + + try: + self.logger.info(f"[LI.FI BRIDGE] GET {url}?{urlencode(params)}") + response = requests.get(url=url, headers=headers, params=params, timeout=30) + response_json = response.json() + lifi_status = response_json.get( + "status", str(LiFiTransactionStatus.UNKNOWN) + ) + execution_data.message = response_json.get( + "substatusMessage", response_json.get("message") + ) + response.raise_for_status() + except Exception as e: + self.logger.error( + f"[LI.FI BRIDGE] Failed to update bridge status for {bridge_request.id}: {e}" + ) + + if lifi_status == LiFiTransactionStatus.DONE: + self.logger.info(f"[LI.FI BRIDGE] Execution done for {bridge_request.id}.") + from_ledger_api = self._from_ledger_api(bridge_request) + from_tx_hash = execution_data.from_tx_hash + to_ledger_api = self._to_ledger_api(bridge_request) + to_tx_hash = response_json.get("receiving", {}).get("txHash") + execution_data.message = None + execution_data.to_tx_hash = to_tx_hash + execution_data.elapsed_time = BridgeProvider._tx_timestamp( + to_tx_hash, to_ledger_api + ) - BridgeProvider._tx_timestamp(from_tx_hash, from_ledger_api) + bridge_request.status = BridgeRequestStatus.EXECUTION_DONE + elif lifi_status == LiFiTransactionStatus.FAILED: + bridge_request.status = BridgeRequestStatus.EXECUTION_FAILED + elif lifi_status == LiFiTransactionStatus.PENDING: + bridge_request.status = BridgeRequestStatus.EXECUTION_PENDING + else: + bridge_request.status = BridgeRequestStatus.EXECUTION_UNKNOWN + + def _get_explorer_link(self, bridge_request: BridgeRequest) -> t.Optional[str]: + """Get the explorer link for a transaction.""" + if not bridge_request.execution_data: + return None + + tx_hash = bridge_request.execution_data.from_tx_hash + if not tx_hash: + return None + + return f"https://scan.li.fi/tx/{tx_hash}" diff --git a/operate/bridge/providers/native_bridge_provider.py b/operate/bridge/providers/native_bridge_provider.py new file mode 100644 index 00000000..016f01f4 --- /dev/null +++ b/operate/bridge/providers/native_bridge_provider.py @@ -0,0 +1,652 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2024 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ +"""Native bridge provider.""" + + +import logging +import time +import typing as t +from abc import ABC, abstractmethod +from math import ceil + +from aea.common import JSONLike +from aea.crypto.base import LedgerApi +from autonomy.chain.base import registry_contracts +from eth_typing import BlockIdentifier +from web3 import Web3 + +from operate.bridge.providers.bridge_provider import ( + BridgeProvider, + BridgeRequest, + BridgeRequestStatus, + GAS_ESTIMATE_BUFFER, + MESSAGE_EXECUTION_FAILED, + MESSAGE_EXECUTION_FAILED_ETA, + MESSAGE_EXECUTION_FAILED_REVERTED, + MESSAGE_QUOTE_ZERO, + QuoteData, +) +from operate.constants import ZERO_ADDRESS +from operate.data import DATA_DIR +from operate.data.contracts.foreign_omnibridge.contract import ForeignOmnibridge +from operate.data.contracts.home_omnibridge.contract import HomeOmnibridge +from operate.data.contracts.l1_standard_bridge.contract import ( + DEFAULT_BRIDGE_MIN_GAS_LIMIT, + L1StandardBridge, +) +from operate.data.contracts.l2_standard_bridge.contract import L2StandardBridge +from operate.data.contracts.optimism_mintable_erc20.contract import ( + OptimismMintableERC20, +) +from operate.ledger.profiles import ERC20_TOKENS, EXPLORER_URL +from operate.operate_types import Chain +from operate.wallet.master import MasterWalletManager + + +BLOCK_CHUNK_SIZE = 5000 + + +class BridgeContractAdaptor(ABC): + """Adaptor class for bridge contract packages.""" + + def __init__( + self, + from_chain: str, + from_bridge: str, + to_chain: str, + to_bridge: str, + bridge_eta: int, + ) -> None: + """Initialize the bridge contract adaptor.""" + super().__init__() + self.from_chain = from_chain + self.from_bridge = from_bridge + self.to_chain = to_chain + self.to_bridge = to_bridge + self.bridge_eta = bridge_eta + + def can_handle_request(self, to_ledger_api: LedgerApi, params: t.Dict) -> bool: + """Returns 'true' if the contract adaptor can handle a request for 'params'.""" + from_chain = params["from"]["chain"] + from_token = Web3.to_checksum_address(params["from"]["token"]) + to_chain = params["to"]["chain"] + to_token = Web3.to_checksum_address(params["to"]["token"]) + + if from_chain != self.from_chain: + return False + + if to_chain != self.to_chain: + return False + + if from_token == ZERO_ADDRESS and to_token == ZERO_ADDRESS: + return True + + for token_map in ERC20_TOKENS: + if ( + Chain(from_chain) in token_map + and Chain(to_chain) in token_map + and token_map[Chain(from_chain)].lower() == from_token.lower() + and token_map[Chain(to_chain)].lower() == to_token.lower() + ): + return True + + return False + + @abstractmethod + def build_bridge_tx( + self, from_ledger_api: LedgerApi, bridge_request: BridgeRequest + ) -> JSONLike: + """Build bridge transaction.""" + raise NotImplementedError() + + @abstractmethod + def find_bridge_finalized_tx( + self, + from_ledger_api: LedgerApi, + to_ledger_api: LedgerApi, + bridge_request: BridgeRequest, + from_block: BlockIdentifier, + to_block: BlockIdentifier, + ) -> t.Optional[str]: + """Return the transaction hash of the event indicating bridge completion.""" + raise NotImplementedError() + + @abstractmethod + def get_explorer_link( + self, from_ledger_api: LedgerApi, bridge_request: BridgeRequest + ) -> t.Optional[str]: + """Get the explorer link for a transaction.""" + raise NotImplementedError() + + +class OptimismContractAdaptor(BridgeContractAdaptor): + """Adaptor class for Optimism contract packages.""" + + _l1_standard_bridge_contract = t.cast( + L1StandardBridge, + L1StandardBridge.from_dir( + directory=str(DATA_DIR / "contracts" / "l1_standard_bridge"), + ), + ) + _l2_standard_bridge_contract = t.cast( + L2StandardBridge, + L2StandardBridge.from_dir( + directory=str(DATA_DIR / "contracts" / "l2_standard_bridge"), + ), + ) + + _optimism_mintable_erc20_contract = t.cast( + OptimismMintableERC20, + OptimismMintableERC20.from_dir( + directory=str(DATA_DIR / "contracts" / "optimism_mintable_erc20"), + ), + ) + + def can_handle_request(self, to_ledger_api: LedgerApi, params: t.Dict) -> bool: + """Returns 'true' if the contract adaptor can handle a request for 'params'.""" + + from_token = Web3.to_checksum_address(params["from"]["token"]) + to_token = Web3.to_checksum_address(params["to"]["token"]) + + if to_token != ZERO_ADDRESS: + try: + l1_token = self._optimism_mintable_erc20_contract.l1_token( + ledger_api=to_ledger_api, + contract_address=to_token, + )["data"] + + if l1_token != from_token: + return False + except Exception: # pylint: disable=broad-except + return False + + return super().can_handle_request(to_ledger_api, params) + + def build_bridge_tx( + self, from_ledger_api: LedgerApi, bridge_request: BridgeRequest + ) -> JSONLike: + """Build bridge transaction.""" + from_address = bridge_request.params["from"]["address"] + from_token = bridge_request.params["from"]["token"] + to_address = bridge_request.params["to"]["address"] + to_token = bridge_request.params["to"]["token"] + to_amount = bridge_request.params["to"]["amount"] + from_bridge = self.from_bridge + extra_data = Web3.keccak(text=bridge_request.id) + + if from_token == ZERO_ADDRESS: + return self._l1_standard_bridge_contract.build_bridge_eth_to_tx( + ledger_api=from_ledger_api, + contract_address=from_bridge, + sender=from_address, + to=to_address, + amount=int(to_amount), + min_gas_limit=DEFAULT_BRIDGE_MIN_GAS_LIMIT, + extra_data=extra_data, + ) + + return self._l1_standard_bridge_contract.build_bridge_erc20_to_tx( + ledger_api=from_ledger_api, + contract_address=from_bridge, + sender=from_address, + local_token=from_token, + remote_token=to_token, + to=to_address, + amount=int(to_amount), + min_gas_limit=DEFAULT_BRIDGE_MIN_GAS_LIMIT, + extra_data=extra_data, + ) + + def find_bridge_finalized_tx( + self, + from_ledger_api: LedgerApi, + to_ledger_api: LedgerApi, + bridge_request: BridgeRequest, + from_block: BlockIdentifier, + to_block: BlockIdentifier, + ) -> t.Optional[str]: + """Return the transaction hash of the event indicating bridge completion.""" + from_address = bridge_request.params["from"]["address"] + from_token = bridge_request.params["from"]["token"] + to_address = bridge_request.params["to"]["address"] + to_token = bridge_request.params["to"]["token"] + to_amount = bridge_request.params["to"]["amount"] + to_bridge = self.to_bridge + extra_data = Web3.keccak(text=bridge_request.id) + + if from_token == ZERO_ADDRESS: + return self._l2_standard_bridge_contract.find_eth_bridge_finalized_tx( + ledger_api=to_ledger_api, + contract_address=to_bridge, + from_=from_address, + to=to_address, + amount=to_amount, + extra_data=extra_data, + from_block=from_block, + to_block=to_block, + ) + + return self._l2_standard_bridge_contract.find_erc20_bridge_finalized_tx( + ledger_api=to_ledger_api, + contract_address=to_bridge, + local_token=to_token, + remote_token=from_token, + from_=from_address, + to=to_address, + amount=to_amount, + extra_data=extra_data, + from_block=from_block, + to_block=to_block, + ) + + def get_explorer_link( + self, from_ledger_api: LedgerApi, bridge_request: BridgeRequest + ) -> t.Optional[str]: + """Get the explorer link for a transaction.""" + if not bridge_request.execution_data: + return None + + tx_hash = bridge_request.execution_data.from_tx_hash + if not tx_hash: + return None + + chain = Chain(bridge_request.params["from"]["chain"]) + url = EXPLORER_URL[chain]["tx"] + return url.format(tx_hash=tx_hash) + + +class OmnibridgeContractAdaptor(BridgeContractAdaptor): + """Adaptor class for Omnibridge contract packages.""" + + _foreign_omnibridge = t.cast( + ForeignOmnibridge, + ForeignOmnibridge.from_dir( + directory=str(DATA_DIR / "contracts" / "foreign_omnibridge"), + ), + ) + + _home_omnibridge = t.cast( + HomeOmnibridge, + HomeOmnibridge.from_dir( + directory=str(DATA_DIR / "contracts" / "home_omnibridge"), + ), + ) + + def can_handle_request(self, to_ledger_api: LedgerApi, params: t.Dict) -> bool: + """Returns 'true' if the contract adaptor can handle a request for 'params'.""" + from_token = Web3.to_checksum_address(params["from"]["token"]) + if from_token == ZERO_ADDRESS: + return False + + return super().can_handle_request(to_ledger_api, params) + + def build_bridge_tx( + self, from_ledger_api: LedgerApi, bridge_request: BridgeRequest + ) -> JSONLike: + """Build bridge transaction.""" + from_address = bridge_request.params["from"]["address"] + from_token = bridge_request.params["from"]["token"] + to_address = bridge_request.params["to"]["address"] + to_amount = bridge_request.params["to"]["amount"] + from_bridge = self.from_bridge + + if from_token == ZERO_ADDRESS: + raise NotImplementedError( + f"{self.__class__.__name__} does not support bridge native tokens." + ) + + return self._foreign_omnibridge.build_relay_tokens_tx( + ledger_api=from_ledger_api, + contract_address=from_bridge, + sender=from_address, + token=from_token, + receiver=to_address, + amount=to_amount, + ) + + def find_bridge_finalized_tx( + self, + from_ledger_api: LedgerApi, + to_ledger_api: LedgerApi, + bridge_request: BridgeRequest, + from_block: BlockIdentifier, + to_block: BlockIdentifier, + ) -> t.Optional[str]: + """Return the transaction hash of the event indicating bridge completion.""" + from_token = bridge_request.params["from"]["token"] + to_address = bridge_request.params["to"]["address"] + to_token = bridge_request.params["to"]["token"] + to_amount = bridge_request.params["to"]["amount"] + to_bridge = self.to_bridge + + if from_token == ZERO_ADDRESS: + raise NotImplementedError( + f"{self.__class__.__name__} does not support bridge native tokens." + ) + + message_id = self.get_message_id( + from_ledger_api=from_ledger_api, + bridge_request=bridge_request, + ) + + if not message_id: + raise RuntimeError( + f"Cannot find 'messageId' for bridge request {bridge_request.id}." + ) + + return self._home_omnibridge.find_tokens_bridged_tx( + ledger_api=to_ledger_api, + contract_address=to_bridge, + token=to_token, + recipient=to_address, + value=to_amount, + message_id=message_id, + from_block=from_block, + to_block=to_block, + ) + + def get_message_id( + self, from_ledger_api: LedgerApi, bridge_request: BridgeRequest + ) -> t.Optional[bytes]: + """Get the bridge message id.""" + if not bridge_request.execution_data: + return None + + if not bridge_request.execution_data.from_tx_hash: + return None + + if ( + bridge_request.execution_data.provider_data + and "message_id" in bridge_request.execution_data.provider_data + ): + return bridge_request.execution_data.provider_data.get("message_id", None) + + from_address = bridge_request.params["from"]["address"] + from_token = bridge_request.params["from"]["token"] + from_tx_hash = bridge_request.execution_data.from_tx_hash + to_amount = bridge_request.params["to"]["amount"] + from_bridge = self.from_bridge + + message_id = self._foreign_omnibridge.get_tokens_bridging_initiated_message_id( + ledger_api=from_ledger_api, + contract_address=from_bridge, + tx_hash=from_tx_hash, + token=from_token, + sender=from_address, + value=to_amount, + ) + + if not bridge_request.execution_data.provider_data: + bridge_request.execution_data.provider_data = {} + + bridge_request.execution_data.provider_data["message_id"] = message_id + return message_id + + def get_explorer_link( + self, from_ledger_api: LedgerApi, bridge_request: BridgeRequest + ) -> t.Optional[str]: + """Get the explorer link for a transaction.""" + message_id = self.get_message_id(from_ledger_api, bridge_request) + if not message_id: + return None + return f"https://bridge.gnosischain.com/bridge-explorer/transaction/0x{message_id.hex()}" + + +class NativeBridgeProvider(BridgeProvider): + """Native bridge provider""" + + def __init__( + self, + bridge_contract_adaptor: BridgeContractAdaptor, + provider_id: str, + wallet_manager: MasterWalletManager, + logger: t.Optional[logging.Logger] = None, + ) -> None: + """Initialize the bridge provider.""" + self.bridge_contract_adaptor = bridge_contract_adaptor + super().__init__( + wallet_manager=wallet_manager, provider_id=provider_id, logger=logger + ) + + def can_handle_request(self, params: t.Dict) -> bool: + """Returns 'true' if the bridge can handle a request for 'params'.""" + + if not super().can_handle_request(params): + return False + + to_chain = params["to"]["chain"] + chain = Chain(to_chain) + wallet = self.wallet_manager.load(chain.ledger_type) + to_ledger_api = wallet.ledger_api(chain) + + if not self.bridge_contract_adaptor.can_handle_request(to_ledger_api, params): + return False + + return True + + def description(self) -> str: + """Get a human-readable description of the bridge provider.""" + return f"Native bridge provider ({self.bridge_contract_adaptor.__class__.__name__})." + + def quote(self, bridge_request: BridgeRequest) -> None: + """Update the request with the quote.""" + self._validate(bridge_request) + + if bridge_request.status not in ( + BridgeRequestStatus.CREATED, + BridgeRequestStatus.QUOTE_DONE, + BridgeRequestStatus.QUOTE_FAILED, + ): + raise RuntimeError( + f"Cannot quote bridge request {bridge_request.id} with status {bridge_request.status}." + ) + + if bridge_request.execution_data: + raise RuntimeError( + f"Cannot quote bridge request {bridge_request.id}: execution already present." + ) + + to_amount = bridge_request.params["to"]["amount"] + bridge_eta = self.bridge_contract_adaptor.bridge_eta + + message = None + if to_amount == 0: + self.logger.info(f"[NATIVE BRIDGE] {MESSAGE_QUOTE_ZERO}") + bridge_eta = 0 + message = MESSAGE_QUOTE_ZERO + + quote_data = QuoteData( + bridge_eta=bridge_eta, + elapsed_time=0, + message=message, + provider_data=None, + timestamp=int(time.time()), + ) + bridge_request.quote_data = quote_data + bridge_request.status = BridgeRequestStatus.QUOTE_DONE + + def _get_approve_tx(self, bridge_request: BridgeRequest) -> t.Optional[t.Dict]: + """Get the approve transaction.""" + self.logger.info( + f"[NATIVE BRIDGE] Get appprove transaction for bridge request {bridge_request.id}." + ) + + if bridge_request.params["to"]["amount"] == 0: + return None + + quote_data = bridge_request.quote_data + if not quote_data: + return None + + from_address = bridge_request.params["from"]["address"] + from_token = bridge_request.params["from"]["token"] + to_amount = bridge_request.params["to"]["amount"] + from_bridge = self.bridge_contract_adaptor.from_bridge + from_ledger_api = self._from_ledger_api(bridge_request) + + if from_token == ZERO_ADDRESS: + return None + + approve_tx = registry_contracts.erc20.get_approve_tx( + ledger_api=from_ledger_api, + contract_address=from_token, + spender=from_bridge, + sender=from_address, + amount=to_amount, + ) + approve_tx["gas"] = 200_000 # TODO backport to ERC20 contract as default + BridgeProvider._update_with_gas_pricing(approve_tx, from_ledger_api) + BridgeProvider._update_with_gas_estimate(approve_tx, from_ledger_api) + approve_tx["gas"] = ceil(approve_tx["gas"] * GAS_ESTIMATE_BUFFER) + return approve_tx + + def _get_bridge_tx(self, bridge_request: BridgeRequest) -> t.Optional[t.Dict]: + """Get the bridge transaction.""" + self.logger.info( + f"[NATIVE BRIDGE] Get bridge transaction for bridge request {bridge_request.id}." + ) + + if bridge_request.params["to"]["amount"] == 0: + return None + + quote_data = bridge_request.quote_data + if not quote_data: + return None + + from_ledger_api = self._from_ledger_api(bridge_request) + bridge_tx = self.bridge_contract_adaptor.build_bridge_tx( + from_ledger_api=from_ledger_api, bridge_request=bridge_request + ) + + BridgeProvider._update_with_gas_pricing(bridge_tx, from_ledger_api) + BridgeProvider._update_with_gas_estimate(bridge_tx, from_ledger_api) + bridge_tx["gas"] = ceil(bridge_tx["gas"] * GAS_ESTIMATE_BUFFER) + return bridge_tx + + def _update_execution_status(self, bridge_request: BridgeRequest) -> None: + """Update the execution status.""" + + if bridge_request.status != BridgeRequestStatus.EXECUTION_PENDING: + return + + self.logger.info( + f"[NATIVE BRIDGE] Updating execution status for bridge request {bridge_request.id}." + ) + + if not bridge_request.execution_data: + raise RuntimeError( + f"Cannot update bridge request {bridge_request.id}: execution data not present." + ) + + execution_data = bridge_request.execution_data + if not execution_data.from_tx_hash: + execution_data.message = ( + f"{MESSAGE_EXECUTION_FAILED} missing transaction hash." + ) + bridge_request.status = BridgeRequestStatus.EXECUTION_FAILED + return + + bridge_eta = self.bridge_contract_adaptor.bridge_eta + + try: + from_ledger_api = self._from_ledger_api(bridge_request) + from_w3 = from_ledger_api.api + + from_tx_hash = execution_data.from_tx_hash + receipt = from_w3.eth.get_transaction_receipt(from_tx_hash) + if receipt.status == 0: + execution_data.message = MESSAGE_EXECUTION_FAILED_REVERTED + bridge_request.status = BridgeRequestStatus.EXECUTION_FAILED + return + + # Get the timestamp of the bridge_tx on the 'from' chain + bridge_tx_receipt = from_w3.eth.get_transaction_receipt(from_tx_hash) + bridge_tx_block = from_w3.eth.get_block(bridge_tx_receipt.blockNumber) + bridge_tx_ts = bridge_tx_block.timestamp + + # Find the event on the 'to' chain + to_ledger_api = self._to_ledger_api(bridge_request) + to_w3 = to_ledger_api.api + starting_block = self._find_block_before_timestamp(to_w3, bridge_tx_ts) + starting_block_ts = to_w3.eth.get_block(starting_block).timestamp + latest_block = to_w3.eth.block_number + + for from_block in range(starting_block, latest_block + 1, BLOCK_CHUNK_SIZE): + to_block = min(from_block + BLOCK_CHUNK_SIZE - 1, latest_block) + + to_tx_hash = self.bridge_contract_adaptor.find_bridge_finalized_tx( + from_ledger_api=from_ledger_api, + to_ledger_api=to_ledger_api, + bridge_request=bridge_request, + from_block=from_block, + to_block=to_block, + ) + + if to_tx_hash: + self.logger.info( + f"[NATIVE BRIDGE] Execution done for {bridge_request.id}." + ) + execution_data.message = None + execution_data.to_tx_hash = to_tx_hash + execution_data.elapsed_time = BridgeProvider._tx_timestamp( + to_tx_hash, to_ledger_api + ) - BridgeProvider._tx_timestamp(from_tx_hash, from_ledger_api) + bridge_request.status = BridgeRequestStatus.EXECUTION_DONE + return + + last_block_ts = to_w3.eth.get_block(to_block).timestamp + if last_block_ts > starting_block_ts + bridge_eta * 2: + self.logger.info( + f"[NATIVE BRIDGE] Execution failed for {bridge_request.id}: bridge exceeds 2*ETA." + ) + execution_data.message = MESSAGE_EXECUTION_FAILED_ETA + bridge_request.status = BridgeRequestStatus.EXECUTION_FAILED + return + + except Exception as e: + self.logger.error(f"Error updating execution status: {e}") + import traceback + + traceback.print_exc() + execution_data.message = f"{MESSAGE_EXECUTION_FAILED} {str(e)}" + bridge_request.status = BridgeRequestStatus.EXECUTION_FAILED + + @staticmethod + def _find_block_before_timestamp(w3: Web3, timestamp: int) -> int: + """Returns the largest block number of the block before `timestamp`.""" + latest = w3.eth.block_number + low, high = 0, latest + best = 0 + while low <= high: + mid = (low + high) // 2 + block = w3.eth.get_block(mid) + if block["timestamp"] < timestamp: + best = mid + low = mid + 1 + else: + high = mid - 1 + return best + + def _get_explorer_link(self, bridge_request: BridgeRequest) -> t.Optional[str]: + """Get the explorer link for a transaction.""" + from_ledger_api = self._from_ledger_api(bridge_request) + return self.bridge_contract_adaptor.get_explorer_link( + from_ledger_api=from_ledger_api, bridge_request=bridge_request + ) diff --git a/operate/cli.py b/operate/cli.py index 24a44a1e..87153adc 100644 --- a/operate/cli.py +++ b/operate/cli.py @@ -27,6 +27,7 @@ import typing as t import uuid from concurrent.futures import ThreadPoolExecutor +from http import HTTPStatus from pathlib import Path from types import FrameType @@ -43,6 +44,7 @@ from operate import services from operate.account.user import UserAccount +from operate.bridge.bridge import BridgeManager from operate.constants import KEY, KEYS, OPERATE_HOME, SERVICES, ZERO_ADDRESS from operate.ledger.profiles import ( DEFAULT_MASTER_EOA_FUNDS, @@ -176,6 +178,15 @@ def wallet_manager(self) -> MasterWalletManager: manager.setup() return manager + @property + def bridge_manager(self) -> BridgeManager: + """Load master wallet.""" + manager = BridgeManager( + path=self._path / "bridge", + wallet_manager=self.wallet_manager, + ) + return manager + def setup(self) -> None: """Make the root directory.""" self._path.mkdir(exist_ok=True) @@ -944,6 +955,90 @@ async def _withdraw_onchain(request: Request) -> JSONResponse: return JSONResponse(content={"error": None}) + @app.post("/api/bridge/bridge_refill_requirements") + @with_retries + async def _bridge_refill_requirements(request: Request) -> JSONResponse: + """Get the bridge refill requirements.""" + if operate.password is None: + return USER_NOT_LOGGED_IN_ERROR + + try: + data = await request.json() + output = operate.bridge_manager.bridge_refill_requirements( + requests_params=data["bridge_requests"], + force_update=data.get("force_update", False), + ) + + return JSONResponse( + content=output, + status_code=HTTPStatus.OK, + ) + except ValueError as e: + return JSONResponse( + content={"error": str(e)}, status_code=HTTPStatus.BAD_REQUEST + ) + except Exception as e: # pylint: disable=broad-except + return JSONResponse( + content={"error": str(e), "traceback": traceback.format_exc()}, + status_code=HTTPStatus.INTERNAL_SERVER_ERROR, + ) + + @app.post("/api/bridge/execute") + @with_retries + async def _bridge_execute(request: Request) -> JSONResponse: + """Get the bridge refill requirements.""" + if operate.password is None: + return USER_NOT_LOGGED_IN_ERROR + + try: + data = await request.json() + output = operate.bridge_manager.execute_bundle(bundle_id=data["id"]) + + return JSONResponse( + content=output, + status_code=HTTPStatus.OK, + ) + except ValueError as e: + return JSONResponse( + content={"error": str(e)}, status_code=HTTPStatus.BAD_REQUEST + ) + except Exception as e: # pylint: disable=broad-except + return JSONResponse( + content={"error": str(e), "traceback": traceback.format_exc()}, + status_code=HTTPStatus.INTERNAL_SERVER_ERROR, + ) + + @app.get("/api/bridge/last_executed_bundle_id") + @with_retries + async def _bridge_last_executed_bundle_id(request: Request) -> t.List[t.Dict]: + """Get last executed bundle id.""" + content = {"id": operate.bridge_manager.last_executed_bundle_id()} + return JSONResponse(content=content, status_code=HTTPStatus.OK) + + @app.get("/api/bridge/status/{id}") + @with_retries + async def _bridge_status(request: Request) -> JSONResponse: + """Get the bridge refill requirements.""" + + quote_bundle_id = request.path_params["id"] + + try: + output = operate.bridge_manager.get_status_json(bundle_id=quote_bundle_id) + + return JSONResponse( + content=output, + status_code=HTTPStatus.OK, + ) + except ValueError as e: + return JSONResponse( + content={"error": str(e)}, status_code=HTTPStatus.BAD_REQUEST + ) + except Exception as e: # pylint: disable=broad-except + return JSONResponse( + content={"error": str(e), "traceback": traceback.format_exc()}, + status_code=HTTPStatus.INTERNAL_SERVER_ERROR, + ) + return app diff --git a/operate/data/README.md b/operate/data/README.md index 2161d3fc..9f4365d6 100644 --- a/operate/data/README.md +++ b/operate/data/README.md @@ -1,11 +1,19 @@ # Contracts Data -This directory contains packages that are used in the middleware. +Reused packages from other repositories: - `contracts/staking_token` is copied from [valory/trader](https://github.com/valory-xyz/trader/tree/main/packages/valory/contracts/staking_token) - `contracts/mech_activity` is copied from [valory/trader](https://github.com/valory-xyz/trader/tree/main/packages/valory/contracts/mech_activity) - `contracts/uniswap_v2_erc20` is copied from [valory/optimus-quickstart](https://github.com/valory-xyz/optimus-quickstart/tree/main/operate/data/contracts/uniswap_v2_erc20) -- `contracts/requester_activity_checker` is new from this repository. -- `contracts/dual_staking_token` is new from this repository. + +New packages from this repository: + +- `contracts/dual_staking_token` +- `contracts/foreign_omnibridge` +- `contracts/home_omnibridge` +- `contracts/l1_standard_bridge` +- `contracts/l2_standard_bridge` +- `contracts/optimism_mintable_erc20` +- `contracts/requester_activity_checker` TODO: Have a better way to import and reuse packages in the middleware. diff --git a/operate/data/contracts/foreign_omnibridge/__init__.py b/operate/data/contracts/foreign_omnibridge/__init__.py new file mode 100644 index 00000000..786a23a1 --- /dev/null +++ b/operate/data/contracts/foreign_omnibridge/__init__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2024 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ + +"""This module contains the support resources for the `ForeignOmnibridge` contract.""" diff --git a/operate/data/contracts/foreign_omnibridge/build/ForeignOmnibridge.json b/operate/data/contracts/foreign_omnibridge/build/ForeignOmnibridge.json new file mode 100644 index 00000000..6394e63d --- /dev/null +++ b/operate/data/contracts/foreign_omnibridge/build/ForeignOmnibridge.json @@ -0,0 +1,1372 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "ForeignOmnibridge", + "sourceName": "ForeignOmnibridge.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "_suffix", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newLimit", + "type": "uint256" + } + ], + "name": "DailyLimitChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newLimit", + "type": "uint256" + } + ], + "name": "ExecutionDailyLimitChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "messageId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "FailedMessageFixed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "nativeToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "bridgedToken", + "type": "address" + } + ], + "name": "NewTokenRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "messageId", + "type": "bytes32" + } + ], + "name": "TokensBridged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "messageId", + "type": "bytes32" + } + ], + "name": "TokensBridgingInitiated", + "type": "event" + }, + { + "inputs": [], + "name": "bridgeContract", + "outputs": [ + { + "internalType": "contract IAMB", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_nativeToken", + "type": "address" + } + ], + "name": "bridgedTokenAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "claimTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_bridgedToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "claimTokensFromTokenContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "dailyLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "_decimals", + "type": "uint8" + }, + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + } + ], + "name": "deployAndHandleBridgedTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "_decimals", + "type": "uint8" + }, + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "deployAndHandleBridgedTokensAndCall", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "disableInterest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "executionDailyLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "executionMaxPerTx", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_messageId", + "type": "bytes32" + } + ], + "name": "fixFailedMessage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "fixMediatorBalance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getBridgeInterfacesVersion", + "outputs": [ + { + "internalType": "uint64", + "name": "major", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "minor", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "patch", + "type": "uint64" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getBridgeMode", + "outputs": [ + { + "internalType": "bytes4", + "name": "_data", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentDay", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + } + ], + "name": "handleBridgedTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "handleBridgedTokensAndCall", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + } + ], + "name": "handleNativeTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "handleNativeTokensAndCall", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_bridgeContract", + "type": "address" + }, + { + "internalType": "address", + "name": "_mediatorContract", + "type": "address" + }, + { + "internalType": "uint256[3]", + "name": "_dailyLimitMaxPerTxMinPerTxArray", + "type": "uint256[3]" + }, + { + "internalType": "uint256[2]", + "name": "_executionDailyLimitExecutionMaxPerTxArray", + "type": "uint256[2]" + }, + { + "internalType": "uint256", + "name": "_requestGasLimit", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "internalType": "address", + "name": "_tokenFactory", + "type": "address" + } + ], + "name": "initialize", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_impl", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_minCashThreshold", + "type": "uint256" + } + ], + "name": "initializeInterest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "interestImplementation", + "outputs": [ + { + "internalType": "contract IInterestImplementation", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "invest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "isBridgedTokenDeployAcknowledged", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isInitialized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "isRegisteredAsNativeToken", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "isTokenRegistered", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "maxAvailablePerTx", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "maxPerTx", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "mediatorBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mediatorContractOnOtherSide", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_messageId", + "type": "bytes32" + } + ], + "name": "messageFixed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_tokenFactory", + "type": "address" + }, + { + "internalType": "address", + "name": "_interestImplementation", + "type": "address" + } + ], + "name": "migrateTo_3_3_0", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "minCashThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "minPerTx", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_bridgedToken", + "type": "address" + } + ], + "name": "nativeTokenAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "onTokenTransfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC677", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + } + ], + "name": "relayTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC677", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + } + ], + "name": "relayTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC677", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "relayTokensAndCall", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_messageId", + "type": "bytes32" + } + ], + "name": "requestFailedMessageFix", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "requestGasLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_bridgeContract", + "type": "address" + } + ], + "name": "setBridgeContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_nativeToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_bridgedToken", + "type": "address" + } + ], + "name": "setCustomTokenAddressPair", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_dailyLimit", + "type": "uint256" + } + ], + "name": "setDailyLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_dailyLimit", + "type": "uint256" + } + ], + "name": "setExecutionDailyLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_maxPerTx", + "type": "uint256" + } + ], + "name": "setExecutionMaxPerTx", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_maxPerTx", + "type": "uint256" + } + ], + "name": "setMaxPerTx", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_mediatorContract", + "type": "address" + } + ], + "name": "setMediatorContractOnOtherSide", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_minCashThreshold", + "type": "uint256" + } + ], + "name": "setMinCashThreshold", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_minPerTx", + "type": "uint256" + } + ], + "name": "setMinPerTx", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_gasLimit", + "type": "uint256" + } + ], + "name": "setRequestGasLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_tokenFactory", + "type": "address" + } + ], + "name": "setTokenFactory", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "tokenFactory", + "outputs": [ + { + "internalType": "contract TokenFactory", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_day", + "type": "uint256" + } + ], + "name": "totalExecutedPerDay", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_day", + "type": "uint256" + } + ], + "name": "totalSpentPerDay", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withinExecutionLimit", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withinLimit", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106103a45760003560e01c80637837cf91116101e9578063c2173d431161010f578063db6fff8c116100ad578063f2fde38b1161007c578063f2fde38b14611081578063f3b83791146110a7578063f3f51415146110c4578063f50dace6146110ea576103a4565b8063db6fff8c14610ff5578063e77772fe14611021578063ec47de2a14611029578063f2c54fe814611055576103a4565b8063d0342acd116100e9578063d0342acd14610d99578063d522cfd714610dc7578063d740548114610f03578063d814b1d714610fc7576103a4565b8063c2173d4314610ca7578063c534576114610ccd578063cd59658314610d91576103a4565b8063a4b1c24311610187578063ab4f5dc511610156578063ab4f5dc514610c0d578063ad58bdd114610c43578063ae813e9f14610c79578063be3b625b14610c9f576103a4565b8063a4b1c24314610ad6578063a4b4b23314610afc578063a4c0ed3614610b28578063ab3a25d914610be1576103a4565b8063871c0760116101c3578063871c076014610a755780638da5cb5b14610a7d5780639a4a439514610a855780639cb7595a14610aa2576103a4565b80637837cf911461095f57806385df73bd1461098b578063867f7a4d146109b1576103a4565b80632c3500a6116102ce578063437764df1161026c57806364696f971161023b57806364696f97146108ad57806369ffa08a146108e55780636e5d6bea146109135780637610722f14610939576103a4565b8063437764df1461081f5780635726ff3014610844578063593399821461086a57806361c04f8414610887576103a4565b8063392e53cd116102a8578063392e53cd146107bd5780633a50bc87146107c55780633e6968b6146107f157806340f8dd86146107f9576103a4565b80632c3500a6146107025780632d70061f146107555780632f73a9f814610797576103a4565b8063107752381161034657806326aa101f1161031557806326aa101f14610594578063272255bb146105ba5780632803212f146105f05780632ae87cdd1461061c576103a4565b806310775238146104d2578063125e4cfb1461051257806316ef191314610548578063194153d31461056e576103a4565b806303f9c7931161038257806303f9c7931461043b5780630950d515146104615780630b26cf661461047e5780630b71a4a7146104a4576103a4565b806301e4f53a146103a957806301fcc1d3146103d7578063032f693f14610403575b600080fd5b6103d5600480360360408110156103bf57600080fd5b506001600160a01b038135169060200135611110565b005b6103d5600480360360408110156103ed57600080fd5b506001600160a01b03813516906020013561114f565b6104296004803603602081101561041957600080fd5b50356001600160a01b03166111ee565b60408051918252519081900360200190f35b6103d56004803603602081101561045157600080fd5b50356001600160a01b0316611246565b6103d56004803603602081101561047757600080fd5b5035611388565b6103d56004803603602081101561049457600080fd5b50356001600160a01b0316611431565b6103d5600480360360408110156104ba57600080fd5b506001600160a01b0381358116916020013516611445565b6104fe600480360360408110156104e857600080fd5b506001600160a01b03813516906020013561151a565b604080519115158252519081900360200190f35b6103d56004803603606081101561052857600080fd5b506001600160a01b0381358116916020810135909116906040013561158d565b6104296004803603602081101561055e57600080fd5b50356001600160a01b03166115c7565b6104296004803603602081101561058457600080fd5b50356001600160a01b0316611624565b6104fe600480360360208110156105aa57600080fd5b50356001600160a01b031661167f565b6103d5600480360360608110156105d057600080fd5b506001600160a01b03813581169160208101359091169060400135611692565b6103d56004803603604081101561060657600080fd5b506001600160a01b0381351690602001356116b5565b6103d5600480360360c081101561063257600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561065c57600080fd5b82018360208201111561066e57600080fd5b803590602001918460018302840111600160201b8311171561068f57600080fd5b919390929091602081019035600160201b8111156106ac57600080fd5b8201836020820111156106be57600080fd5b803590602001918460018302840111600160201b831117156106df57600080fd5b919350915060ff813516906001600160a01b036020820135169060400135611784565b6104fe600480360361014081101561071957600080fd5b506001600160a01b0381358116916020810135821691604082019160a081019160e08201359161010081013582169161012090910135166117ab565b61077b6004803603602081101561076b57600080fd5b50356001600160a01b031661197f565b604080516001600160a01b039092168252519081900360200190f35b6103d5600480360360208110156107ad57600080fd5b50356001600160a01b03166119e5565b6104fe6119f6565b6104fe600480360360408110156107db57600080fd5b506001600160a01b038135169060200135611a47565b610429611a9d565b6104296004803603602081101561080f57600080fd5b50356001600160a01b0316611aa6565b610827611b05565b604080516001600160e01b03199092168252519081900360200190f35b6104296004803603602081101561085a57600080fd5b50356001600160a01b0316611b10565b6104fe6004803603602081101561088057600080fd5b5035611b6c565b61077b6004803603602081101561089d57600080fd5b50356001600160a01b0316611bbf565b6103d5600480360360608110156108c357600080fd5b506001600160a01b038135811691602081013582169160409091013516611c28565b6103d5600480360360408110156108fb57600080fd5b506001600160a01b0381358116916020013516611cad565b6103d56004803603602081101561092957600080fd5b50356001600160a01b0316611ce4565b6104296004803603602081101561094f57600080fd5b50356001600160a01b0316611cf5565b6103d56004803603604081101561097557600080fd5b506001600160a01b038135169060200135611d4f565b61077b600480360360208110156109a157600080fd5b50356001600160a01b0316611e27565b6103d5600480360360808110156109c757600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610a0157600080fd5b820183602082011115610a1357600080fd5b803590602001918460018302840111600160201b83111715610a3457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611e86945050505050565b61077b611eb0565b61077b611f07565b6103d560048036036020811015610a9b57600080fd5b5035611f5e565b610aaa612153565b6040805167ffffffffffffffff9485168152928416602084015292168183015290519081900360600190f35b61042960048036036020811015610aec57600080fd5b50356001600160a01b031661215d565b6103d560048036036040811015610b1257600080fd5b506001600160a01b0381351690602001356121e2565b6104fe60048036036060811015610b3e57600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b811115610b6d57600080fd5b820183602082011115610b7f57600080fd5b803590602001918460018302840111600160201b83111715610ba057600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506121f4945050505050565b61042960048036036040811015610bf757600080fd5b506001600160a01b03813516906020013561225b565b6103d560048036036060811015610c2357600080fd5b506001600160a01b038135811691602081013590911690604001356122c1565b6103d560048036036060811015610c5957600080fd5b506001600160a01b038135811691602081013590911690604001356122fb565b6104fe60048036036020811015610c8f57600080fd5b50356001600160a01b0316612309565b610429612362565b6104fe60048036036020811015610cbd57600080fd5b50356001600160a01b03166123b0565b6103d560048036036080811015610ce357600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610d1d57600080fd5b820183602082011115610d2f57600080fd5b803590602001918460018302840111600160201b83111715610d5057600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506123dd945050505050565b61077b61241d565b6103d560048036036040811015610daf57600080fd5b506001600160a01b0381358116916020013516612474565b6103d5600480360360e0811015610ddd57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b811115610e0757600080fd5b820183602082011115610e1957600080fd5b803590602001918460018302840111600160201b83111715610e3a57600080fd5b919390929091602081019035600160201b811115610e5757600080fd5b820183602082011115610e6957600080fd5b803590602001918460018302840111600160201b83111715610e8a57600080fd5b9193909260ff833516926001600160a01b03602082013516926040820135929091608081019060600135600160201b811115610ec557600080fd5b820183602082011115610ed757600080fd5b803590602001918460018302840111600160201b83111715610ef857600080fd5b509092509050612533565b6103d560048036036080811015610f1957600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610f5357600080fd5b820183602082011115610f6557600080fd5b803590602001918460018302840111600160201b83111715610f8657600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506125a9945050505050565b6103d560048036036040811015610fdd57600080fd5b506001600160a01b03813581169160200135166125b5565b6103d56004803603604081101561100b57600080fd5b506001600160a01b0381351690602001356127e6565b61077b612883565b6103d56004803603604081101561103f57600080fd5b506001600160a01b0381351690602001356128da565b6104296004803603604081101561106b57600080fd5b506001600160a01b03813516906020013561297b565b6103d56004803603602081101561109757600080fd5b50356001600160a01b03166129e4565b6103d5600480360360208110156110bd57600080fd5b50356129f5565b610429600480360360208110156110da57600080fd5b50356001600160a01b0316612a06565b6103d56004803603602081101561110057600080fd5b50356001600160a01b0316612a5c565b61114b8233836000805b506040519080825280601f01601f191660200182016040528015611145576020820181803683370190505b50612ae8565b5050565b611157612c49565b6111608261167f565b61116957600080fd5b8015806111885750600081118015611188575061118582611aa6565b81105b61119157600080fd5b60408051700caf0cac6eae8d2dedc9ac2f0a0cae4a8f607b1b60208083019190915260609490941b6001600160601b0319166031820152815180820360250181526045909101825280519084012060009081529283905290912055565b60408051670dac2f0a0cae4a8f60c31b6020808301919091526001600160601b0319606085901b1660288301528251601c818403018152603c909201835281519181019190912060009081529081905220545b919050565b600061125182611e27565b905060006112e0826001600160a01b031663cff77444856040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156112a557600080fd5b505afa1580156112b9573d6000803e3d6000fd5b505050506040513d60208110156112cf57600080fd5b50516112da85611624565b90612c70565b905060006112ed84611b10565b90508082116112fb57600080fd5b8082036113126001600160a01b0386168583612cb9565b836001600160a01b031663b9b8c24686836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561136957600080fd5b505af115801561137d573d6000803e3d6000fd5b505050505050505050565b611390612d0b565b61139981611b6c565b156113a357600080fd5b60006113ae82612db5565b905060006113bb83612e0e565b905060006113c884612e6b565b90506113d384612eba565b6113de838383612f13565b604080516001600160a01b03808616825284166020820152808201839052905185917f07b5483b8e4bd8ea240a474d5117738350e7d431e3668c48a97910b0b397796a919081900360600190a250505050565b611439612c49565b61144281612f34565b50565b61144d612c49565b6114568161167f565b1561146057600080fd5b600061146b82611bbf565b6001600160a01b03161461147e57600080fd5b60006114898361197f565b6001600160a01b03161461149c57600080fd5b6114b16001600160a01b038216306001612fb0565b806001600160a01b03166342966c6860016040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156114f857600080fd5b505af115801561150c573d6000803e3d6000fd5b5050505061114b828261303c565b600080611538836115328661152d611a9d565b61225b565b90613137565b905060006115466000612a06565b11801561155b57508061155885612a06565b10155b801561156f575061156b846111ee565b8311155b8015611583575061157f8461215d565b8310155b9150505b92915050565b611595612d0b565b60006115a08461197f565b90506115ab8161167f565b6115b457600080fd5b6115c18160008585613191565b50505050565b60408051700caf0cac6eae8d2dedc9ac2f0a0cae4a8f607b1b60208083019190915260609390931b6001600160601b0319166031820152815180820360250181526045909101825280519083012060009081529182905290205490565b604080516e6d65646961746f7242616c616e636560881b60208083019190915260609390931b6001600160601b031916602f820152815180820360230181526043909101825280519083012060009081529182905290205490565b60008061168b8361215d565b1192915050565b61169a612d0b565b6116a38361322e565b6116b08360018484613191565b505050565b6116bd612c49565b6116c68261167f565b6116cf57600080fd5b6116d8826111ee565b8111806116e3575080155b6116ec57600080fd5b604080516919185a5b1e531a5b5a5d60b21b6020808301919091526001600160601b0319606086901b16602a8301528251601e818403018152603e83018085528151918301919091206000908152918290529083902084905583905290516001600160a01b038416917fca0b3dabefdbd8c72c0a9cf4a6e9d107da897abf036ef3f3f3b010cdd25941599190819003605e0190a25050565b61178c612d0b565b600061179c8989898989896132ea565b905061137d8160008585613191565b60408051600481526024810182526020810180516001600160e01b03166337ef410160e11b1781529151815160009384936060933093919290918291908083835b6020831061180b5780518252601f1990920191602091820191016117ec565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d806000811461186b576040519150601f19603f3d011682016040523d82523d6000602084013e611870565b606091505b50915091508115806118ac5750805160201480156118ac575080806020019051602081101561189e57600080fd5b50516001600160a01b031633145b806118b657503330145b6118bf57600080fd5b6118c76119f6565b156118d157600080fd5b6118da8a612f34565b6118e389613638565b61191760008960038060200260405190810160405280929190826003602002808284376000920191909152506136a2915050565b60408051808201825261194691600091908a9060029083908390808284376000920191909152506137f6915050565b61194f866138e5565b61195885613946565b61196184613a0e565b611969613a8a565b6119716119f6565b9a9950505050505050505050565b604080516f686f6d65546f6b656e4164647265737360801b60208083019190915260609390931b6001600160601b03191660308201528151808203602401815260449091018252805190830120600090815260029092529020546001600160a01b031690565b6119ed612c49565b61144281613a0e565b7f0a6f646cd611241d8073675e00d1a1ff700fbf1b53fcf473de56d1e6e4b714ba60005260046020527f078d888f9b66f3f8bfa10909e31f1e16240db73449f0500afdbbe3a70da457cc5460ff1690565b600080611a5f8361153286611a5a611a9d565b61297b565b90506000611a6d6000611aa6565b118015611a82575080611a7f85611aa6565b10155b80156115835750611a92846115c7565b909211159392505050565b62015180420490565b6040805172195e1958dd5d1a5bdb91185a5b1e531a5b5a5d606a1b60208083019190915260609390931b6001600160601b0319166033820152815180820360270181526047909101825280519083012060009081529182905290205490565b6358a8b61360e11b90565b604080516f1b5a5b90d85cda151a1c995cda1bdb1960821b60208083019190915260609390931b6001600160601b0319166030820152815180820360240181526044909101825280519083012060009081529182905290205490565b604080516b1b595cdcd859d9519a5e195960a21b602080830191909152602c80830185905283518084039091018152604c909201835281519181019190912060009081526004909152205460ff16919050565b6040805172666f726569676e546f6b656e4164647265737360681b60208083019190915260609390931b6001600160601b03191660338201528151808203602701815260479091018252805190830120600090815260029092529020546001600160a01b031690565b611c30613ae1565b826001600160a01b03166369ffa08a83836040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b0316815260200192505050600060405180830381600087803b158015611c9057600080fd5b505af1158015611ca4573d6000803e3d6000fd5b50505050505050565b611cb5613ae1565b6001600160a01b0382161580611cd15750611ccf8261167f565b155b611cda57600080fd5b61114b8282613b5a565b611cec612c49565b61144281613638565b600080611d01836111ee565b90506000611d0e84612a06565b90506000611d1e8561152d611a9d565b90506000818311611d30576000611d34565b8183035b9050808410611d435780611d45565b835b9695505050505050565b611d57612c49565b611d608261167f565b611d6957600080fd5b611d72826115c7565b811180611d7d575080155b611d8657600080fd5b6040805172195e1958dd5d1a5bdb91185a5b1e531a5b5a5d606a1b6020808301919091526001600160601b0319606086901b16603383015282516027818403018152604783018085528151918301919091206000908152918290529083902084905583905290516001600160a01b038416917f4c177b42dbe934b3abbc0208c11a42e46589983431616f1710ab19969c5ed62e919081900360670190a25050565b604080516b1a5b9d195c995cdd125b5c1b60a21b60208083019190915260609390931b6001600160601b031916602c8201528151808203840181529082018252805190830120600090815260029092529020546001600160a01b031690565b611e8e612d0b565b611e978461322e565b611ea48460018585613191565b6115c183858484613b94565b7f98aa806e31e94a687a31c65769cb99670064dd7f5a87526da075c5fb4eab988060005260026020527f0c1206883be66049a02d4937078367c00b3d71dd1a9465df969363c6ddeac96d546001600160a01b031690565b7f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c060005260026020527fb7802e97e87ef2842a6cce7da7ffaeaedaa2f61a6a7870b23d9d01fc9b73712e546001600160a01b031690565b6000611f6861241d565b9050806001600160a01b031663cb08a10c836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611fae57600080fd5b505afa158015611fc2573d6000803e3d6000fd5b505050506040513d6020811015611fd857600080fd5b505115611fe457600080fd5b306001600160a01b0316816001600160a01b0316633f9a8e7e846040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561203257600080fd5b505afa158015612046573d6000803e3d6000fd5b505050506040513d602081101561205c57600080fd5b50516001600160a01b03161461207157600080fd5b612079611eb0565b6001600160a01b0316816001600160a01b0316634a610b04846040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156120c657600080fd5b505afa1580156120da573d6000803e3d6000fd5b505050506040513d60208110156120f057600080fd5b50516001600160a01b03161461210557600080fd5b6040805160248082018590528251808303909101815260449091019091526020810180516001600160e01b0316630950d51560e01b9081179091529061214c816001613d01565b5050505050565b6003806001909192565b60408051670dad2dca0cae4a8f60c31b6020808301919091526001600160601b0319606085901b1660288301528251601c818403018152603c9092018352815191810191909120600090815290819052908120546001600160a01b0383166121c6579050611241565b600081116121d55760006121d8565b60015b60ff169392505050565b6121ea612c49565b61114b8282613e0c565b60006121fe613e68565b61225157604080516000815260208101909152825185906014116122415761222584613e8d565b9050601484511115612241578351601319016014850190815291505b61224e3387838886613e94565b50505b5060019392505050565b604080516f746f74616c5370656e7450657244617960801b60208083019190915260609490941b6001600160601b031916603082015260448082019390935281518082039093018352606401815281519183019190912060009081529182905290205490565b6122c9612c49565b60006122d484611e27565b6001600160a01b0316146122e757600080fd5b6122f18383613f2d565b6116b08382613e0c565b6116b083838360008061111a565b604080516861636b4465706c6f7960b81b60208083019190915260609390931b6001600160601b03191660298201528151808203601d018152603d90910182528051908301206000908152600490925290205460ff1690565b7f2dfd6c9f781bb6bbb5369c114e949b69ebb440ef3d4dd6b2836225eb1dc3a2be60009081526020527f2de0d2cdc19d356cb53b5984f91bfd3b31fe0c678a0d190a6db39274bb34753f5490565b60006123bb8261167f565b8015611587575060006123cd83611bbf565b6001600160a01b03161492915050565b6123e5612d0b565b60006123f08561197f565b90506123fb8161167f565b61240457600080fd5b6124118160008686613191565b61214c84828585613b94565b7f811bbb11e8899da471f0e69a3ed55090fc90215227fc5fb1cb0d6e962ea7b74f60005260026020527fb4ed64697d3ef8518241966f7c6f28b0d72f20f51198717d198d2d55076c593d546001600160a01b031690565b61247c613ae1565b806001600160a01b03811661249057600080fd5b612499836123b0565b6124a257600080fd5b60006124ad84614033565b9050600081116124bc57600080fd5b60006124c785611cf5565b9050600081116124d657600080fd5b808211156124e2578091505b6124f4856124ee611a9d565b84614131565b60408051600080825260208201909252606091612516918890889087906141af565b90506000612525826001613d01565b9050611ca48188888761482a565b61253b612d0b565b600061254b8b8b8b8b8b8b6132ea565b905061255a8160008787613191565b61259c85828686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613b9492505050565b5050505050505050505050565b6115c184848484612ae8565b7fd814b1d787b8a2d93a1c320d66800a58a03ed3bf12b285ec5ec1e0e26d6550cc600081905260046020527f612ef5ed0e5e2bed1afa8019b1ae0542ab321409196a5627628d39f86fff869a5460ff161561260f57600080fd5b61261883613a0e565b612624621e84806138e5565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48650246139ca80061264a8285613f2d565b6126548282613e0c565b600061265f83611624565b905081811161266d57600080fd5b8181036126846001600160a01b0385168783612cb9565b856001600160a01b031663b9b8c24685836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156126db57600080fd5b505af11580156126ef573d6000803e3d6000fd5b5050505073dac17f958d2ee523a2206206994597c13d831ec7935064ae9f7bcc00925061271c8487613f2d565b6127268484613e0c565b61272f84611624565b915082821161273d57600080fd5b508181036127556001600160a01b0385168783612cb9565b856001600160a01b031663b9b8c24685836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156127ac57600080fd5b505af11580156127c0573d6000803e3d6000fd5b50505060009586525050600460205250506040909120805460ff19166001179055505050565b6127ee612c49565b6127f78261167f565b61280057600080fd5b80158061282657506128118261215d565b81118015612826575061282382612a06565b81105b61282f57600080fd5b60408051670dac2f0a0cae4a8f60c31b60208083019190915260609490941b6001600160601b03191660288201528151808203601c018152603c909101825280519084012060009081529283905290912055565b7f269c5905f777ee6391c7a361d17039a7d62f52ba9fffeb98c5ade342705731a360005260026020527f15c764a0cd4bb3d72a49abedd3d6793c3b93c0d57f43174a348b443be86f79c1546001600160a01b031690565b6128e2612c49565b6128eb8261167f565b6128f457600080fd5b60008111801561290b575061290882612a06565b81105b801561291e575061291b826111ee565b81105b61292757600080fd5b60408051670dad2dca0cae4a8f60c31b60208083019190915260609490941b6001600160601b03191660288201528151808203601c018152603c909101825280519084012060009081529283905290912055565b6040805172746f74616c457865637574656450657244617960681b60208083019190915260609490941b6001600160601b031916603382015260478082019390935281518082039093018352606701815281519183019190912060009081529182905290205490565b6129ec612c49565b61144281613946565b6129fd612c49565b611442816138e5565b604080516919185a5b1e531a5b5a5d60b21b60208083019190915260609390931b6001600160601b031916602a8201528151808203601e018152603e909101825280519083012060009081529182905290205490565b612a64612c49565b612a6d81611e27565b6001600160a01b031663f3fef3a3826000196040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015612ac557600080fd5b505af1158015612ad9573d6000803e3d6000fd5b50505050611442816000613f2d565b612af0613e68565b15612afa57600080fd5b6000846001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015612b4957600080fd5b505afa158015612b5d573d6000803e3d6000fd5b505050506040513d6020811015612b7357600080fd5b50519050612b81600161489a565b612b966001600160a01b0386163330866148be565b612ba0600061489a565b6000612c2582876001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015612bf357600080fd5b505afa158015612c07573d6000803e3d6000fd5b505050506040513d6020811015612c1d57600080fd5b505190612c70565b905083811115612c3457600080fd5b612c418633878487613e94565b505050505050565b612c51611f07565b6001600160a01b0316336001600160a01b031614612c6e57600080fd5b565b6000612cb283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614918565b9392505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526116b09084906149af565b6000612d1561241d565b9050336001600160a01b03821614612d2c57600080fd5b612d34611eb0565b6001600160a01b0316816001600160a01b031663d67bdd256040518163ffffffff1660e01b815260040160206040518083038186803b158015612d7657600080fd5b505afa158015612d8a573d6000803e3d6000fd5b505050506040513d6020811015612da057600080fd5b50516001600160a01b03161461144257600080fd5b604080516b36b2b9b9b0b3b2aa37b5b2b760a11b602080830191909152602c80830185905283518084039091018152604c90920183528151918101919091206000908152600290915220546001600160a01b0316919050565b604080516f1b595cdcd859d9549958da5c1a595b9d60821b602080830191909152603080830185905283518084039091018152605090920183528151918101919091206000908152600290915220546001600160a01b0316919050565b604080516b6d65737361676556616c756560a01b602080830191909152602c80830185905283518084039091018152604c90920183528151918101919091206000908152908190522054919050565b604080516b1b595cdcd859d9519a5e195960a21b602080830191909152602c8083019490945282518083039094018452604c9091018252825192810192909220600090815260049092529020805460ff19166001179055565b6116b06000612f2185611bbf565b6001600160a01b03161484848485614a60565b612f3d81614c34565b612f4657600080fd5b7f811bbb11e8899da471f0e69a3ed55090fc90215227fc5fb1cb0d6e962ea7b74f60005260026020527fb4ed64697d3ef8518241966f7c6f28b0d72f20f51198717d198d2d55076c593d80546001600160a01b0319166001600160a01b0392909216919091179055565b826001600160a01b03166340c10f1983836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561300757600080fd5b505af115801561301b573d6000803e3d6000fd5b505050506040513d602081101561303157600080fd5b50516116b057600080fd5b604080516f686f6d65546f6b656e4164647265737360801b6020808301919091526001600160601b0319606086811b82166030850152845160248186030181526044850186528051908401206000908152600280855286822080546001600160a01b03808b166001600160a01b0319928316811790935572666f726569676e546f6b656e4164647265737360681b60648a0152948a901b90951660778801528751606b818903018152608b909701808952875197870197909720835294529485208054909216908716908117909155909290917f78d063210f4fb6b4cc932390bb8045fa2465e51349590182dab8b9e84c57a6ee9190a35050565b600082820183811015612cb2576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b613199613e68565b156131a357600080fd5b6131ad8482611a47565b6131b657600080fd5b6131c8846131c2611a9d565b83614c6d565b6131d58385848485614a60565b6131dd614cee565b826001600160a01b0316856001600160a01b03167f9afd47907e25028cdaca89d193518c302bbb128617d5a992c5abd45815526593846040518082815260200191505060405180910390a450505050565b604080516861636b4465706c6f7960b81b6020808301919091526001600160601b0319606085901b1660298301528251601d818403018152603d909201835281519181019190912060009081526004909152205460ff1661144257604080516861636b4465706c6f7960b81b6020808301919091526001600160601b0319606085901b1660298301528251601d818403018152603d90920183528151918101919091206000908152600490915220805460ff1916600117905550565b6000806132f68861197f565b90506001600160a01b03811661359d57606087878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b018190048102820181019092528981529394506060939250899150889081908401838280828437600092019190915250508451929350505015158061338b575060008151115b61339457600080fd5b81516133a2578091506133ab565b80516133ab5750805b6133b482614d61565b91506133be612883565b6001600160a01b031663a39d6acf8383886133d761241d565b6001600160a01b0316631544298e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561340f57600080fd5b505afa158015613423573d6000803e3d6000fd5b505050506040513d602081101561343957600080fd5b50516040516001600160e01b031960e087901b16815260ff831660448201526064810182905260806004820190815285516084830152855190918291602482019160a40190602089019080838360005b838110156134a1578181015183820152602001613489565b50505050905090810190601f1680156134ce5780820380516001836020036101000a031916815260200191505b50838103825286518152865160209182019188019080838360005b838110156135015781810151838201526020016134e9565b50505050905090810190601f16801561352e5780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b15801561355157600080fd5b505af1158015613565573d6000803e3d6000fd5b505050506040513d602081101561357b57600080fd5b505192506135898a8461303c565b613596838660ff16614e16565b505061362d565b6135a68161167f565b61362d578260ff16816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156135e757600080fd5b505afa1580156135fb573d6000803e3d6000fd5b505050506040513d602081101561361157600080fd5b505160ff161461362057600080fd5b61362d818460ff16614e16565b979650505050505050565b7f98aa806e31e94a687a31c65769cb99670064dd7f5a87526da075c5fb4eab988060005260026020527f0c1206883be66049a02d4937078367c00b3d71dd1a9465df969363c6ddeac96d80546001600160a01b0319166001600160a01b0392909216919091179055565b6040810151158015906136bc575060408101516020820151115b80156136cc575060208101518151115b6136d557600080fd5b8051604080516919185a5b1e531a5b5a5d60b21b602082810191909152606086901b6001600160601b031916602a83018190528351808403601e018152603e8401855280519083012060009081528083528481209590955581860151670dac2f0a0cae4a8f60c31b605e850152606684018290528451605a818603018152607a8501865280519084012086528583528486205583860151670dad2dca0cae4a8f60c31b609a85015260a28401919091528351609681850301815260b690930184528251928201929092208452839052908220556001600160a01b038316907fca0b3dabefdbd8c72c0a9cf4a6e9d107da897abf036ef3f3f3b010cdd25941599083905b60200201516040518082815260200191505060405180910390a25050565b805160208201511061380757600080fd5b80516040805172195e1958dd5d1a5bdb91185a5b1e531a5b5a5d606a1b602082810191909152606086901b6001600160601b031916603383018190528351808403602701815260478401855280519083012060009081528083528481209590955581860151700caf0cac6eae8d2dedc9ac2f0a0cae4a8f607b1b606785015260788401919091528351606c818503018152608c90930184528251928201929092208452839052908220556001600160a01b038316907f4c177b42dbe934b3abbc0208c11a42e46589983431616f1710ab19969c5ed62e9083906137d8565b6138ed614f9a565b8111156138f957600080fd5b7f2dfd6c9f781bb6bbb5369c114e949b69ebb440ef3d4dd6b2836225eb1dc3a2be60009081526020527f2de0d2cdc19d356cb53b5984f91bfd3b31fe0c678a0d190a6db39274bb34753f55565b6001600160a01b03811661395957600080fd5b7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0613982611f07565b604080516001600160a01b03928316815291841660208301528051918290030190a17f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c060005260026020527fb7802e97e87ef2842a6cce7da7ffaeaedaa2f61a6a7870b23d9d01fc9b73712e80546001600160a01b0319166001600160a01b0392909216919091179055565b613a1781614c34565b613a2057600080fd5b7f269c5905f777ee6391c7a361d17039a7d62f52ba9fffeb98c5ade342705731a360005260026020527f15c764a0cd4bb3d72a49abedd3d6793c3b93c0d57f43174a348b443be86f79c180546001600160a01b0319166001600160a01b0392909216919091179055565b7f0a6f646cd611241d8073675e00d1a1ff700fbf1b53fcf473de56d1e6e4b714ba60005260046020527f078d888f9b66f3f8bfa10909e31f1e16240db73449f0500afdbbe3a70da457cc805460ff19166001179055565b306001600160a01b0316636fde82026040518163ffffffff1660e01b815260040160206040518083038186803b158015613b1a57600080fd5b505afa158015613b2e573d6000803e3d6000fd5b505050506040513d6020811015613b4457600080fd5b50516001600160a01b03163314612c6e57600080fd5b806001600160a01b038116613b6e57600080fd5b6001600160a01b038316613b8a57613b8582614fdc565b6116b0565b6116b08383614fe7565b613b9d84614c34565b156115c157836001600160a01b031663db7af85460e01b84848460405160240180846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015613c0c578181015183820152602001613bf4565b50505050905090810190601f168015613c395780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990991698909817885251815191979096508695509350915081905083835b60208310613c9f5780518252601f199092019160209182019101613c80565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611ca4576040519150601f19603f3d011682016040523d82523d6000602084013e611ca4565b6000613d0b61241d565b6001600160a01b031663dc8601b3613d21611eb0565b85613d2a612362565b6040518463ffffffff1660e01b815260040180846001600160a01b0316815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015613d8b578181015183820152602001613d73565b50505050905090810190601f168015613db85780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b158015613dd957600080fd5b505af1158015613ded573d6000803e3d6000fd5b505050506040513d6020811015613e0357600080fd5b50519392505050565b604080516f1b5a5b90d85cda151a1c995cda1bdb1960821b60208083019190915260609490941b6001600160601b0319166030820152815180820360240181526044909101825280519084012060009081529283905290912055565b7f6168652c307c1e813ca11cfb3a601f1cf3b22452021a5052d8b05f1f1f8a3e925490565b6014015190565b6001600160a01b03831615801590613ec55750613eaf611eb0565b6001600160a01b0316836001600160a01b031614155b613ece57600080fd5b613ed78561167f565b613ef7576000613ee686615074565b9050613ef5868260ff16614e16565b505b613f01858361151a565b613f0a57600080fd5b613f16856124ee611a9d565b6060612516613f2487611bbf565b878686866141af565b6001600160a01b0381161580613fb85750806001600160a01b031663bdd378a0836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015613f8b57600080fd5b505afa158015613f9f573d6000803e3d6000fd5b505050506040513d6020811015613fb557600080fd5b50515b613fc157600080fd5b604080516b1a5b9d195c995cdd125b5c1b60a21b60208083019190915260609490941b6001600160601b031916602c82015281518082038501815290820182528051908401206000908152600290935290912080546001600160a01b0319166001600160a01b03909216919091179055565b60008061403f83611e27565b9050600061404c82614c34565b6140575760006140d1565b816001600160a01b031663cff77444856040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156140a457600080fd5b505afa1580156140b8573d6000803e3d6000fd5b505050506040513d60208110156140ce57600080fd5b50515b90506141296140e3826112da87611624565b604080516370a0823160e01b815230600482015290516001600160a01b038816916370a08231916024808301926020929190829003018186803b158015612bf357600080fd5b949350505050565b61413f81611532858561225b565b600080858560405160200180806f746f74616c5370656e7450657244617960801b815250601001836001600160a01b031660601b81526014018281526020019250505060405160208183030381529060405280519060200120815260200190815260200160002081905550505050565b6060600080835111806141d457506000356001600160e01b03191663d740548160e01b145b90506001600160a01b03871661468f576141fa866141f5866115328a611624565b615242565b61420386612309565b15614340578061426157604080516001600160a01b0380891660248301528716604482015260648082018790528251808303909101815260849091019091526020810180516001600160e01b031663125e4cfb60e01b179052614338565b63c534576160e01b8686868660405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156142d15781810151838201526020016142b9565b50505050905090810190601f1680156142fe5780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909916989098179097525050505050505b915050614821565b600061434b87615074565b905060606143588861529d565b9050606061436589615463565b9050600082511180614378575060008151115b61438157600080fd5b836144d457632ae87cdd60e01b898383868c8c60405160240180876001600160a01b0316815260200180602001806020018660ff168152602001856001600160a01b03168152602001848152602001838103835288818151815260200191508051906020019080838360005b838110156144055781810151838201526020016143ed565b50505050905090810190601f1680156144325780820380516001836020036101000a031916815260200191505b50838103825287518152875160209182019189019080838360005b8381101561446557818101518382015260200161444d565b50505050905090810190601f1680156144925780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909c169b909b17909a5250614684975050505050505050565b63d522cfd760e01b898383868c8c8c60405160240180886001600160a01b0316815260200180602001806020018760ff168152602001866001600160a01b031681526020018581526020018060200184810384528a818151815260200191508051906020019080838360005b83811015614558578181015183820152602001614540565b50505050905090810190601f1680156145855780820380516001836020036101000a031916815260200191505b5084810383528951815289516020918201918b019080838360005b838110156145b85781810151838201526020016145a0565b50505050905090810190601f1680156145e55780820380516001836020036101000a031916815260200191505b50848103825285518152855160209182019187019080838360005b83811015614618578181015183820152602001614600565b50505050905090810190601f1680156146455780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909e169d909d17909c5250505050505050505050505b945050505050614821565b856001600160a01b03166342966c68856040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156146d557600080fd5b505af11580156146e9573d6000803e3d6000fd5b505050508061474657604080516001600160a01b03808a1660248301528716604482015260648082018790528251808303909101815260849091019091526020810180516001600160e01b031663272255bb60e01b17905261481d565b63867f7a4d60e01b8786868660405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156147b657818101518382015260200161479e565b50505050905090810190601f1680156147e35780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909916989098179097525050505050505b9150505b95945050505050565b6148348484615596565b61483e8483615602565b6148488482615672565b83826001600160a01b0316846001600160a01b03167f59a9a8027b9c87b961e254899821c9a276b5efc35d1f7409ea4f291470f1629a846040518082815260200191505060405180910390a450505050565b7f6168652c307c1e813ca11cfb3a601f1cf3b22452021a5052d8b05f1f1f8a3e9255565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b1790526115c19085906149af565b600081848411156149a75760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561496c578181015183820152602001614954565b50505050905090810190601f1680156149995780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6060614a04826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166156c19092919063ffffffff16565b8051909150156116b057808060200190516020811015614a2357600080fd5b50516116b05760405162461bcd60e51b815260040180806020018281038252602a815260200180615b61602a913960400191505060405180910390fd5b8415614c16576000614a7185611624565b90506001600160a01b038516730ae055097c6d159879521c384f1d2123d1f195e6148015614a9e57508281105b15614abc57614ab96001600160a01b03861630838603612fb0565b50815b6000614ac786611e27565b90506001600160a01b03811615614bed576000614b5d826001600160a01b031663cff77444896040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015614b2a57600080fd5b505afa158015614b3e573d6000803e3d6000fd5b505050506040513d6020811015614b5457600080fd5b50518490612c70565b905080851115614beb57816001600160a01b031663f3fef3a388614b8c614b838b611b10565b858a0390613137565b6040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015614bd257600080fd5b505af1158015614be6573d6000803e3d6000fd5b505050505b505b614bfb866141f58486612c70565b614c0f6001600160a01b0387168686612cb9565b505061214c565b61214c8383614c24876156d0565b6001600160a01b03169190612fb0565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590614129575050151592915050565b614c7b81611532858561297b565b6000808585604051602001808072746f74616c457865637574656450657244617960681b815250601301836001600160a01b031660601b81526014018281526020019250505060405160208183030381529060405280519060200120815260200190815260200160002081905550505050565b6000614cf861241d565b6001600160a01b031663669f618b6040518163ffffffff1660e01b815260040160206040518083038186803b158015614d3057600080fd5b505afa158015614d44573d6000803e3d6000fd5b505050506040513d6020811015614d5a57600080fd5b5051905090565b606080827f2066726f6d2078446169000000000000000000000000000000000000000000006040516020018083805190602001908083835b60208310614db85780518252601f199092019160209182019101614d99565b51815160209384036101000a60001901801990921691161790529201938452506040805180850381529390910190525093517f000000000000000000000000000000000000000000000000000000000000000a018452509192915050565b60006012821015614f0a5781601203600a0a90506000614e4082614e3a600061215d565b906156d3565b90506000614e5283614e3a60006111ee565b90506000614e6484614e3a6000612a06565b90506000614e7685614e3a60006115c7565b90506000614e8886614e3a6000611aa6565b905084614ebe5760019450848411614ebe5760649350606491508383111580614eb15750818111155b15614ebe57506127109150815b614ee2886040518060600160405280868152602001878152602001888152506136a2565b614f00886040518060400160405280848152602001858152506137f6565b50505050506116b0565b60128203600a0a9050614f63836040518060600160405280614f3685614f306000612a06565b90615715565b8152602001614f4985614f3060006111ee565b8152602001614f5c85614f30600061215d565b90526136a2565b6116b0836040518060400160405280614f8085614f306000611aa6565b8152602001614f9385614f3060006115c7565b90526137f6565b6000614fa461241d565b6001600160a01b031663e5789d036040518163ffffffff1660e01b815260040160206040518083038186803b158015614d3057600080fd5b4761114b828261576e565b604080516370a0823160e01b8152306004820152905183916000916001600160a01b038416916370a08231916024808301926020929190829003018186803b15801561503257600080fd5b505afa158015615046573d6000803e3d6000fd5b505050506040513d602081101561505c57600080fd5b505190506115c16001600160a01b0383168483612cb9565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b1781529151815160009384936060936001600160a01b03881693919290918291908083835b602083106150dd5780518252601f1990920191602091820191016150be565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d806000811461513d576040519150601f19603f3d011682016040523d82523d6000602084013e615142565b606091505b5091509150816152235760408051600481526024810182526020810180516001600160e01b0316632e0f262560e01b178152915181516001600160a01b0388169382918083835b602083106151a85780518252601f199092019160209182019101615189565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114615208576040519150601f19603f3d011682016040523d82523d6000602084013e61520d565b606091505b5090925090508161522357600092505050611241565b80806020019051602081101561523857600080fd5b5051949350505050565b604080516e6d65646961746f7242616c616e636560881b60208083019190915260609490941b6001600160601b031916602f820152815180820360230181526043909101825280519084012060009081529283905290912055565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b1781529151815160609360009385936001600160a01b03881693919290918291908083835b602083106153065780518252601f1990920191602091820191016152e7565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114615366576040519150601f19603f3d011682016040523d82523d6000602084013e61536b565b606091505b50915091508161545a5760408051600481526024810182526020810180516001600160e01b03166351fa6fbf60e11b178152915181516001600160a01b0388169382918083835b602083106153d15780518252601f1990920191602091820191016153b2565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114615431576040519150601f19603f3d011682016040523d82523d6000602084013e615436565b606091505b5090925090508161545a576040518060200160405280600081525092505050611241565b614129816157d3565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b1781529151815160609360009385936001600160a01b03881693919290918291908083835b602083106154cc5780518252601f1990920191602091820191016154ad565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d806000811461552c576040519150601f19603f3d011682016040523d82523d6000602084013e615531565b606091505b50915091508161545a5760408051600481526024810182526020810180516001600160e01b0316631eedf1af60e31b178152915181516001600160a01b038816938291808383602083106153d15780518252601f1990920191602091820191016153b2565b604080516b36b2b9b9b0b3b2aa37b5b2b760a11b602080830191909152602c8083019590955282518083039095018552604c90910182528351938101939093206000908152600290935290912080546001600160a01b0319166001600160a01b03909216919091179055565b604080516f1b595cdcd859d9549958da5c1a595b9d60821b60208083019190915260308083019590955282518083039095018552605090910182528351938101939093206000908152600290935290912080546001600160a01b0319166001600160a01b03909216919091179055565b604080516b6d65737361676556616c756560a01b602080830191909152602c8083019590955282518083039095018552604c909101825283519381019390932060009081529283905290912055565b6060614129848460008561592f565b90565b6000612cb283836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250615a9c565b60008261572457506000611587565b8282028284828161573157fe5b0414612cb25760405162461bcd60e51b8152600401808060200182810382526021815260200180615b406021913960400191505060405180910390fd5b6040516001600160a01b0383169082156108fc029083906000818181858888f1935050505061114b5780826040516157a590615b01565b6001600160a01b039091168152604051908190036020019082f09050801580156115c1573d6000803e3d6000fd5b60606020825111156158a9578180602001905160208110156157f457600080fd5b8101908080516040519392919084600160201b82111561581357600080fd5b90830190602082018581111561582857600080fd5b8251600160201b81118282018810171561584157600080fd5b82525081516020918201929091019080838360005b8381101561586e578181015183820152602001615856565b50505050905090810190601f16801561589b5780820380516001836020036101000a031916815260200191505b506040525050509050611241565b81516020141561591a5760008280602001905160208110156158ca57600080fd5b50516040805160208082528183019092529192506060919060208201818036833701905050905060008260208301525b821561590f5760089290921b916001016158fa565b815291506112419050565b50604080516020810190915260008152611241565b606061593a85614c34565b61598b576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b602083106159ca5780518252601f1990920191602091820191016159ab565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114615a2c576040519150601f19603f3d011682016040523d82523d6000602084013e615a31565b606091505b50915091508115615a455791506141299050565b805115615a555780518082602001fd5b60405162461bcd60e51b815260206004820181815286516024840152865187939192839260440191908501908083836000831561496c578181015183820152602001614954565b60008183615aeb5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561496c578181015183820152602001614954565b506000838581615af757fe5b0495945050505050565b603280615b0e8339019056fe60806040526040516032380380603283398181016040526020811015602357600080fd5b50516001600160a01b038116fffe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220274caa5a6a0c729be67fdcf4620871c021af258e3a717eac25b66f36cb17ee4964736f6c63430007050033", + "linkReferences": {}, + "deployedLinkReferences": {} +} \ No newline at end of file diff --git a/operate/data/contracts/foreign_omnibridge/contract.py b/operate/data/contracts/foreign_omnibridge/contract.py new file mode 100644 index 00000000..7bd2337d --- /dev/null +++ b/operate/data/contracts/foreign_omnibridge/contract.py @@ -0,0 +1,130 @@ +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2024 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ + +"""This module contains the class to connect to the `ForeignOmnibridge` contract.""" + +from math import ceil +from typing import Optional + +from aea.common import JSONLike +from aea.configurations.base import PublicId +from aea.contracts.base import Contract +from aea.crypto.base import LedgerApi + + +PLACEHOLDER_NATIVE_TOKEN_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" # nosec + +#DEFAULT_GAS_BRIDGE_ETH_TO = 800_000 +DEFAULT_GAS_RELAY_TOKENS = 800_000 + +# By simulations, nonzero-ERC20-bridge gas ~ 1.05 zero-ERC20-bridge gas +NONZERO_ERC20_GAS_FACTOR = 1.15 + + +class ForeignOmnibridge(Contract): + """ForeignOmnibridge.""" + + contract_id = PublicId.from_str("valory/foreign_omnibridge:0.1.0") + + @classmethod + def build_relay_tokens_tx( + cls, + ledger_api: LedgerApi, + contract_address: str, + sender: str, + token: str, + receiver: str, + amount: int, + raise_on_try: bool = False, + ) -> JSONLike: + """Build bridgeERC20To tx.""" + contract_instance = cls.get_instance( + ledger_api=ledger_api, contract_address=contract_address + ) + tx = contract_instance.functions.relayTokens( + token, receiver, amount + ).build_transaction( + { + "from": sender, + "gas": 1, + "gasPrice": ledger_api.api.eth.gas_price, + "nonce": ledger_api.api.eth.get_transaction_count(sender), + } + ) + + ledger_api.update_with_gas_estimate( + transaction=tx, + raise_on_try=raise_on_try, + ) + + if tx["gas"] > 1: + return tx + + tx_zero = contract_instance.functions.relayTokens( + token, receiver, 0 + ).build_transaction( + { + "from": PLACEHOLDER_NATIVE_TOKEN_ADDRESS, + "gas": 1, + "gasPrice": ledger_api.api.eth.gas_price, + "nonce": ledger_api.api.eth.get_transaction_count(sender), + } + ) + + ledger_api.update_with_gas_estimate( + transaction=tx_zero, + raise_on_try=raise_on_try, + ) + + if tx_zero["gas"] > 1: + tx["gas"] = ceil(tx_zero["gas"] * NONZERO_ERC20_GAS_FACTOR) + return tx + + tx["gas"] = DEFAULT_GAS_RELAY_TOKENS + return tx + + @classmethod + def get_tokens_bridging_initiated_message_id( + cls, + ledger_api: LedgerApi, + contract_address: str, + tx_hash: str, + token: str, + sender: str, + value: int, + raise_on_try: bool = False, + ) -> Optional[bytes]: + """Get the 'messageId' for the matching 'TokensBridgingInitiated' within the transaction 'tx_hash'.""" + contract_instance = cls.get_instance( + ledger_api=ledger_api, contract_address=contract_address + ) + receipt = ledger_api.api.eth.get_transaction_receipt(tx_hash) + event = contract_instance.events.TokensBridgingInitiated() + events = event.process_receipt(receipt) + + for e in events: + args = e["args"] + if ( + args["token"].lower() == token.lower() + and args["sender"].lower() == sender.lower() + and int(args["value"]) == value + ): + return args["messageId"] + + return None diff --git a/operate/data/contracts/foreign_omnibridge/contract.yaml b/operate/data/contracts/foreign_omnibridge/contract.yaml new file mode 100644 index 00000000..4e9eba2b --- /dev/null +++ b/operate/data/contracts/foreign_omnibridge/contract.yaml @@ -0,0 +1,23 @@ +name: foreign_omnibridge +author: valory +version: 0.1.0 +type: contract +description: ForeignOmnibridge +license: Apache-2.0 +aea_version: '>=1.0.0, <2.0.0' +fingerprint: + __init__.py: bafybeibsmumov3s36vfo24xp2niilcp3ywju2d4yqfadllyjncqtgtndly + build/ForeignOmnibridge.json: bafybeibmcflt7w5p5szgii7glbtrvjahweclowz2k7e6qjq7yfbvszy6em + contract.py: bafybeidjjdhjr2rj3q2q27fhm366kt4qpsvjqg3ytpa2titic5sari6r24 +fingerprint_ignore_patterns: [] +contracts: [] +class_name: ForeignOmnibridge +contract_interface_paths: + ethereum: build/ForeignOmnibridge.json +dependencies: + open-aea-ledger-ethereum: + version: ==1.60.0 + open-aea-test-autonomy: + version: ==0.18.3 + web3: + version: <7,>=6.0.0 diff --git a/operate/data/contracts/home_omnibridge/__init__.py b/operate/data/contracts/home_omnibridge/__init__.py new file mode 100644 index 00000000..5a31957d --- /dev/null +++ b/operate/data/contracts/home_omnibridge/__init__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2024 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ + +"""This module contains the support resources for the `HomeOmnibridge` contract.""" diff --git a/operate/data/contracts/home_omnibridge/build/HomeOmnibridge.json b/operate/data/contracts/home_omnibridge/build/HomeOmnibridge.json new file mode 100644 index 00000000..9f150921 --- /dev/null +++ b/operate/data/contracts/home_omnibridge/build/HomeOmnibridge.json @@ -0,0 +1,1421 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "HomeOmnibridge", + "sourceName": "HomeOmnibridge.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "_suffix", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newLimit", + "type": "uint256" + } + ], + "name": "DailyLimitChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newLimit", + "type": "uint256" + } + ], + "name": "ExecutionDailyLimitChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "messageId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "FailedMessageFixed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "messageId", + "type": "bytes32" + } + ], + "name": "FeeDistributed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "FeeDistributionFailed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "nativeToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "bridgedToken", + "type": "address" + } + ], + "name": "NewTokenRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "messageId", + "type": "bytes32" + } + ], + "name": "TokensBridged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "messageId", + "type": "bytes32" + } + ], + "name": "TokensBridgingInitiated", + "type": "event" + }, + { + "inputs": [], + "name": "bridgeContract", + "outputs": [ + { + "internalType": "contract IAMB", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_nativeToken", + "type": "address" + } + ], + "name": "bridgedTokenAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "claimTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_bridgedToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "claimTokensFromTokenContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "dailyLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "_decimals", + "type": "uint8" + }, + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + } + ], + "name": "deployAndHandleBridgedTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "_decimals", + "type": "uint8" + }, + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "deployAndHandleBridgedTokensAndCall", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "executionDailyLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "executionMaxPerTx", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeManager", + "outputs": [ + { + "internalType": "contract OmnibridgeFeeManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_messageId", + "type": "bytes32" + } + ], + "name": "fixFailedMessage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "fixMediatorBalance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_homeToken", + "type": "address" + } + ], + "name": "foreignTokenAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "forwardingRulesManager", + "outputs": [ + { + "internalType": "contract MultiTokenForwardingRulesManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gasLimitManager", + "outputs": [ + { + "internalType": "contract SelectorTokenGasLimitManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBridgeInterfacesVersion", + "outputs": [ + { + "internalType": "uint64", + "name": "major", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "minor", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "patch", + "type": "uint64" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getBridgeMode", + "outputs": [ + { + "internalType": "bytes4", + "name": "_data", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentDay", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + } + ], + "name": "handleBridgedTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "handleBridgedTokensAndCall", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + } + ], + "name": "handleNativeTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "handleNativeTokensAndCall", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_foreignToken", + "type": "address" + } + ], + "name": "homeTokenAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_bridgeContract", + "type": "address" + }, + { + "internalType": "address", + "name": "_mediatorContract", + "type": "address" + }, + { + "internalType": "uint256[3]", + "name": "_dailyLimitMaxPerTxMinPerTxArray", + "type": "uint256[3]" + }, + { + "internalType": "uint256[2]", + "name": "_executionDailyLimitExecutionMaxPerTxArray", + "type": "uint256[2]" + }, + { + "internalType": "address", + "name": "_gasLimitManager", + "type": "address" + }, + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "internalType": "address", + "name": "_tokenFactory", + "type": "address" + }, + { + "internalType": "address", + "name": "_feeManager", + "type": "address" + }, + { + "internalType": "address", + "name": "_forwardingRulesManager", + "type": "address" + } + ], + "name": "initialize", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "isBridgedTokenDeployAcknowledged", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isInitialized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "isRegisteredAsNativeToken", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "isTokenRegistered", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "maxAvailablePerTx", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "maxPerTx", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "mediatorBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mediatorContractOnOtherSide", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_messageId", + "type": "bytes32" + } + ], + "name": "messageFixed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_tokenFactory", + "type": "address" + }, + { + "internalType": "address", + "name": "_forwardingRulesManager", + "type": "address" + }, + { + "internalType": "address", + "name": "_gasLimitManager", + "type": "address" + }, + { + "internalType": "address", + "name": "_feeManager", + "type": "address" + } + ], + "name": "migrateTo_3_3_0", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "minPerTx", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_bridgedToken", + "type": "address" + } + ], + "name": "nativeTokenAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "onTokenTransfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC677", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + } + ], + "name": "relayTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC677", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + } + ], + "name": "relayTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC677", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "relayTokensAndCall", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_messageId", + "type": "bytes32" + } + ], + "name": "requestFailedMessageFix", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_bridgeContract", + "type": "address" + } + ], + "name": "setBridgeContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_nativeToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_bridgedToken", + "type": "address" + } + ], + "name": "setCustomTokenAddressPair", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_dailyLimit", + "type": "uint256" + } + ], + "name": "setDailyLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_dailyLimit", + "type": "uint256" + } + ], + "name": "setExecutionDailyLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_maxPerTx", + "type": "uint256" + } + ], + "name": "setExecutionMaxPerTx", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_feeManager", + "type": "address" + } + ], + "name": "setFeeManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_manager", + "type": "address" + } + ], + "name": "setForwardingRulesManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_manager", + "type": "address" + } + ], + "name": "setGasLimitManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_maxPerTx", + "type": "uint256" + } + ], + "name": "setMaxPerTx", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_mediatorContract", + "type": "address" + } + ], + "name": "setMediatorContractOnOtherSide", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_minPerTx", + "type": "uint256" + } + ], + "name": "setMinPerTx", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_tokenFactory", + "type": "address" + } + ], + "name": "setTokenFactory", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "tokenFactory", + "outputs": [ + { + "internalType": "contract TokenFactory", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_day", + "type": "uint256" + } + ], + "name": "totalExecutedPerDay", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_day", + "type": "uint256" + } + ], + "name": "totalSpentPerDay", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withinExecutionLimit", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withinLimit", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106103a45760003560e01c80636e5d6bea116101e9578063c2173d431161010f578063d7405481116100ad578063ec47de2a1161007c578063ec47de2a14611047578063f2c54fe814611073578063f2fde38b1461109f578063f3f51415146110c5576103a4565b8063d740548114610f29578063db6fff8c14610fed578063dfbe4ae014611019578063e77772fe1461103f576103a4565b8063cd596583116100e9578063cd59658314610daf578063d0342acd14610db7578063d0fb020314610de5578063d522cfd714610ded576103a4565b8063c2173d4314610cbd578063c534576114610ce3578063c722b1be14610da7576103a4565b80639a4a439511610187578063a4c0ed3611610156578063a4c0ed3614610b7c578063ab3a25d914610c35578063ad58bdd114610c61578063ae813e9f14610c97576103a4565b80639a4a439514610afd5780639cb7595a14610b1a5780639d4051ae14610b4e578063a4b1c24314610b56576103a4565b8063867f7a4d116101c3578063867f7a4d14610a03578063871c076014610ac75780638da5cb5b14610acf57806390ad84a814610ad7576103a4565b80636e5d6bea1461098b5780637610722f146109b15780637837cf91146109d7576103a4565b80632d70061f116102ce578063437764df1161026c578063613fa2f21161023b578063613fa2f2146108d957806361c04f84146108ff57806364696f971461092557806369ffa08a1461095d576103a4565b8063437764df1461084b578063472d35b91461087057806347ac7d6a1461089657806359339982146108bc576103a4565b80633a50bc87116102a85780633a50bc871461078a5780633da98c8b146107b65780633e6968b61461081d57806340f8dd8614610825576103a4565b80632d70061f1461071a5780632f73a9f81461075c578063392e53cd14610782576103a4565b8063125e4cfb1161034657806326aa101f1161031557806326aa101f146105ac578063272255bb146105d25780632803212f146106085780632ae87cdd14610634576103a4565b8063125e4cfb146104ec57806316ef191314610522578063194153d3146105485780631ba9212d1461056e576103a4565b80630950d515116103825780630950d5151461043b5780630b26cf66146104585780630b71a4a71461047e57806310775238146104ac576103a4565b806301e4f53a146103a957806301fcc1d3146103d7578063032f693f14610403575b600080fd5b6103d5600480360360408110156103bf57600080fd5b506001600160a01b0381351690602001356110eb565b005b6103d5600480360360408110156103ed57600080fd5b506001600160a01b03813516906020013561112a565b6104296004803603602081101561041957600080fd5b50356001600160a01b03166111c9565b60408051918252519081900360200190f35b6103d56004803603602081101561045157600080fd5b5035611221565b6103d56004803603602081101561046e57600080fd5b50356001600160a01b03166112ca565b6103d56004803603604081101561049457600080fd5b506001600160a01b03813581169160200135166112de565b6104d8600480360360408110156104c257600080fd5b506001600160a01b0381351690602001356113b3565b604080519115158252519081900360200190f35b6103d56004803603606081101561050257600080fd5b506001600160a01b03813581169160208101359091169060400135611426565b6104296004803603602081101561053857600080fd5b50356001600160a01b0316611460565b6104296004803603602081101561055e57600080fd5b50356001600160a01b03166114bd565b6103d56004803603608081101561058457600080fd5b506001600160a01b038135811691602081013582169160408201358116916060013516611518565b6104d8600480360360208110156105c257600080fd5b50356001600160a01b031661164b565b6103d5600480360360608110156105e857600080fd5b506001600160a01b0381358116916020810135909116906040013561165e565b6103d56004803603604081101561061e57600080fd5b506001600160a01b038135169060200135611681565b6103d5600480360360c081101561064a57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561067457600080fd5b82018360208201111561068657600080fd5b803590602001918460018302840111600160201b831117156106a757600080fd5b919390929091602081019035600160201b8111156106c457600080fd5b8201836020820111156106d657600080fd5b803590602001918460018302840111600160201b831117156106f757600080fd5b919350915060ff813516906001600160a01b036020820135169060400135611750565b6107406004803603602081101561073057600080fd5b50356001600160a01b0316611782565b604080516001600160a01b039092168252519081900360200190f35b6103d56004803603602081101561077257600080fd5b50356001600160a01b03166117e8565b6104d86117f9565b6104d8600480360360408110156107a057600080fd5b506001600160a01b03813516906020013561184a565b6104d860048036036101808110156107cd57600080fd5b506001600160a01b0381358116916020810135821691604082019160a081019160e082013581169161010081013582169161012082013581169161014081013582169161016090910135166118a0565b610429611a88565b6104296004803603602081101561083b57600080fd5b50356001600160a01b0316611a91565b610853611af0565b604080516001600160e01b03199092168252519081900360200190f35b6103d56004803603602081101561088657600080fd5b50356001600160a01b0316611afb565b610740600480360360208110156108ac57600080fd5b50356001600160a01b0316611b0c565b6104d8600480360360208110156108d257600080fd5b5035611b17565b6103d5600480360360208110156108ef57600080fd5b50356001600160a01b0316611b6a565b6107406004803603602081101561091557600080fd5b50356001600160a01b0316611b7b565b6103d56004803603606081101561093b57600080fd5b506001600160a01b038135811691602081013582169160409091013516611be4565b6103d56004803603604081101561097357600080fd5b506001600160a01b0381358116916020013516611c69565b6103d5600480360360208110156109a157600080fd5b50356001600160a01b0316611ca0565b610429600480360360208110156109c757600080fd5b50356001600160a01b0316611cb1565b6103d5600480360360408110156109ed57600080fd5b506001600160a01b038135169060200135611d0b565b6103d560048036036080811015610a1957600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610a5357600080fd5b820183602082011115610a6557600080fd5b803590602001918460018302840111600160201b83111715610a8657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611de3945050505050565b610740611e0d565b610740611e64565b6103d560048036036020811015610aed57600080fd5b50356001600160a01b0316611ebb565b6103d560048036036020811015610b1357600080fd5b5035611ecc565b610b226120c1565b6040805167ffffffffffffffff9485168152928416602084015292168183015290519081900360600190f35b6107406120cb565b61042960048036036020811015610b6c57600080fd5b50356001600160a01b0316612122565b6104d860048036036060811015610b9257600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b811115610bc157600080fd5b820183602082011115610bd357600080fd5b803590602001918460018302840111600160201b83111715610bf457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506121a7945050505050565b61042960048036036040811015610c4b57600080fd5b506001600160a01b03813516906020013561220e565b6103d560048036036060811015610c7757600080fd5b506001600160a01b03813581169160208101359091169060400135612274565b6104d860048036036020811015610cad57600080fd5b50356001600160a01b0316612282565b6104d860048036036020811015610cd357600080fd5b50356001600160a01b03166122db565b6103d560048036036080811015610cf957600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610d3357600080fd5b820183602082011115610d4557600080fd5b803590602001918460018302840111600160201b83111715610d6657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612308945050505050565b610740612348565b61074061239f565b6103d560048036036040811015610dcd57600080fd5b506001600160a01b03813581169160200135166123f6565b6107406124b5565b6103d5600480360360e0811015610e0357600080fd5b6001600160a01b038235169190810190604081016020820135600160201b811115610e2d57600080fd5b820183602082011115610e3f57600080fd5b803590602001918460018302840111600160201b83111715610e6057600080fd5b919390929091602081019035600160201b811115610e7d57600080fd5b820183602082011115610e8f57600080fd5b803590602001918460018302840111600160201b83111715610eb057600080fd5b9193909260ff833516926001600160a01b03602082013516926040820135929091608081019060600135600160201b811115610eeb57600080fd5b820183602082011115610efd57600080fd5b803590602001918460018302840111600160201b83111715610f1e57600080fd5b50909250905061250c565b6103d560048036036080811015610f3f57600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610f7957600080fd5b820183602082011115610f8b57600080fd5b803590602001918460018302840111600160201b83111715610fac57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612582945050505050565b6103d56004803603604081101561100357600080fd5b506001600160a01b03813516906020013561258e565b6107406004803603602081101561102f57600080fd5b50356001600160a01b031661262b565b610740612636565b6103d56004803603604081101561105d57600080fd5b506001600160a01b03813516906020013561268d565b6104296004803603604081101561108957600080fd5b506001600160a01b03813516906020013561272e565b6103d5600480360360208110156110b557600080fd5b50356001600160a01b0316612797565b610429600480360360208110156110db57600080fd5b50356001600160a01b03166127a8565b6111268233836000805b506040519080825280601f01601f191660200182016040528015611120576020820181803683370190505b506127fe565b5050565b61113261295f565b61113b8261164b565b61114457600080fd5b8015806111635750600081118015611163575061116082611a91565b81105b61116c57600080fd5b60408051700caf0cac6eae8d2dedc9ac2f0a0cae4a8f607b1b60208083019190915260609490941b6001600160601b0319166031820152815180820360250181526045909101825280519084012060009081529283905290912055565b60408051670dac2f0a0cae4a8f60c31b6020808301919091526001600160601b0319606085901b1660288301528251601c818403018152603c909201835281519181019190912060009081529081905220545b919050565b611229612986565b61123281611b17565b1561123c57600080fd5b600061124782612a30565b9050600061125483612a89565b9050600061126184612ae6565b905061126c84612b35565b611277838383612b8e565b604080516001600160a01b03808616825284166020820152808201839052905185917f07b5483b8e4bd8ea240a474d5117738350e7d431e3668c48a97910b0b397796a919081900360600190a250505050565b6112d261295f565b6112db81612baf565b50565b6112e661295f565b6112ef8161164b565b156112f957600080fd5b600061130482611b7b565b6001600160a01b03161461131757600080fd5b600061132283611782565b6001600160a01b03161461133557600080fd5b61134a6001600160a01b038216306001612c2b565b806001600160a01b03166342966c6860016040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561139157600080fd5b505af11580156113a5573d6000803e3d6000fd5b505050506111268282612cb7565b6000806113d1836113cb866113c6611a88565b61220e565b90612db2565b905060006113df60006127a8565b1180156113f45750806113f1856127a8565b10155b80156114085750611404846111c9565b8311155b801561141c575061141884612122565b8310155b9150505b92915050565b61142e612986565b600061143984611782565b90506114448161164b565b61144d57600080fd5b61145a8160008585612e13565b50505050565b60408051700caf0cac6eae8d2dedc9ac2f0a0cae4a8f607b1b60208083019190915260609390931b6001600160601b0319166031820152815180820360250181526045909101825280519083012060009081529182905290205490565b604080516e6d65646961746f7242616c616e636560881b60208083019190915260609390931b6001600160601b031916602f820152815180820360230181526043909101825280519083012060009081529182905290205490565b7f1ba9212d27ad775f3f89cdd276d3829dd95d169a049be071de905db3bbca633e600081905260046020527f39ed9a5a925de329b4b8d3797a51d757351f7bb58fe4f46a37c1af393b814a685460ff161561157257600080fd5b33301461157e57600080fd5b61158785612f3d565b61159084612fb9565b61159983613046565b6115a2826130d3565b604080516919185a5b1e531a5b5a5d60b21b6020808301919091526000602a83018190528351601e818503018152603e84018086528151918401919091208252918190528381206ec097ce7bc90715b34b9f10000000009081905590915291517fca0b3dabefdbd8c72c0a9cf4a6e9d107da897abf036ef3f3f3b010cdd259415991819003605e0190a26000908152600460205260409020805460ff1916600117905550505050565b60008061165783612122565b1192915050565b611666612986565b61166f83613160565b61167c8360018484612e13565b505050565b61168961295f565b6116928261164b565b61169b57600080fd5b6116a4826111c9565b8111806116af575080155b6116b857600080fd5b604080516919185a5b1e531a5b5a5d60b21b6020808301919091526001600160601b0319606086901b16602a8301528251601e818403018152603e83018085528151918301919091206000908152918290529083902084905583905290516001600160a01b038416917fca0b3dabefdbd8c72c0a9cf4a6e9d107da897abf036ef3f3f3b010cdd25941599190819003605e0190a25050565b611758612986565b600061176889898989898961321c565b90506117778160008585612e13565b505050505050505050565b604080516f686f6d65546f6b656e4164647265737360801b60208083019190915260609390931b6001600160601b03191660308201528151808203602401815260449091018252805190830120600090815260029092529020546001600160a01b031690565b6117f061295f565b6112db81612f3d565b7f0a6f646cd611241d8073675e00d1a1ff700fbf1b53fcf473de56d1e6e4b714ba60005260046020527f078d888f9b66f3f8bfa10909e31f1e16240db73449f0500afdbbe3a70da457cc5460ff1690565b600080611862836113cb8661185d611a88565b61272e565b905060006118706000611a91565b11801561188557508061188285611a91565b10155b801561141c575061189584611460565b909211159392505050565b60408051600481526024810182526020810180516001600160e01b03166337ef410160e11b1781529151815160009384936060933093919290918291908083835b602083106119005780518252601f1990920191602091820191016118e1565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114611960576040519150601f19603f3d011682016040523d82523d6000602084013e611965565b606091505b50915091508115806119a15750805160201480156119a1575080806020019051602081101561199357600080fd5b50516001600160a01b031633145b806119ab57503330145b6119b457600080fd5b6119bc6117f9565b156119c657600080fd5b6119cf8c612baf565b6119d88b61356a565b611a0c60008b60038060200260405190810160405280929190826003602002808284376000920191909152506135d4915050565b604080518082018252611a3b91600091908c906002908390839080828437600092019190915250613728915050565b611a4488613046565b611a4d87613817565b611a5686612f3d565b611a5f856130d3565b611a6884612fb9565b611a706138df565b611a786117f9565b9c9b505050505050505050505050565b62015180420490565b6040805172195e1958dd5d1a5bdb91185a5b1e531a5b5a5d606a1b60208083019190915260609390931b6001600160601b0319166033820152815180820360270181526047909101825280519083012060009081529182905290205490565b6358a8b61360e11b90565b611b0361295f565b6112db816130d3565b600061142082611b7b565b604080516b1b595cdcd859d9519a5e195960a21b602080830191909152602c80830185905283518084039091018152604c909201835281519181019190912060009081526004909152205460ff16919050565b611b7261295f565b6112db81613046565b6040805172666f726569676e546f6b656e4164647265737360681b60208083019190915260609390931b6001600160601b03191660338201528151808203602701815260479091018252805190830120600090815260029092529020546001600160a01b031690565b611bec613936565b826001600160a01b03166369ffa08a83836040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b0316815260200192505050600060405180830381600087803b158015611c4c57600080fd5b505af1158015611c60573d6000803e3d6000fd5b50505050505050565b611c71613936565b6001600160a01b0382161580611c8d5750611c8b8261164b565b155b611c9657600080fd5b61112682826139af565b611ca861295f565b6112db8161356a565b600080611cbd836111c9565b90506000611cca846127a8565b90506000611cda856113c6611a88565b90506000818311611cec576000611cf0565b8183035b9050808410611cff5780611d01565b835b9695505050505050565b611d1361295f565b611d1c8261164b565b611d2557600080fd5b611d2e82611460565b811180611d39575080155b611d4257600080fd5b6040805172195e1958dd5d1a5bdb91185a5b1e531a5b5a5d606a1b6020808301919091526001600160601b0319606086901b16603383015282516027818403018152604783018085528151918301919091206000908152918290529083902084905583905290516001600160a01b038416917f4c177b42dbe934b3abbc0208c11a42e46589983431616f1710ab19969c5ed62e919081900360670190a25050565b611deb612986565b611df484613160565b611e018460018585612e13565b61145a838584846139e9565b7f98aa806e31e94a687a31c65769cb99670064dd7f5a87526da075c5fb4eab988060005260026020527f0c1206883be66049a02d4937078367c00b3d71dd1a9465df969363c6ddeac96d546001600160a01b031690565b7f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c060005260026020527fb7802e97e87ef2842a6cce7da7ffaeaedaa2f61a6a7870b23d9d01fc9b73712e546001600160a01b031690565b611ec361295f565b6112db81612fb9565b6000611ed661239f565b9050806001600160a01b031663cb08a10c836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611f1c57600080fd5b505afa158015611f30573d6000803e3d6000fd5b505050506040513d6020811015611f4657600080fd5b505115611f5257600080fd5b306001600160a01b0316816001600160a01b0316633f9a8e7e846040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611fa057600080fd5b505afa158015611fb4573d6000803e3d6000fd5b505050506040513d6020811015611fca57600080fd5b50516001600160a01b031614611fdf57600080fd5b611fe7611e0d565b6001600160a01b0316816001600160a01b0316634a610b04846040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561203457600080fd5b505afa158015612048573d6000803e3d6000fd5b505050506040513d602081101561205e57600080fd5b50516001600160a01b03161461207357600080fd5b6040805160248082018590528251808303909101815260449091019091526020810180516001600160e01b0316630950d51560e01b908117909152906120ba816001613b56565b5050505050565b6003806001909192565b7f5f5bc4e0b888be22a35f2166061a04607296c26861006b9b8e089a172696a82260005260026020527f60072fd9ffad01d76b1d1421ce17a3613dc06795e4b113745995ad1d84a52121546001600160a01b031690565b60408051670dad2dca0cae4a8f60c31b6020808301919091526001600160601b0319606085901b1660288301528251601c818403018152603c9092018352815191810191909120600090815290819052908120546001600160a01b03831661218b57905061121c565b6000811161219a57600061219d565b60015b60ff169392505050565b60006121b1613d6a565b61220457604080516000815260208101909152825185906014116121f4576121d884613d8f565b90506014845111156121f4578351601319016014850190815291505b6122013387838886613d96565b50505b5060019392505050565b604080516f746f74616c5370656e7450657244617960801b60208083019190915260609490941b6001600160601b031916603082015260448082019390935281518082039093018352606401815281519183019190912060009081529182905290205490565b61167c8383836000806110f5565b604080516861636b4465706c6f7960b81b60208083019190915260609390931b6001600160601b03191660298201528151808203601d018152603d90910182528051908301206000908152600490925290205460ff1690565b60006122e68261164b565b8015611420575060006122f883611b7b565b6001600160a01b03161492915050565b612310612986565b600061231b85611782565b90506123268161164b565b61232f57600080fd5b61233c8160008686612e13565b6120ba848285856139e9565b7f5f86f226cd489cc09187d5f5e0adfb94308af0d4ceac482dd8a8adea9d80daf460005260026020527fab9e97adef29adb9492a44df89badb4a706f8f35202918df21ca61ed056c4868546001600160a01b031690565b7f811bbb11e8899da471f0e69a3ed55090fc90215227fc5fb1cb0d6e962ea7b74f60005260026020527fb4ed64697d3ef8518241966f7c6f28b0d72f20f51198717d198d2d55076c593d546001600160a01b031690565b6123fe613936565b806001600160a01b03811661241257600080fd5b61241b836122db565b61242457600080fd5b600061242f84613ef6565b90506000811161243e57600080fd5b600061244985611cb1565b90506000811161245857600080fd5b80821115612464578091505b61247685612470611a88565b84613f4a565b6040805160008082526020820190925260609161249891889088908790613fc8565b905060006124a7826001613b56565b9050611c6081888887614643565b7f779a349c5bee7817f04c960f525ee3e2f2516078c38c68a3149787976ee837e560005260026020527fc155b21a14c4592b97825e495fbe0d2705fb46420018cac5bfa7a09c43fae517546001600160a01b031690565b612514612986565b60006125248b8b8b8b8b8b61321c565b90506125338160008787612e13565b61257585828686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506139e992505050565b5050505050505050505050565b61145a848484846127fe565b61259661295f565b61259f8261164b565b6125a857600080fd5b8015806125ce57506125b982612122565b811180156125ce57506125cb826127a8565b81105b6125d757600080fd5b60408051670dac2f0a0cae4a8f60c31b60208083019190915260609490941b6001600160601b03191660288201528151808203601c018152603c909101825280519084012060009081529283905290912055565b600061142082611782565b7f269c5905f777ee6391c7a361d17039a7d62f52ba9fffeb98c5ade342705731a360005260026020527f15c764a0cd4bb3d72a49abedd3d6793c3b93c0d57f43174a348b443be86f79c1546001600160a01b031690565b61269561295f565b61269e8261164b565b6126a757600080fd5b6000811180156126be57506126bb826127a8565b81105b80156126d157506126ce826111c9565b81105b6126da57600080fd5b60408051670dad2dca0cae4a8f60c31b60208083019190915260609490941b6001600160601b03191660288201528151808203601c018152603c909101825280519084012060009081529283905290912055565b6040805172746f74616c457865637574656450657244617960681b60208083019190915260609490941b6001600160601b031916603382015260478082019390935281518082039093018352606701815281519183019190912060009081529182905290205490565b61279f61295f565b6112db81613817565b604080516919185a5b1e531a5b5a5d60b21b60208083019190915260609390931b6001600160601b031916602a8201528151808203601e018152603e909101825280519083012060009081529182905290205490565b612806613d6a565b1561281057600080fd5b6000846001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561285f57600080fd5b505afa158015612873573d6000803e3d6000fd5b505050506040513d602081101561288957600080fd5b5051905061289760016146b3565b6128ac6001600160a01b0386163330866146d7565b6128b660006146b3565b600061293b82876001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561290957600080fd5b505afa15801561291d573d6000803e3d6000fd5b505050506040513d602081101561293357600080fd5b505190614731565b90508381111561294a57600080fd5b6129578633878487613d96565b505050505050565b612967611e64565b6001600160a01b0316336001600160a01b03161461298457600080fd5b565b600061299061239f565b9050336001600160a01b038216146129a757600080fd5b6129af611e0d565b6001600160a01b0316816001600160a01b031663d67bdd256040518163ffffffff1660e01b815260040160206040518083038186803b1580156129f157600080fd5b505afa158015612a05573d6000803e3d6000fd5b505050506040513d6020811015612a1b57600080fd5b50516001600160a01b0316146112db57600080fd5b604080516b36b2b9b9b0b3b2aa37b5b2b760a11b602080830191909152602c80830185905283518084039091018152604c90920183528151918101919091206000908152600290915220546001600160a01b0316919050565b604080516f1b595cdcd859d9549958da5c1a595b9d60821b602080830191909152603080830185905283518084039091018152605090920183528151918101919091206000908152600290915220546001600160a01b0316919050565b604080516b6d65737361676556616c756560a01b602080830191909152602c80830185905283518084039091018152604c90920183528151918101919091206000908152908190522054919050565b604080516b1b595cdcd859d9519a5e195960a21b602080830191909152602c8083019490945282518083039094018452604c9091018252825192810192909220600090815260049092529020805460ff19166001179055565b61167c6000612b9c85611b7b565b6001600160a01b03161484848485614773565b612bb8816147c7565b612bc157600080fd5b7f811bbb11e8899da471f0e69a3ed55090fc90215227fc5fb1cb0d6e962ea7b74f60005260026020527fb4ed64697d3ef8518241966f7c6f28b0d72f20f51198717d198d2d55076c593d80546001600160a01b0319166001600160a01b0392909216919091179055565b826001600160a01b03166340c10f1983836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015612c8257600080fd5b505af1158015612c96573d6000803e3d6000fd5b505050506040513d6020811015612cac57600080fd5b505161167c57600080fd5b604080516f686f6d65546f6b656e4164647265737360801b6020808301919091526001600160601b0319606086811b82166030850152845160248186030181526044850186528051908401206000908152600280855286822080546001600160a01b03808b166001600160a01b0319928316811790935572666f726569676e546f6b656e4164647265737360681b60648a0152948a901b90951660778801528751606b818903018152608b909701808952875197870197909720835294529485208054909216908716908117909155909290917f78d063210f4fb6b4cc932390bb8045fa2465e51349590182dab8b9e84c57a6ee9190a35050565b600082820183811015612e0c576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b612e1b613d6a565b15612e2557600080fd5b612e2f848261184a565b612e3857600080fd5b612e4a84612e44611a88565b83614803565b806000612e7a7f03be2b2875cb41e0e77355e802a16769bb8dfcf825061cde185c73bf94f1262586838986614884565b90506000612e86614c2f565b90508115612edb5760408051838152905182916001600160a01b038a16917fd560a522f77cfb4924d6fe51be1615e540a48a8931c48fe0349c7f47ebabe7479181900360200190a3612ed88383614731565b92505b612ee88688878688614773565b80856001600160a01b0316886001600160a01b03167f9afd47907e25028cdaca89d193518c302bbb128617d5a992c5abd45815526593866040518082815260200191505060405180910390a450505050505050565b612f46816147c7565b612f4f57600080fd5b7f269c5905f777ee6391c7a361d17039a7d62f52ba9fffeb98c5ade342705731a360005260026020527f15c764a0cd4bb3d72a49abedd3d6793c3b93c0d57f43174a348b443be86f79c180546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0381161580612fd35750612fd3816147c7565b612fdc57600080fd5b7f5f86f226cd489cc09187d5f5e0adfb94308af0d4ceac482dd8a8adea9d80daf460005260026020527fab9e97adef29adb9492a44df89badb4a706f8f35202918df21ca61ed056c486880546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b03811615806130605750613060816147c7565b61306957600080fd5b7f5f5bc4e0b888be22a35f2166061a04607296c26861006b9b8e089a172696a82260005260026020527f60072fd9ffad01d76b1d1421ce17a3613dc06795e4b113745995ad1d84a5212180546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b03811615806130ed57506130ed816147c7565b6130f657600080fd5b7f779a349c5bee7817f04c960f525ee3e2f2516078c38c68a3149787976ee837e560005260026020527fc155b21a14c4592b97825e495fbe0d2705fb46420018cac5bfa7a09c43fae51780546001600160a01b0319166001600160a01b0392909216919091179055565b604080516861636b4465706c6f7960b81b6020808301919091526001600160601b0319606085901b1660298301528251601d818403018152603d909201835281519181019190912060009081526004909152205460ff166112db57604080516861636b4465706c6f7960b81b6020808301919091526001600160601b0319606085901b1660298301528251601d818403018152603d90920183528151918101919091206000908152600490915220805460ff1916600117905550565b60008061322888611782565b90506001600160a01b0381166134cf57606087878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8b01819004810282018101909252898152939450606093925089915088908190840183828082843760009201919091525050845192935050501515806132bd575060008151115b6132c657600080fd5b81516132d4578091506132dd565b80516132dd5750805b6132e682614ca2565b91506132f0612636565b6001600160a01b031663a39d6acf83838861330961239f565b6001600160a01b0316631544298e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561334157600080fd5b505afa158015613355573d6000803e3d6000fd5b505050506040513d602081101561336b57600080fd5b50516040516001600160e01b031960e087901b16815260ff831660448201526064810182905260806004820190815285516084830152855190918291602482019160a40190602089019080838360005b838110156133d35781810151838201526020016133bb565b50505050905090810190601f1680156134005780820380516001836020036101000a031916815260200191505b50838103825286518152865160209182019188019080838360005b8381101561343357818101518382015260200161341b565b50505050905090810190601f1680156134605780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b15801561348357600080fd5b505af1158015613497573d6000803e3d6000fd5b505050506040513d60208110156134ad57600080fd5b505192506134bb8a84612cb7565b6134c8838660ff16614d57565b505061355f565b6134d88161164b565b61355f578260ff16816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561351957600080fd5b505afa15801561352d573d6000803e3d6000fd5b505050506040513d602081101561354357600080fd5b505160ff161461355257600080fd5b61355f818460ff16614d57565b979650505050505050565b7f98aa806e31e94a687a31c65769cb99670064dd7f5a87526da075c5fb4eab988060005260026020527f0c1206883be66049a02d4937078367c00b3d71dd1a9465df969363c6ddeac96d80546001600160a01b0319166001600160a01b0392909216919091179055565b6040810151158015906135ee575060408101516020820151115b80156135fe575060208101518151115b61360757600080fd5b8051604080516919185a5b1e531a5b5a5d60b21b602082810191909152606086901b6001600160601b031916602a83018190528351808403601e018152603e8401855280519083012060009081528083528481209590955581860151670dac2f0a0cae4a8f60c31b605e850152606684018290528451605a818603018152607a8501865280519084012086528583528486205583860151670dad2dca0cae4a8f60c31b609a85015260a28401919091528351609681850301815260b690930184528251928201929092208452839052908220556001600160a01b038316907fca0b3dabefdbd8c72c0a9cf4a6e9d107da897abf036ef3f3f3b010cdd25941599083905b60200201516040518082815260200191505060405180910390a25050565b805160208201511061373957600080fd5b80516040805172195e1958dd5d1a5bdb91185a5b1e531a5b5a5d606a1b602082810191909152606086901b6001600160601b031916603383018190528351808403602701815260478401855280519083012060009081528083528481209590955581860151700caf0cac6eae8d2dedc9ac2f0a0cae4a8f607b1b606785015260788401919091528351606c818503018152608c90930184528251928201929092208452839052908220556001600160a01b038316907f4c177b42dbe934b3abbc0208c11a42e46589983431616f1710ab19969c5ed62e90839061370a565b6001600160a01b03811661382a57600080fd5b7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0613853611e64565b604080516001600160a01b03928316815291841660208301528051918290030190a17f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c060005260026020527fb7802e97e87ef2842a6cce7da7ffaeaedaa2f61a6a7870b23d9d01fc9b73712e80546001600160a01b0319166001600160a01b0392909216919091179055565b7f0a6f646cd611241d8073675e00d1a1ff700fbf1b53fcf473de56d1e6e4b714ba60005260046020527f078d888f9b66f3f8bfa10909e31f1e16240db73449f0500afdbbe3a70da457cc805460ff19166001179055565b306001600160a01b0316636fde82026040518163ffffffff1660e01b815260040160206040518083038186803b15801561396f57600080fd5b505afa158015613983573d6000803e3d6000fd5b505050506040513d602081101561399957600080fd5b50516001600160a01b0316331461298457600080fd5b806001600160a01b0381166139c357600080fd5b6001600160a01b0383166139df576139da82614edb565b61167c565b61167c8383614ee6565b6139f2846147c7565b1561145a57836001600160a01b031663db7af85460e01b84848460405160240180846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015613a61578181015183820152602001613a49565b50505050905090810190601f168015613a8e5780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990991698909817885251815191979096508695509350915081905083835b60208310613af45780518252601f199092019160209182019101613ad5565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611c60576040519150601f19603f3d011682016040523d82523d6000602084013e611c60565b600080613b61611e0d565b90506000613b6e85614f73565b90506000613b7a61239f565b905084613c7357806001600160a01b03166394643f718488856040518463ffffffff1660e01b815260040180846001600160a01b0316815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015613bf4578181015183820152602001613bdc565b50505050905090810190601f168015613c215780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b158015613c4257600080fd5b505af1158015613c56573d6000803e3d6000fd5b505050506040513d6020811015613c6c57600080fd5b5051611d01565b806001600160a01b031663dc8601b38488856040518463ffffffff1660e01b815260040180846001600160a01b0316815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015613ce6578181015183820152602001613cce565b50505050905090810190601f168015613d135780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b158015613d3457600080fd5b505af1158015613d48573d6000803e3d6000fd5b505050506040513d6020811015613d5e57600080fd5b50519695505050505050565b7f6168652c307c1e813ca11cfb3a601f1cf3b22452021a5052d8b05f1f1f8a3e925490565b6014015190565b6001600160a01b03831615801590613dc75750613db1611e0d565b6001600160a01b0316836001600160a01b031614155b613dd057600080fd5b613dd98561164b565b613df9576000613de8866150a7565b9050613df7868260ff16614d57565b505b613e0385836113b3565b613e0c57600080fd5b613e1885612470611a88565b6000613e2386611b7b565b90506000613e5e7f741ede137d0537e88e0ea0ff25b1f22d837903dbbee8980b4a06e8523247ee266001600160a01b03841615888a88614884565b90506000613e6c8583614731565b90506060613e7d848a898589613fc8565b90506000613e9582613e908c8c8c615275565b613b56565b9050613ea3818b8b86614643565b8315613eea5760408051858152905182916001600160a01b038d16917fd560a522f77cfb4924d6fe51be1615e540a48a8931c48fe0349c7f47ebabe7479181900360200190a35b50505050505050505050565b6000611420613f04836114bd565b604080516370a0823160e01b815230600482015290516001600160a01b038616916370a08231916024808301926020929190829003018186803b15801561290957600080fd5b613f58816113cb858561220e565b600080858560405160200180806f746f74616c5370656e7450657244617960801b815250601001836001600160a01b031660601b81526014018281526020019250505060405160208183030381529060405280519060200120815260200190815260200160002081905550505050565b606060008083511180613fed57506000356001600160e01b03191663d740548160e01b145b90506001600160a01b0387166144a8576140138661400e866113cb8a6114bd565b615324565b61401c86612282565b15614159578061407a57604080516001600160a01b0380891660248301528716604482015260648082018790528251808303909101815260849091019091526020810180516001600160e01b031663125e4cfb60e01b179052614151565b63c534576160e01b8686868660405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156140ea5781810151838201526020016140d2565b50505050905090810190601f1680156141175780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909916989098179097525050505050505b91505061463a565b6000614164876150a7565b905060606141718861537f565b9050606061417e89615545565b9050600082511180614191575060008151115b61419a57600080fd5b836142ed57632ae87cdd60e01b898383868c8c60405160240180876001600160a01b0316815260200180602001806020018660ff168152602001856001600160a01b03168152602001848152602001838103835288818151815260200191508051906020019080838360005b8381101561421e578181015183820152602001614206565b50505050905090810190601f16801561424b5780820380516001836020036101000a031916815260200191505b50838103825287518152875160209182019189019080838360005b8381101561427e578181015183820152602001614266565b50505050905090810190601f1680156142ab5780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909c169b909b17909a525061449d975050505050505050565b63d522cfd760e01b898383868c8c8c60405160240180886001600160a01b0316815260200180602001806020018760ff168152602001866001600160a01b031681526020018581526020018060200184810384528a818151815260200191508051906020019080838360005b83811015614371578181015183820152602001614359565b50505050905090810190601f16801561439e5780820380516001836020036101000a031916815260200191505b5084810383528951815289516020918201918b019080838360005b838110156143d15781810151838201526020016143b9565b50505050905090810190601f1680156143fe5780820380516001836020036101000a031916815260200191505b50848103825285518152855160209182019187019080838360005b83811015614431578181015183820152602001614419565b50505050905090810190601f16801561445e5780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909e169d909d17909c5250505050505050505050505b94505050505061463a565b856001600160a01b03166342966c68856040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156144ee57600080fd5b505af1158015614502573d6000803e3d6000fd5b505050508061455f57604080516001600160a01b03808a1660248301528716604482015260648082018790528251808303909101815260849091019091526020810180516001600160e01b031663272255bb60e01b179052614636565b63867f7a4d60e01b8786868660405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156145cf5781810151838201526020016145b7565b50505050905090810190601f1680156145fc5780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909916989098179097525050505050505b9150505b95945050505050565b61464d8484615678565b61465784836156e4565b6146618482615754565b83826001600160a01b0316846001600160a01b03167f59a9a8027b9c87b961e254899821c9a276b5efc35d1f7409ea4f291470f1629a846040518082815260200191505060405180910390a450505050565b7f6168652c307c1e813ca11cfb3a601f1cf3b22452021a5052d8b05f1f1f8a3e9255565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b17905261145a9085906157a3565b6000612e0c83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250615854565b84156147a95761478d6001600160a01b03851684846158eb565b6147a48461400e8361479e886114bd565b90614731565b6120ba565b6120ba83836147b78761593d565b6001600160a01b03169190612c2b565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708181148015906147fb57508115155b949350505050565b614811816113cb858561272e565b6000808585604051602001808072746f74616c457865637574656450657244617960681b815250601301836001600160a01b031660601b81526014018281526020019250505060405160208183030381529060405280519060200120815260200190815260200160002081905550505050565b60008061488f6124b5565b90506001600160a01b03811615614c22577f741ede137d0537e88e0ea0ff25b1f22d837903dbbee8980b4a06e8523247ee26871480156149445750806001600160a01b031663071664c5866040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561491757600080fd5b505afa15801561492b573d6000803e3d6000fd5b505050506040513d602081101561494157600080fd5b50515b1561495357600091505061463a565b6000816001600160a01b031663710c60138987876040518463ffffffff1660e01b815260040180848152602001836001600160a01b03168152602001828152602001935050505060206040518083038186803b1580156149b257600080fd5b505afa1580156149c6573d6000803e3d6000fd5b505050506040513d60208110156149dc57600080fd5b505190508015614c19577f741ede137d0537e88e0ea0ff25b1f22d837903dbbee8980b4a06e8523247ee26881415614a2757614a226001600160a01b03861683836158eb565b614bb1565b600087614a3b576340c10f1960e01b614a44565b63a9059cbb60e01b5b604080516001600160a01b038681166024830152604480830187905283518084039091018152606490920183526020820180516001600160e01b03166001600160e01b0319861617815292518251949550600094606094928c16939282918083835b60208310614ac55780518252601f199092019160209182019101614aa6565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114614b27576040519150601f19603f3d011682016040523d82523d6000602084013e614b2c565b606091505b509150915081614b83576040805185815290516001600160a01b038a16917fb8842ee9d1603ef0f5620c01feb6cf2e7921091eba728cbce562041a86ee109a919081900360200190a260009550505050505061463a565b80511580614ba45750808060200190516020811015614ba157600080fd5b50515b614bad57600080fd5b5050505b816001600160a01b0316634e281a7b866040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b158015614c0057600080fd5b505af1158015614c14573d6000803e3d6000fd5b505050505b915061463a9050565b5060009695505050505050565b6000614c3961239f565b6001600160a01b031663669f618b6040518163ffffffff1660e01b815260040160206040518083038186803b158015614c7157600080fd5b505afa158015614c85573d6000803e3d6000fd5b505050506040513d6020811015614c9b57600080fd5b5051905090565b606080827f2066726f6d204d61696e6e6574000000000000000000000000000000000000006040516020018083805190602001908083835b60208310614cf95780518252601f199092019160209182019101614cda565b51815160209384036101000a60001901801990921691161790529201938452506040805180850381529390910190525093517f000000000000000000000000000000000000000000000000000000000000000d018452509192915050565b60006012821015614e4b5781601203600a0a90506000614d8182614d7b6000612122565b90615983565b90506000614d9383614d7b60006111c9565b90506000614da584614d7b60006127a8565b90506000614db785614d7b6000611460565b90506000614dc986614d7b6000611a91565b905084614dff5760019450848411614dff5760649350606491508383111580614df25750818111155b15614dff57506127109150815b614e23886040518060600160405280868152602001878152602001888152506135d4565b614e4188604051806040016040528084815260200185815250613728565b505050505061167c565b60128203600a0a9050614ea4836040518060600160405280614e7785614e7160006127a8565b906159c5565b8152602001614e8a85614e7160006111c9565b8152602001614e9d85614e716000612122565b90526135d4565b61167c836040518060400160405280614ec185614e716000611a91565b8152602001614ed485614e716000611460565b9052613728565b476111268282615a1e565b604080516370a0823160e01b8152306004820152905183916000916001600160a01b038416916370a08231916024808301926020929190829003018186803b158015614f3157600080fd5b505afa158015614f45573d6000803e3d6000fd5b505050506040513d6020811015614f5b57600080fd5b5051905061145a6001600160a01b03831684836158eb565b600080614f7e6120cb565b90506001600160a01b03811661500357614f9661239f565b6001600160a01b031663e5789d036040518163ffffffff1660e01b815260040160206040518083038186803b158015614fce57600080fd5b505afa158015614fe2573d6000803e3d6000fd5b505050506040513d6020811015614ff857600080fd5b5051915061121c9050565b60405163fb47201960e01b81526020600482018181528551602484015285516001600160a01b0385169363fb4720199388939283926044019185019080838360005b8381101561505d578181015183820152602001615045565b50505050905090810190601f16801561508a5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b158015614fce57600080fd5b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b1781529151815160009384936060936001600160a01b03881693919290918291908083835b602083106151105780518252601f1990920191602091820191016150f1565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114615170576040519150601f19603f3d011682016040523d82523d6000602084013e615175565b606091505b5091509150816152565760408051600481526024810182526020810180516001600160e01b0316632e0f262560e01b178152915181516001600160a01b0388169382918083835b602083106151db5780518252601f1990920191602091820191016151bc565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d806000811461523b576040519150601f19603f3d011682016040523d82523d6000602084013e615240565b606091505b509092509050816152565760009250505061121c565b80806020019051602081101561526b57600080fd5b5051949350505050565b600080615280612348565b90506001600160a01b038116158061463a57506040805163f7baa04960e01b81526001600160a01b03878116600483015286811660248301528581166044830152915160009284169163f7baa049916064808301926020929190829003018186803b1580156152ee57600080fd5b505afa158015615302573d6000803e3d6000fd5b505050506040513d602081101561531857600080fd5b50511395945050505050565b604080516e6d65646961746f7242616c616e636560881b60208083019190915260609490941b6001600160601b031916602f820152815180820360230181526043909101825280519084012060009081529283905290912055565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b1781529151815160609360009385936001600160a01b03881693919290918291908083835b602083106153e85780518252601f1990920191602091820191016153c9565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114615448576040519150601f19603f3d011682016040523d82523d6000602084013e61544d565b606091505b50915091508161553c5760408051600481526024810182526020810180516001600160e01b03166351fa6fbf60e11b178152915181516001600160a01b0388169382918083835b602083106154b35780518252601f199092019160209182019101615494565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114615513576040519150601f19603f3d011682016040523d82523d6000602084013e615518565b606091505b5090925090508161553c57604051806020016040528060008152509250505061121c565b6147fb81615a83565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b1781529151815160609360009385936001600160a01b03881693919290918291908083835b602083106155ae5780518252601f19909201916020918201910161558f565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d806000811461560e576040519150601f19603f3d011682016040523d82523d6000602084013e615613565b606091505b50915091508161553c5760408051600481526024810182526020810180516001600160e01b0316631eedf1af60e31b178152915181516001600160a01b038816938291808383602083106154b35780518252601f199092019160209182019101615494565b604080516b36b2b9b9b0b3b2aa37b5b2b760a11b602080830191909152602c8083019590955282518083039095018552604c90910182528351938101939093206000908152600290935290912080546001600160a01b0319166001600160a01b03909216919091179055565b604080516f1b595cdcd859d9549958da5c1a595b9d60821b60208083019190915260308083019590955282518083039095018552605090910182528351938101939093206000908152600290935290912080546001600160a01b0319166001600160a01b03909216919091179055565b604080516b6d65737361676556616c756560a01b602080830191909152602c8083019590955282518083039095018552604c909101825283519381019390932060009081529283905290912055565b60606157f8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316615bdf9092919063ffffffff16565b80519091501561167c5780806020019051602081101561581757600080fd5b505161167c5760405162461bcd60e51b815260040180806020018281038252602a815260200180615e20602a913960400191505060405180910390fd5b600081848411156158e35760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156158a8578181015183820152602001615890565b50505050905090810190601f1680156158d55780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261167c9084906157a3565b60006001600160a01b03821673b7d311e2eb55f2f68a9440da38e7989210b9a05e141561597f575073857dd07866c1e19eb2cdfcef7ae655ce7f9e560d61121c565b5090565b6000612e0c83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250615bee565b6000826159d457506000611420565b828202828482816159e157fe5b0414612e0c5760405162461bcd60e51b8152600401808060200182810382526021815260200180615dff6021913960400191505060405180910390fd5b6040516001600160a01b0383169082156108fc029083906000818181858888f19350505050611126578082604051615a5590615dc0565b6001600160a01b039091168152604051908190036020019082f090508015801561145a573d6000803e3d6000fd5b6060602082511115615b5957818060200190516020811015615aa457600080fd5b8101908080516040519392919084600160201b821115615ac357600080fd5b908301906020820185811115615ad857600080fd5b8251600160201b811182820188101715615af157600080fd5b82525081516020918201929091019080838360005b83811015615b1e578181015183820152602001615b06565b50505050905090810190601f168015615b4b5780820380516001836020036101000a031916815260200191505b50604052505050905061121c565b815160201415615bca576000828060200190516020811015615b7a57600080fd5b50516040805160208082528183019092529192506060919060208201818036833701905050905060008260208301525b8215615bbf5760089290921b91600101615baa565b8152915061121c9050565b5060408051602081019091526000815261121c565b60606147fb8484600085615c53565b60008183615c3d5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156158a8578181015183820152602001615890565b506000838581615c4957fe5b0495945050505050565b6060615c5e856147c7565b615caf576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b60208310615cee5780518252601f199092019160209182019101615ccf565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114615d50576040519150601f19603f3d011682016040523d82523d6000602084013e615d55565b606091505b50915091508115615d695791506147fb9050565b805115615d795780518082602001fd5b60405162461bcd60e51b81526020600482018181528651602484015286518793919283926044019190850190808383600083156158a8578181015183820152602001615890565b603280615dcd8339019056fe60806040526040516032380380603283398181016040526020811015602357600080fd5b50516001600160a01b038116fffe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a264697066735822122016ad8a7dfc627988e4caf299120e2273aae2be383102b8f744ab97c4389ae59364736f6c63430007050033", + "linkReferences": {}, + "deployedLinkReferences": {} +} \ No newline at end of file diff --git a/operate/data/contracts/home_omnibridge/contract.py b/operate/data/contracts/home_omnibridge/contract.py new file mode 100644 index 00000000..bf2080ce --- /dev/null +++ b/operate/data/contracts/home_omnibridge/contract.py @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2024 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ + +"""This module contains the class to connect to the `ForeignOmnibridge` contract.""" + +from typing import Optional, cast + +import eth_abi +from aea.configurations.base import PublicId +from aea.contracts.base import Contract +from aea.crypto.base import LedgerApi +from aea_ledger_ethereum import EthereumApi +from web3 import Web3 +from web3.types import BlockIdentifier + + +class HomeOmnibridge(Contract): + """HomeOmnibridge.""" + + contract_id = PublicId.from_str("valory/home_omnibridge:0.1.0") + + @classmethod + def find_tokens_bridged_tx( + cls, + ledger_api: LedgerApi, + contract_address: str, + token: str, + recipient: str, + value: int, + message_id: bytes, + from_block: BlockIdentifier = "earliest", + to_block: BlockIdentifier = "latest", + ) -> Optional[str]: + """Return the transaction hash of the matching TokensBridged event in the given block range.""" + ledger_api = cast(EthereumApi, ledger_api) + event_signature = "TokensBridged(address,address,uint256,bytes32)" + event_signature_hash = Web3.keccak(text=event_signature).hex() + + topics = [ + event_signature_hash, # TokensBridged + "0x" + token.lower()[2:].rjust(64, "0"), # token + "0x" + recipient.lower()[2:].rjust(64, "0"), # recipient + "0x" + message_id.hex().rjust(64, "0"), # messageId + ] + non_indexed_types = ["uint256"] + non_indexed_values = [ + value, # value + ] + + logs = ledger_api.api.eth.get_logs( + { + "fromBlock": from_block, + "toBlock": to_block, + "address": contract_address, + "topics": topics, + } + ) + + for log in logs: + decoded = eth_abi.decode(non_indexed_types, log["data"]) + if all(a == b for a, b in zip(decoded, non_indexed_values)): + return log["transactionHash"].hex() + + return None diff --git a/operate/data/contracts/home_omnibridge/contract.yaml b/operate/data/contracts/home_omnibridge/contract.yaml new file mode 100644 index 00000000..a628b2fd --- /dev/null +++ b/operate/data/contracts/home_omnibridge/contract.yaml @@ -0,0 +1,23 @@ +name: home_omnibridge +author: valory +version: 0.1.0 +type: contract +description: HomeOmnibridge +license: Apache-2.0 +aea_version: '>=1.0.0, <2.0.0' +fingerprint: + __init__.py: bafybeigrlrmwk3dhnoe4o5ovygtmudik7ybhsx2etqqjpvdi65rtlfpuhe + build/HomeOmnibridge.json: bafybeihm4ff4mhoca2iwcogg5srqe2x6p674uxxc3v5dcci4emxfgc7qpm + contract.py: bafybeignqvstktpvbliopzztan4a46crvf3ig5o4yt4fxhjpgljtlyrzga +fingerprint_ignore_patterns: [] +contracts: [] +class_name: HomeOmnibridge +contract_interface_paths: + ethereum: build/HomeOmnibridge.json +dependencies: + open-aea-ledger-ethereum: + version: ==1.60.0 + open-aea-test-autonomy: + version: ==0.18.3 + web3: + version: <7,>=6.0.0 diff --git a/operate/data/contracts/l1_standard_bridge/__init__.py b/operate/data/contracts/l1_standard_bridge/__init__.py new file mode 100644 index 00000000..a87c4a4f --- /dev/null +++ b/operate/data/contracts/l1_standard_bridge/__init__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2024 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ + +"""This module contains the support resources for the `L1StandardBridge` contract.""" diff --git a/operate/data/contracts/l1_standard_bridge/build/L1StandardBridge.json b/operate/data/contracts/l1_standard_bridge/build/L1StandardBridge.json new file mode 100644 index 00000000..3366c1f2 --- /dev/null +++ b/operate/data/contracts/l1_standard_bridge/build/L1StandardBridge.json @@ -0,0 +1,831 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "L1StandardBridge", + "sourceName": "L1StandardBridge.sol", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "localToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "remoteToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ERC20BridgeFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "localToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "remoteToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ERC20BridgeInitiated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "l2Token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ERC20DepositInitiated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "l2Token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ERC20WithdrawalFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ETHBridgeFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ETHBridgeInitiated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ETHDepositInitiated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ETHWithdrawalFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "inputs": [], + "name": "MESSENGER", + "outputs": [ + { + "internalType": "contract ICrossDomainMessenger", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "OTHER_BRIDGE", + "outputs": [ + { + "internalType": "contract StandardBridge", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_localToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "bridgeERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_localToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "bridgeERC20To", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "bridgeETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "bridgeETHTo", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "address", + "name": "_l2Token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "depositERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "address", + "name": "_l2Token", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "depositERC20To", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "depositETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "depositETHTo", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "deposits", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_localToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "finalizeBridgeERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "finalizeBridgeETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "address", + "name": "_l2Token", + "type": "address" + }, + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "finalizeERC20Withdrawal", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "finalizeETHWithdrawal", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ICrossDomainMessenger", + "name": "_messenger", + "type": "address" + }, + { + "internalType": "contract ISuperchainConfig", + "name": "_superchainConfig", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "l2TokenBridge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "messenger", + "outputs": [ + { + "internalType": "contract ICrossDomainMessenger", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "otherBridge", + "outputs": [ + { + "internalType": "contract StandardBridge", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "superchainConfig", + "outputs": [ + { + "internalType": "contract ISuperchainConfig", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": "", + "deployedBytecode": "0x6080604052600436106101795760003560e01c80637f46ddb2116100cb578063927ede2d1161007f578063b1a1a88211610059578063b1a1a88214610503578063c89701a214610516578063e11013dd1461054357600080fd5b8063927ede2d146104a55780639a2ac6d5146104d0578063a9f9e675146104e357600080fd5b806387087623116100b0578063870876231461043f5780638f601f661461045f57806391c49bf8146103f457600080fd5b80637f46ddb2146103f4578063838b25201461041f57600080fd5b80633cb747bf1161012d57806354fd4d501161010757806354fd4d501461035957806358a997f6146103af5780635c975abb146103cf57600080fd5b80633cb747bf146102ec578063485cc95514610319578063540abf731461033957600080fd5b80631532ec341161015e5780631532ec341461026f5780631635f5fd1461028257806335e80ab31461029557600080fd5b80630166a07a1461023c57806309fc88431461025c57600080fd5b3661023757610186610556565b610217576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b610235333362030d4060405180602001604052806000815250610593565b005b600080fd5b34801561024857600080fd5b50610235610257366004612777565b6105a6565b61023561026a366004612828565b6109c0565b61023561027d36600461287b565b610a9c565b61023561029036600461287b565b610ab0565b3480156102a157600080fd5b506032546102c29073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156102f857600080fd5b506003546102c29073ffffffffffffffffffffffffffffffffffffffff1681565b34801561032557600080fd5b506102356103343660046128ee565b610f79565b34801561034557600080fd5b50610235610354366004612927565b611162565b34801561036557600080fd5b506103a26040518060400160405280600581526020017f322e332e3000000000000000000000000000000000000000000000000000000081525081565b6040516102e39190612a14565b3480156103bb57600080fd5b506102356103ca366004612a27565b6111a7565b3480156103db57600080fd5b506103e4611280565b60405190151581526020016102e3565b34801561040057600080fd5b5060045473ffffffffffffffffffffffffffffffffffffffff166102c2565b34801561042b57600080fd5b5061023561043a366004612927565b611319565b34801561044b57600080fd5b5061023561045a366004612a27565b61135e565b34801561046b57600080fd5b5061049761047a3660046128ee565b600260209081526000928352604080842090915290825290205481565b6040519081526020016102e3565b3480156104b157600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff166102c2565b6102356104de366004612aaa565b611437565b3480156104ef57600080fd5b506102356104fe366004612777565b611479565b610235610511366004612828565b611488565b34801561052257600080fd5b506004546102c29073ffffffffffffffffffffffffffffffffffffffff1681565b610235610551366004612aaa565b61155e565b60003233036105655750600190565b333b60170361058d57604051602081016040526020600082333c5160e81c62ef010014905090565b50600090565b6105a084843485856115a1565b50505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610679575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa15801561063d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106619190612b0d565b73ffffffffffffffffffffffffffffffffffffffff16145b61072b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a40161020e565b610733611280565b1561079a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616e646172644272696467653a2070617573656400000000000000000000604482015260640161020e565b6107a38761176b565b156108f1576107b287876117cd565b610864576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a40161020e565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156108d457600080fd5b505af11580156108e8573d6000803e3d6000fd5b50505050610973565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461092f908490612b59565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c16835293905291909120919091556109739085856118ed565b6109b7878787878787878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506119c192505050565b50505050505050565b6109c8610556565b610a54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f41000000000000000000606482015260840161020e565b610a973333348686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506115a192505050565b505050565b610aa98585858585610ab0565b5050505050565b60035473ffffffffffffffffffffffffffffffffffffffff1633148015610b83575060048054600354604080517f6e296e45000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff938416949390921692636e296e459282820192602092908290030181865afa158015610b47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b6b9190612b0d565b73ffffffffffffffffffffffffffffffffffffffff16145b610c35576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a40161020e565b610c3d611280565b15610ca4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f5374616e646172644272696467653a2070617573656400000000000000000000604482015260640161020e565b823414610d33576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e74207265717569726564000000000000606482015260840161020e565b3073ffffffffffffffffffffffffffffffffffffffff851603610dd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c660000000000000000000000000000000000000000000000000000000000606482015260840161020e565b60035473ffffffffffffffffffffffffffffffffffffffff90811690851603610e83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e676572000000000000000000000000000000000000000000000000606482015260840161020e565b610ec585858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a4f92505050565b6000610ee2855a8660405180602001604052806000815250611ac2565b905080610f71576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c65640000000000000000000000000000000000000000000000000000000000606482015260840161020e565b505050505050565b600054610100900460ff1615808015610f995750600054600160ff909116105b80610fb35750303b158015610fb3575060005460ff166001145b61103f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161020e565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561109d57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161790556110fb83734200000000000000000000000000000000000010611ada565b8015610a9757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b6109b787873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bc492505050565b6111af610556565b61123b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f41000000000000000000606482015260840161020e565b610f7186863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611f7d92505050565b603254604080517f5c975abb000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff1691635c975abb9160048083019260209291908290030181865afa1580156112f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113149190612b70565b905090565b6109b787873388888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611f7d92505050565b611366610556565b6113f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f41000000000000000000606482015260840161020e565b610f7186863333888888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bc492505050565b6105a033858585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061059392505050565b6109b7878787878787876105a6565b611490610556565b61151c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f41000000000000000000606482015260840161020e565b610a9733338585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061059392505050565b6105a03385348686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506115a192505050565b823414611630576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c75650000606482015260840161020e565b61163c85858584611f8c565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9287929116907f1635f5fd000000000000000000000000000000000000000000000000000000009061169f908b908b9086908a90602401612b92565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b909216825261173292918890600401612bdb565b6000604051808303818588803b15801561174b57600080fd5b505af115801561175f573d6000803e3d6000fd5b50505050505050505050565b6000611797827f1d1d8b6300000000000000000000000000000000000000000000000000000000611fff565b806117c757506117c7827fec4fc8e300000000000000000000000000000000000000000000000000000000611fff565b92915050565b60006117f9837f1d1d8b6300000000000000000000000000000000000000000000000000000000611fff565b156118a2578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa158015611849573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061186d9190612b0d565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161490506117c7565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa158015611849573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a979084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612022565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b3868686604051611a3993929190612c20565b60405180910390a4610f7186868686868661212e565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e6318484604051611aae929190612c5e565b60405180910390a36105a0848484846121b6565b6000806000835160208501868989f195945050505050565b600054610100900460ff16611b71576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161020e565b6003805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560048054929093169116179055565b3415611c52576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f5374616e646172644272696467653a2063616e6e6f742073656e642076616c7560448201527f6500000000000000000000000000000000000000000000000000000000000000606482015260840161020e565b611c5b8761176b565b15611da957611c6a87876117cd565b611d1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a40161020e565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b158015611d8c57600080fd5b505af1158015611da0573d6000803e3d6000fd5b50505050611e3d565b611dcb73ffffffffffffffffffffffffffffffffffffffff8816863086612223565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a1683529290522054611e09908490612c77565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b611e4b878787878786612281565b60035460045460405173ffffffffffffffffffffffffffffffffffffffff92831692633dbb202b9216907f0166a07a0000000000000000000000000000000000000000000000000000000090611eaf908b908d908c908c908c908b90602401612c8f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b9092168252611f4292918790600401612bdb565b600060405180830381600087803b158015611f5c57600080fd5b505af1158015611f70573d6000803e3d6000fd5b5050505050505050505050565b6109b787878787878787611bc4565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f238484604051611feb929190612c5e565b60405180910390a36105a08484848461230f565b600061200a8361236e565b801561201b575061201b83836123d2565b9392505050565b6000612084826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166124a19092919063ffffffff16565b805190915015610a9757808060200190518101906120a29190612b70565b610a97576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161020e565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd8686866040516121a693929190612c20565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d8484604051612215929190612c5e565b60405180910390a350505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526105a09085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161193f565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d03968686866040516122f993929190612c20565b60405180910390a4610f718686868686866124b8565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af58484604051612215929190612c5e565b600061239a827f01ffc9a7000000000000000000000000000000000000000000000000000000006123d2565b80156117c757506123cb827fffffffff000000000000000000000000000000000000000000000000000000006123d2565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561248a575060208210155b80156124965750600081115b979650505050505050565b60606124b08484600085612530565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf8686866040516121a693929190612c20565b6060824710156125c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161020e565b73ffffffffffffffffffffffffffffffffffffffff85163b612640576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161020e565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516126699190612cea565b60006040518083038185875af1925050503d80600081146126a6576040519150601f19603f3d011682016040523d82523d6000602084013e6126ab565b606091505b5091509150612496828286606083156126c557508161201b565b8251156126d55782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161020e9190612a14565b73ffffffffffffffffffffffffffffffffffffffff8116811461272b57600080fd5b50565b60008083601f84011261274057600080fd5b50813567ffffffffffffffff81111561275857600080fd5b60208301915083602082850101111561277057600080fd5b9250929050565b600080600080600080600060c0888a03121561279257600080fd5b873561279d81612709565b965060208801356127ad81612709565b955060408801356127bd81612709565b945060608801356127cd81612709565b93506080880135925060a088013567ffffffffffffffff8111156127f057600080fd5b6127fc8a828b0161272e565b989b979a50959850939692959293505050565b803563ffffffff8116811461282357600080fd5b919050565b60008060006040848603121561283d57600080fd5b6128468461280f565b9250602084013567ffffffffffffffff81111561286257600080fd5b61286e8682870161272e565b9497909650939450505050565b60008060008060006080868803121561289357600080fd5b853561289e81612709565b945060208601356128ae81612709565b935060408601359250606086013567ffffffffffffffff8111156128d157600080fd5b6128dd8882890161272e565b969995985093965092949392505050565b6000806040838503121561290157600080fd5b823561290c81612709565b9150602083013561291c81612709565b809150509250929050565b600080600080600080600060c0888a03121561294257600080fd5b873561294d81612709565b9650602088013561295d81612709565b9550604088013561296d81612709565b9450606088013593506129826080890161280f565b925060a088013567ffffffffffffffff8111156127f057600080fd5b60005b838110156129b95781810151838201526020016129a1565b838111156105a05750506000910152565b600081518084526129e281602086016020860161299e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061201b60208301846129ca565b60008060008060008060a08789031215612a4057600080fd5b8635612a4b81612709565b95506020870135612a5b81612709565b945060408701359350612a706060880161280f565b9250608087013567ffffffffffffffff811115612a8c57600080fd5b612a9889828a0161272e565b979a9699509497509295939492505050565b60008060008060608587031215612ac057600080fd5b8435612acb81612709565b9350612ad96020860161280f565b9250604085013567ffffffffffffffff811115612af557600080fd5b612b018782880161272e565b95989497509550505050565b600060208284031215612b1f57600080fd5b815161201b81612709565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612b6b57612b6b612b2a565b500390565b600060208284031215612b8257600080fd5b8151801515811461201b57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525083604083015260806060830152612bd160808301846129ca565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff84168152606060208201526000612c0a60608301856129ca565b905063ffffffff83166040830152949350505050565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000612c5560608301846129ca565b95945050505050565b8281526040602082015260006124b060408301846129ca565b60008219821115612c8a57612c8a612b2a565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a0830152612cde60c08301846129ca565b98975050505050505050565b60008251612cfc81846020870161299e565b919091019291505056fea164736f6c634300080f000a", + "linkReferences": {}, + "deployedLinkReferences": {} +} \ No newline at end of file diff --git a/operate/data/contracts/l1_standard_bridge/contract.py b/operate/data/contracts/l1_standard_bridge/contract.py new file mode 100644 index 00000000..9cdaff3a --- /dev/null +++ b/operate/data/contracts/l1_standard_bridge/contract.py @@ -0,0 +1,138 @@ +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2024 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ + +"""This module contains the class to connect to the `L1StandardBridge` contract.""" + +from math import ceil + +from aea.common import JSONLike +from aea.configurations.base import PublicId +from aea.contracts.base import Contract +from aea.crypto.base import LedgerApi + + +PLACEHOLDER_NATIVE_TOKEN_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" # nosec + +# Minimum gas required for L2 execution when bridging from L1. +# Prevents underfunded messages that could fail on L2. +DEFAULT_BRIDGE_MIN_GAS_LIMIT = 300_000 + +DEFAULT_GAS_BRIDGE_ETH_TO = 800_000 +DEFAULT_GAS_BRIDGE_ERC20_TO = 800_000 + +# By simulations, nonzero-ERC20-bridge gas ~ 1.05 zero-ERC20-bridge gas +NONZERO_ERC20_GAS_FACTOR = 1.15 + + +class L1StandardBridge(Contract): + """Optimism L1StandardBridge.""" + + contract_id = PublicId.from_str("valory/l1_standard_bridge:0.1.0") + + @classmethod + def build_bridge_eth_to_tx( + cls, + ledger_api: LedgerApi, + contract_address: str, + sender: str, + to: str, + amount: int, + min_gas_limit: int, + extra_data: bytes, + raise_on_try: bool = False, + ) -> JSONLike: + """Build bridgeETHTo tx.""" + contract_instance = cls.get_instance( + ledger_api=ledger_api, contract_address=contract_address + ) + tx = contract_instance.functions.bridgeETHTo( + to, min_gas_limit, extra_data + ).build_transaction( + { + "from": sender, + "value": amount, + "gas": DEFAULT_GAS_BRIDGE_ETH_TO, + "gasPrice": ledger_api.api.eth.gas_price, + "nonce": ledger_api.api.eth.get_transaction_count(sender), + } + ) + return ledger_api.update_with_gas_estimate( + transaction=tx, + raise_on_try=raise_on_try, + ) + + @classmethod + def build_bridge_erc20_to_tx( + cls, + ledger_api: LedgerApi, + contract_address: str, + sender: str, + local_token: str, + remote_token: str, + to: str, + amount: int, + min_gas_limit: int, + extra_data: bytes, + raise_on_try: bool = False, + ) -> JSONLike: + """Build bridgeERC20To tx.""" + contract_instance = cls.get_instance( + ledger_api=ledger_api, contract_address=contract_address + ) + tx = contract_instance.functions.bridgeERC20To( + local_token, remote_token, to, amount, min_gas_limit, extra_data + ).build_transaction( + { + "from": sender, + "gas": 1, + "gasPrice": ledger_api.api.eth.gas_price, + "nonce": ledger_api.api.eth.get_transaction_count(sender), + } + ) + + ledger_api.update_with_gas_estimate( + transaction=tx, + raise_on_try=raise_on_try, + ) + + if tx["gas"] > 1: + return tx + + tx_zero = contract_instance.functions.bridgeERC20To( + local_token, remote_token, to, 0, min_gas_limit, extra_data + ).build_transaction( + { + "from": PLACEHOLDER_NATIVE_TOKEN_ADDRESS, + "gas": 1, + "gasPrice": ledger_api.api.eth.gas_price, + "nonce": ledger_api.api.eth.get_transaction_count(sender), + } + ) + + ledger_api.update_with_gas_estimate( + transaction=tx_zero, + raise_on_try=raise_on_try, + ) + + if tx_zero["gas"] > 1: + tx["gas"] = ceil(tx_zero["gas"] * NONZERO_ERC20_GAS_FACTOR) + return tx + + tx["gas"] = DEFAULT_GAS_BRIDGE_ERC20_TO + return tx diff --git a/operate/data/contracts/l1_standard_bridge/contract.yaml b/operate/data/contracts/l1_standard_bridge/contract.yaml new file mode 100644 index 00000000..a617b83e --- /dev/null +++ b/operate/data/contracts/l1_standard_bridge/contract.yaml @@ -0,0 +1,23 @@ +name: l1_standard_bridge +author: valory +version: 0.1.0 +type: contract +description: Optimism L1 Standard Bridge +license: Apache-2.0 +aea_version: '>=1.0.0, <2.0.0' +fingerprint: + __init__.py: bafybeifsbxn6hlccnpgqnpvaz3ph6ajl4is4mcyerr6aqp7heggagcphye + build/L1StandardBridge.json: bafybeidq6jt7zmedtuxbbyggiqhu7w6543bunyd2vrbibg6y2svxsi2q5m + contract.py: bafybeib2kiztts3436vccvraeura3jb23oihgzxgrt3biakbed24edcaai +fingerprint_ignore_patterns: [] +contracts: [] +class_name: L1StandardBridge +contract_interface_paths: + ethereum: build/L1StandardBridge.json +dependencies: + open-aea-ledger-ethereum: + version: ==1.60.0 + open-aea-test-autonomy: + version: ==0.18.3 + web3: + version: <7,>=6.0.0 diff --git a/operate/data/contracts/l2_standard_bridge/__init__.py b/operate/data/contracts/l2_standard_bridge/__init__.py new file mode 100644 index 00000000..970e8263 --- /dev/null +++ b/operate/data/contracts/l2_standard_bridge/__init__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2025 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ + +"""This module contains the support resources for the `L2StandardBridge` contract.""" diff --git a/operate/data/contracts/l2_standard_bridge/build/L2StandardBridge.json b/operate/data/contracts/l2_standard_bridge/build/L2StandardBridge.json new file mode 100644 index 00000000..13755b45 --- /dev/null +++ b/operate/data/contracts/l2_standard_bridge/build/L2StandardBridge.json @@ -0,0 +1,626 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "L2StandardBridge", + "sourceName": "L2StandardBridge.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "addresspayable", + "name": "_otherBridge", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "l2Token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "DepositFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "localToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "remoteToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ERC20BridgeFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "localToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "remoteToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ERC20BridgeInitiated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ETHBridgeFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "ETHBridgeInitiated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "l2Token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "WithdrawalInitiated", + "type": "event" + }, + { + "inputs": [], + "name": "MESSENGER", + "outputs": [ + { + "internalType": "contractCrossDomainMessenger", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "OTHER_BRIDGE", + "outputs": [ + { + "internalType": "contractStandardBridge", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_localToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "bridgeERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_localToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "bridgeERC20To", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "bridgeETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "bridgeETHTo", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "deposits", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_localToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "finalizeBridgeERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "finalizeBridgeETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "address", + "name": "_l2Token", + "type": "address" + }, + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "finalizeDeposit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "l1TokenBridge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "messenger", + "outputs": [ + { + "internalType": "contractCrossDomainMessenger", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_l2Token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_l2Token", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "_minGasLimit", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "withdrawTo", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": "", + "deployedBytecode": "0x6080604052600436106100ec5760003560e01c806354fd4d501161008a5780638f601f66116100595780638f601f661461034e578063927ede2d14610394578063a3a79548146103c8578063e11013dd146103db57600080fd5b806354fd4d50146102c5578063662a633a146102e75780637f46ddb2146102fa578063870876231461032e57600080fd5b806332b7006d116100c657806332b7006d1461020657806336c717c1146102195780633cb747bf14610272578063540abf73146102a557600080fd5b80630166a07a146101c057806309fc8843146101e05780631635f5fd146101f357600080fd5b366101bb57333b15610185576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f4100000000000000000060648201526084015b60405180910390fd5b6101b973deaddeaddeaddeaddeaddeaddeaddeaddead000033333462030d40604051806020016040528060008152506103ee565b005b600080fd5b3480156101cc57600080fd5b506101b96101db366004612372565b6104c9565b6101b96101ee366004612423565b6108b6565b6101b9610201366004612476565b61098d565b6101b96102143660046124e9565b610e5a565b34801561022557600080fd5b507f0000000000000000000000003154cf16ccdb4c6d922629664174b904d80f2c355b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561027e57600080fd5b507f0000000000000000000000004200000000000000000000000000000000000007610248565b3480156102b157600080fd5b506101b96102c036600461253d565b610f34565b3480156102d157600080fd5b506102da610f79565b604051610269919061262a565b6101b96102f5366004612372565b61101c565b34801561030657600080fd5b506102487f0000000000000000000000003154cf16ccdb4c6d922629664174b904d80f2c3581565b34801561033a57600080fd5b506101b961034936600461263d565b61108f565b34801561035a57600080fd5b506103866103693660046126c0565b600260209081526000928352604080842090915290825290205481565b604051908152602001610269565b3480156103a057600080fd5b506102487f000000000000000000000000420000000000000000000000000000000000000781565b6101b96103d636600461263d565b611163565b6101b96103e93660046126f9565b6111a7565b7fffffffffffffffffffffffff215221522152215221522152215221522153000073ffffffffffffffffffffffffffffffffffffffff87160161043d5761043885858585856111f0565b6104c1565b60008673ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa15801561048a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104ae919061275c565b90506104bf878288888888886113d4565b505b505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004200000000000000000000000000000000000007161480156105e757507f0000000000000000000000003154cf16ccdb4c6d922629664174b904d80f2c3573ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000420000000000000000000000000000000000000773ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105cf919061275c565b73ffffffffffffffffffffffffffffffffffffffff16145b610699576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a40161017c565b6106a28761171b565b156107f0576106b1878761177d565b610763576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a40161017c565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590528816906340c10f1990604401600060405180830381600087803b1580156107d357600080fd5b505af11580156107e7573d6000803e3d6000fd5b50505050610872565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461082e9084906127a8565b73ffffffffffffffffffffffffffffffffffffffff8089166000818152600260209081526040808320948c168352939052919091209190915561087290858561189d565b6104bf878787878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061197192505050565b333b15610945576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f41000000000000000000606482015260840161017c565b6109883333348686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506111f092505050565b505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000420000000000000000000000000000000000000716148015610aab57507f0000000000000000000000003154cf16ccdb4c6d922629664174b904d80f2c3573ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000420000000000000000000000000000000000000773ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a93919061275c565b73ffffffffffffffffffffffffffffffffffffffff16145b610b5d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20746865206f7468657220627269646760648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a40161017c565b823414610bec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5374616e646172644272696467653a20616d6f756e742073656e7420646f657360448201527f206e6f74206d6174636820616d6f756e74207265717569726564000000000000606482015260840161017c565b3073ffffffffffffffffffffffffffffffffffffffff851603610c91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f207360448201527f656c660000000000000000000000000000000000000000000000000000000000606482015260840161017c565b7f000000000000000000000000420000000000000000000000000000000000000773ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610d6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f5374616e646172644272696467653a2063616e6e6f742073656e6420746f206d60448201527f657373656e676572000000000000000000000000000000000000000000000000606482015260840161017c565b610dae85858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506119ff92505050565b6000610dcb855a8660405180602001604052806000815250611aa0565b9050806104c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5374616e646172644272696467653a20455448207472616e736665722066616960448201527f6c65640000000000000000000000000000000000000000000000000000000000606482015260840161017c565b333b15610ee9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f41000000000000000000606482015260840161017c565b610f2d853333878787878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506103ee92505050565b5050505050565b6104bf87873388888888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506113d492505050565b6060610fa47f0000000000000000000000000000000000000000000000000000000000000001611aba565b610fcd7f0000000000000000000000000000000000000000000000000000000000000001611aba565b610ff67f0000000000000000000000000000000000000000000000000000000000000000611aba565b604051602001611008939291906127bf565b604051602081830303815290604052905090565b73ffffffffffffffffffffffffffffffffffffffff8716158015611069575073ffffffffffffffffffffffffffffffffffffffff861673deaddeaddeaddeaddeaddeaddeaddeaddead0000145b156110805761107b858585858561098d565b6104bf565b6104bf868887878787876104c9565b333b1561111e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f5374616e646172644272696467653a2066756e6374696f6e2063616e206f6e6c60448201527f792062652063616c6c65642066726f6d20616e20454f41000000000000000000606482015260840161017c565b6104c186863333888888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506113d492505050565b6104c1863387878787878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506103ee92505050565b6111ea3385348686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506111f092505050565b50505050565b82341461127f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5374616e646172644272696467653a206272696467696e6720455448206d757360448201527f7420696e636c7564652073756666696369656e74204554482076616c75650000606482015260840161017c565b61128b85858584611bf7565b7f000000000000000000000000420000000000000000000000000000000000000773ffffffffffffffffffffffffffffffffffffffff16633dbb202b847f0000000000000000000000003154cf16ccdb4c6d922629664174b904d80f2c35631635f5fd60e01b898989886040516024016113089493929190612835565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e086901b909216825261139b9291889060040161287e565b6000604051808303818588803b1580156113b457600080fd5b505af11580156113c8573d6000803e3d6000fd5b50505050505050505050565b6113dd8761171b565b1561152b576113ec878761177d565b61149e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f5374616e646172644272696467653a2077726f6e672072656d6f746520746f6b60448201527f656e20666f72204f7074696d69736d204d696e7461626c65204552433230206c60648201527f6f63616c20746f6b656e00000000000000000000000000000000000000000000608482015260a40161017c565b6040517f9dc29fac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015260248201859052881690639dc29fac90604401600060405180830381600087803b15801561150e57600080fd5b505af1158015611522573d6000803e3d6000fd5b505050506115bf565b61154d73ffffffffffffffffffffffffffffffffffffffff8816863086611c98565b73ffffffffffffffffffffffffffffffffffffffff8088166000908152600260209081526040808320938a168352929052205461158b9084906128c3565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b16835292905220555b6115cd878787878786611cf6565b7f000000000000000000000000420000000000000000000000000000000000000773ffffffffffffffffffffffffffffffffffffffff16633dbb202b7f0000000000000000000000003154cf16ccdb4c6d922629664174b904d80f2c35630166a07a60e01b898b8a8a8a8960405160240161164d969594939291906128db565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009485161790525160e085901b90921682526116e09291879060040161287e565b600060405180830381600087803b1580156116fa57600080fd5b505af115801561170e573d6000803e3d6000fd5b5050505050505050505050565b6000611747827f1d1d8b6300000000000000000000000000000000000000000000000000000000611d84565b806117775750611777827fec4fc8e300000000000000000000000000000000000000000000000000000000611d84565b92915050565b60006117a9837f1d1d8b6300000000000000000000000000000000000000000000000000000000611d84565b15611852578273ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181d919061275c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050611777565b8273ffffffffffffffffffffffffffffffffffffffff1663d6c0b2c46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117f9573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109889084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611da7565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd898686866040516119e993929190612936565b60405180910390a46104c1868686868686611eb3565b8373ffffffffffffffffffffffffffffffffffffffff1673deaddeaddeaddeaddeaddeaddeaddeaddead000073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd89868686604051611a8c93929190612936565b60405180910390a46111ea84848484611f3b565b600080600080845160208601878a8af19695505050505050565b606081600003611afd57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611b275780611b1181612974565b9150611b209050600a836129db565b9150611b01565b60008167ffffffffffffffff811115611b4257611b426129ef565b6040519080825280601f01601f191660200182016040528015611b6c576020820181803683370190505b5090505b8415611bef57611b816001836127a8565b9150611b8e600a86612a1e565b611b999060306128c3565b60f81b818381518110611bae57611bae612a32565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611be8600a866129db565b9450611b70565b949350505050565b8373ffffffffffffffffffffffffffffffffffffffff1673deaddeaddeaddeaddeaddeaddeaddeaddead000073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e868686604051611c8493929190612936565b60405180910390a46111ea84848484611fa8565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526111ea9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016118ef565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e868686604051611d6e93929190612936565b60405180910390a46104c1868686868686612007565b6000611d8f8361207f565b8015611da05750611da083836120e3565b9392505050565b6000611e09826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166121b29092919063ffffffff16565b8051909150156109885780806020019051810190611e279190612a61565b610988576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161017c565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd868686604051611f2b93929190612936565b60405180910390a4505050505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f31b2166ff604fc5672ea5df08a78081d2bc6d746cadce880747f3643d819e83d8484604051611f9a929190612a83565b60405180910390a350505050565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2849b43074093a05396b6f2a937dee8565b15a48a7b3d4bffb732a5017380af58484604051611f9a929190612a83565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf868686604051611f2b93929190612936565b60006120ab827f01ffc9a7000000000000000000000000000000000000000000000000000000006120e3565b801561177757506120dc827fffffffff000000000000000000000000000000000000000000000000000000006120e3565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561219b575060208210155b80156121a75750600081115b979650505050505050565b6060611bef84846000858573ffffffffffffffffffffffffffffffffffffffff85163b61223b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161017c565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516122649190612a9c565b60006040518083038185875af1925050503d80600081146122a1576040519150601f19603f3d011682016040523d82523d6000602084013e6122a6565b606091505b50915091506121a7828286606083156122c0575081611da0565b8251156122d05782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161017c919061262a565b73ffffffffffffffffffffffffffffffffffffffff8116811461232657600080fd5b50565b60008083601f84011261233b57600080fd5b50813567ffffffffffffffff81111561235357600080fd5b60208301915083602082850101111561236b57600080fd5b9250929050565b600080600080600080600060c0888a03121561238d57600080fd5b873561239881612304565b965060208801356123a881612304565b955060408801356123b881612304565b945060608801356123c881612304565b93506080880135925060a088013567ffffffffffffffff8111156123eb57600080fd5b6123f78a828b01612329565b989b979a50959850939692959293505050565b803563ffffffff8116811461241e57600080fd5b919050565b60008060006040848603121561243857600080fd5b6124418461240a565b9250602084013567ffffffffffffffff81111561245d57600080fd5b61246986828701612329565b9497909650939450505050565b60008060008060006080868803121561248e57600080fd5b853561249981612304565b945060208601356124a981612304565b935060408601359250606086013567ffffffffffffffff8111156124cc57600080fd5b6124d888828901612329565b969995985093965092949392505050565b60008060008060006080868803121561250157600080fd5b853561250c81612304565b9450602086013593506125216040870161240a565b9250606086013567ffffffffffffffff8111156124cc57600080fd5b600080600080600080600060c0888a03121561255857600080fd5b873561256381612304565b9650602088013561257381612304565b9550604088013561258381612304565b9450606088013593506125986080890161240a565b925060a088013567ffffffffffffffff8111156123eb57600080fd5b60005b838110156125cf5781810151838201526020016125b7565b838111156111ea5750506000910152565b600081518084526125f88160208601602086016125b4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611da060208301846125e0565b60008060008060008060a0878903121561265657600080fd5b863561266181612304565b9550602087013561267181612304565b9450604087013593506126866060880161240a565b9250608087013567ffffffffffffffff8111156126a257600080fd5b6126ae89828a01612329565b979a9699509497509295939492505050565b600080604083850312156126d357600080fd5b82356126de81612304565b915060208301356126ee81612304565b809150509250929050565b6000806000806060858703121561270f57600080fd5b843561271a81612304565b93506127286020860161240a565b9250604085013567ffffffffffffffff81111561274457600080fd5b61275087828801612329565b95989497509550505050565b60006020828403121561276e57600080fd5b8151611da081612304565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156127ba576127ba612779565b500390565b600084516127d18184602089016125b4565b80830190507f2e00000000000000000000000000000000000000000000000000000000000000808252855161280d816001850160208a016125b4565b600192019182015283516128288160028401602088016125b4565b0160020195945050505050565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261287460808301846125e0565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006128ad60608301856125e0565b905063ffffffff83166040830152949350505050565b600082198211156128d6576128d6612779565b500190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a083015261292a60c08301846125e0565b98975050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815282602082015260606040820152600061296b60608301846125e0565b95945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036129a5576129a5612779565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826129ea576129ea6129ac565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082612a2d57612a2d6129ac565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215612a7357600080fd5b81518015158114611da057600080fd5b828152604060208201526000611bef60408301846125e0565b60008251612aae8184602087016125b4565b919091019291505056fea164736f6c634300080f000a", + "linkReferences": {}, + "deployedLinkReferences": {} +} \ No newline at end of file diff --git a/operate/data/contracts/l2_standard_bridge/contract.py b/operate/data/contracts/l2_standard_bridge/contract.py new file mode 100644 index 00000000..48149d52 --- /dev/null +++ b/operate/data/contracts/l2_standard_bridge/contract.py @@ -0,0 +1,130 @@ +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2024 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ + +"""This module contains the class to connect to the `L2StandardBridge` contract.""" + +from typing import Optional, cast + +import eth_abi +from aea.configurations.base import PublicId +from aea.contracts.base import Contract +from aea.crypto.base import LedgerApi +from aea_ledger_ethereum import EthereumApi +from web3 import Web3 +from web3.types import BlockIdentifier + + +class L2StandardBridge(Contract): + """Optimism L2StandardBridge.""" + + contract_id = PublicId.from_str("valory/l2_standard_bridge:0.1.0") + + @classmethod + def find_eth_bridge_finalized_tx( + cls, + ledger_api: LedgerApi, + contract_address: str, + from_: str, + to: str, + amount: int, + extra_data: bytes, + from_block: BlockIdentifier = "earliest", + to_block: BlockIdentifier = "latest", + ) -> Optional[str]: + """Return the transaction hash of the matching ETHBridgeFinalized event in the given block range.""" + ledger_api = cast(EthereumApi, ledger_api) + event_signature = "ETHBridgeFinalized(address,address,uint256,bytes)" + event_signature_hash = Web3.keccak(text=event_signature).hex() + + topics = [ + event_signature_hash, # ETHBridgeFinalized + "0x" + from_.lower()[2:].rjust(64, "0"), # from + "0x" + to.lower()[2:].rjust(64, "0"), # to + ] + non_indexed_types = ["uint256", "bytes"] + non_indexed_values = [ + amount, # amount + extra_data, # extraData + ] + + logs = ledger_api.api.eth.get_logs( + { + "fromBlock": from_block, + "toBlock": to_block, + "address": contract_address, + "topics": topics, + } + ) + + for log in logs: + decoded = eth_abi.decode(non_indexed_types, log["data"]) + if all(a == b for a, b in zip(decoded, non_indexed_values)): + return log["transactionHash"].hex() + + return None + + @classmethod + def find_erc20_bridge_finalized_tx( + cls, + ledger_api: LedgerApi, + contract_address: str, + local_token: str, + remote_token: str, + from_: str, + to: str, + amount: int, + extra_data: bytes, + from_block: BlockIdentifier = "earliest", + to_block: BlockIdentifier = "latest", + ) -> Optional[str]: + """Return the transaction hash of the matching ERC20BridgeFinalized event in the given block range.""" + ledger_api = cast(EthereumApi, ledger_api) + event_signature = ( + "ERC20BridgeFinalized(address,address,address,address,uint256,bytes)" + ) + event_signature_hash = Web3.keccak(text=event_signature).hex() + + topics = [ + event_signature_hash, # ERC20BridgeFinalized + "0x" + local_token.lower()[2:].rjust(64, "0"), # localToken + "0x" + remote_token.lower()[2:].rjust(64, "0"), # remoteToken + "0x" + from_.lower()[2:].rjust(64, "0"), # from + ] + non_indexed_types = ["address", "uint256", "bytes"] + non_indexed_values = [ + to.lower(), # to + amount, # amount + extra_data, # extraData + ] + + logs = ledger_api.api.eth.get_logs( + { + "fromBlock": from_block, + "toBlock": to_block, + "address": contract_address, + "topics": topics, + } + ) + + for log in logs: + decoded = eth_abi.decode(non_indexed_types, log["data"]) + if all(a == b for a, b in zip(decoded, non_indexed_values)): + return log["transactionHash"].hex() + + return None diff --git a/operate/data/contracts/l2_standard_bridge/contract.yaml b/operate/data/contracts/l2_standard_bridge/contract.yaml new file mode 100644 index 00000000..74191f55 --- /dev/null +++ b/operate/data/contracts/l2_standard_bridge/contract.yaml @@ -0,0 +1,23 @@ +name: l2_standard_bridge +author: valory +version: 0.1.0 +type: contract +description: Optimism L2 Standard Bridge +license: Apache-2.0 +aea_version: '>=1.0.0, <2.0.0' +fingerprint: + __init__.py: bafybeihp3ucqaxnuozotqcmvm6bjdds4rfbtr56sj7jeb6sbxlzikvtxyq + build/L2StandardBridge.json: bafybeid2zqptx4awocztkhmifqsdnqrqcib73hbsp53snmfd24u7k3q6me + contract.py: bafybeifah3y4wr4mkqdu4yuv364gxssdybuqf32wcszvrgwc33lucrjdw4 +fingerprint_ignore_patterns: [] +contracts: [] +class_name: L2StandardBridge +contract_interface_paths: + ethereum: build/L2StandardBridge.json +dependencies: + open-aea-ledger-ethereum: + version: ==1.60.0 + open-aea-test-autonomy: + version: ==0.18.3 + web3: + version: <7,>=6.0.0 diff --git a/operate/data/contracts/optimism_mintable_erc20/__init__.py b/operate/data/contracts/optimism_mintable_erc20/__init__.py new file mode 100644 index 00000000..3cc8edd5 --- /dev/null +++ b/operate/data/contracts/optimism_mintable_erc20/__init__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2024 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ + +"""This module contains the support resources for the `OptimismMintableERC20` contract.""" diff --git a/operate/data/contracts/optimism_mintable_erc20/build/OptimismMintableERC20.json b/operate/data/contracts/optimism_mintable_erc20/build/OptimismMintableERC20.json new file mode 100644 index 00000000..1a12425e --- /dev/null +++ b/operate/data/contracts/optimism_mintable_erc20/build/OptimismMintableERC20.json @@ -0,0 +1,491 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "OptimismMintableERC20", + "sourceName": "OptimismMintableERC20.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_bridge", + "type": "address" + }, + { + "internalType": "address", + "name": "_remoteToken", + "type": "address" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "BRIDGE", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REMOTE_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bridge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "l1Token", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l2Bridge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "remoteToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "", + "deployedBytecode": "", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/operate/data/contracts/optimism_mintable_erc20/contract.py b/operate/data/contracts/optimism_mintable_erc20/contract.py new file mode 100644 index 00000000..dc880537 --- /dev/null +++ b/operate/data/contracts/optimism_mintable_erc20/contract.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2024 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ + +"""This module contains the class to connect to the `OptimismMintableERC20` contract.""" + + +from aea.common import JSONLike +from aea.configurations.base import PublicId +from aea.contracts.base import Contract +from aea.crypto.base import LedgerApi + + +class OptimismMintableERC20(Contract): + """Optimism OptimismMintableERC20.""" + + contract_id = PublicId.from_str("valory/optimism_mintable_erc20:0.1.0") + + @classmethod + def l1_token( + cls, + ledger_api: LedgerApi, + contract_address: str, + ) -> JSONLike: + """l1Token""" + contract_instance = cls.get_instance( + ledger_api=ledger_api, contract_address=contract_address + ) + l1_token = contract_instance.functions.l1Token().call() + return dict(data=l1_token) diff --git a/operate/data/contracts/optimism_mintable_erc20/contract.yaml b/operate/data/contracts/optimism_mintable_erc20/contract.yaml new file mode 100644 index 00000000..54c202f9 --- /dev/null +++ b/operate/data/contracts/optimism_mintable_erc20/contract.yaml @@ -0,0 +1,23 @@ +name: optimism_mintable_erc20 +author: valory +version: 0.1.0 +type: contract +description: Optimism Mintable ERC20 +license: Apache-2.0 +aea_version: '>=1.0.0, <2.0.0' +fingerprint: + __init__.py: bafybeiffqotbwpjde3htgfuplg62x4btoekvitqrkrlx2vkjpciwzov6sy + build/OptimismMintableERC20.json: bafybeieuzn55dh5zlg4ygtuifqso6hwbhsjvidxkjkh2vnah5psxqup62i + contract.py: bafybeiauq7vas7xuyb2zt4m5mb6i2g2nrwtptv6muivur5u3c5lwckys4q +fingerprint_ignore_patterns: [] +contracts: [] +class_name: OptimismMintableERC20 +contract_interface_paths: + ethereum: build/OptimismMintableERC20.json +dependencies: + open-aea-ledger-ethereum: + version: ==1.60.0 + open-aea-test-autonomy: + version: ==0.18.3 + web3: + version: <7,>=6.0.0 diff --git a/operate/ledger/__init__.py b/operate/ledger/__init__.py index 85087284..3e1c4327 100644 --- a/operate/ledger/__init__.py +++ b/operate/ledger/__init__.py @@ -34,7 +34,7 @@ BASE_PUBLIC_RPC = os.environ.get("BASE_RPC", "https://mainnet.base.org") CELO_PUBLIC_RPC = os.environ.get("CELO_RPC", "https://forno.celo.org") OPTIMISM_PUBLIC_RPC = os.environ.get("OPTIMISM_RPC", "https://mainnet.optimism.io") -MODE_PUBLIC_RPC = os.environ.get("MODE_RPC", "https://rpc.mode.network") +MODE_PUBLIC_RPC = os.environ.get("MODE_RPC", "https://mainnet.mode.network/") ETHEREUM_RPC = os.environ.get("ETHEREUM_RPC", "https://ethereum.publicnode.com") GNOSIS_RPC = os.environ.get("GNOSIS_RPC", "https://rpc-gate.autonolas.tech/gnosis-rpc/") @@ -42,7 +42,7 @@ BASE_RPC = os.environ.get("BASE_RPC", "https://mainnet.base.org") CELO_RPC = os.environ.get("CELO_RPC", "https://forno.celo.org") OPTIMISM_RPC = os.environ.get("OPTIMISM_RPC", "https://mainnet.optimism.io") -MODE_RPC = os.environ.get("MODE_RPC", "https://rpc.mode.network") +MODE_RPC = os.environ.get("MODE_RPC", "https://mainnet.mode.network/") PUBLIC_RPCS = { Chain.ETHEREUM: ETHEREUM_PUBLIC_RPC, diff --git a/operate/ledger/profiles.py b/operate/ledger/profiles.py index a755880f..53b936d0 100644 --- a/operate/ledger/profiles.py +++ b/operate/ledger/profiles.py @@ -203,6 +203,29 @@ Chain.OPTIMISTIC: {ZERO_ADDRESS: 5_000_000_000_000_000}, } +EXPLORER_URL = { + Chain.BASE: { + "tx": "https://basescan.org/tx/{tx_hash}", + "address": "https://basescan.org/address/{address}", + }, + Chain.ETHEREUM: { + "tx": "https://etherscan.io/tx/{tx_hash}", + "address": "https://etherscan.io/address/{address}", + }, + Chain.GNOSIS: { + "tx": "https://gnosisscan.io/tx/{tx_hash}", + "address": "https://gnosisscan.io/address/{address}", + }, + Chain.MODE: { + "tx": "https://modescan.io/tx/{tx_hash}", + "address": "https://modescan.io/address/{address}", + }, + Chain.OPTIMISTIC: { + "tx": "https://optimistic.etherscan.io/tx/{tx_hash}", + "address": "https://optimistic.etherscan.io/address/{address}", + }, +} + def get_staking_contract( chain: str, staking_program_id: t.Optional[str] diff --git a/poetry.lock b/poetry.lock index ec5e306e..ea434198 100644 --- a/poetry.lock +++ b/poetry.lock @@ -134,13 +134,13 @@ files = [ [[package]] name = "anyio" -version = "4.8.0" +version = "4.9.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.8.0-py3-none-any.whl", hash = "sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a"}, - {file = "anyio-4.8.0.tar.gz", hash = "sha256:1d9fe889df5212298c0c0723fa20479d1b94883a2df44bd3897aa91083316f7a"}, + {file = "anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c"}, + {file = "anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028"}, ] [package.dependencies] @@ -150,8 +150,8 @@ sniffio = ">=1.1" typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] +doc = ["Sphinx (>=8.2,<9.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "blockbuster (>=1.5.23)", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -235,20 +235,20 @@ files = [ [[package]] name = "attrs" -version = "25.1.0" +version = "25.3.0" description = "Classes Without Boilerplate" optional = false python-versions = ">=3.8" files = [ - {file = "attrs-25.1.0-py3-none-any.whl", hash = "sha256:c75a69e28a550a7e93789579c22aa26b0f5b83b75dc4e08fe092980051e1090a"}, - {file = "attrs-25.1.0.tar.gz", hash = "sha256:1c97078a80c814273a76b2a298a932eb681c87415c11dee0a6921de7f1b02c3e"}, + {file = "attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3"}, + {file = "attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -343,13 +343,13 @@ typecheck = ["mypy"] [[package]] name = "beautifulsoup4" -version = "4.13.3" +version = "4.13.4" description = "Screen-scraping library" optional = false python-versions = ">=3.7.0" files = [ - {file = "beautifulsoup4-4.13.3-py3-none-any.whl", hash = "sha256:99045d7d3f08f91f0d656bc9b7efbae189426cd913d830294a15eefa0ea4df16"}, - {file = "beautifulsoup4-4.13.3.tar.gz", hash = "sha256:1bd32405dacc920b42b83ba01644747ed77456a65760e285fbc47633ceddaf8b"}, + {file = "beautifulsoup4-4.13.4-py3-none-any.whl", hash = "sha256:9bbbb14bfde9d79f38b8cd5f8c7c85f4b8f2523190ebed90e950a8dea4cb1c4b"}, + {file = "beautifulsoup4-4.13.4.tar.gz", hash = "sha256:dbb3c4e1ceae6aefebdaf2423247260cd062430a410e38c66f2baa50a8437195"}, ] [package.dependencies] @@ -547,13 +547,13 @@ virtualenv = ["virtualenv (>=20.0.35)"] [[package]] name = "certifi" -version = "2025.1.31" +version = "2025.4.26" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe"}, - {file = "certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651"}, + {file = "certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3"}, + {file = "certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6"}, ] [[package]] @@ -637,103 +637,103 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.1" +version = "3.4.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, - {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, - {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7c48ed483eb946e6c04ccbe02c6b4d1d48e51944b6db70f697e089c193404941"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2d318c11350e10662026ad0eb71bb51c7812fc8590825304ae0bdd4ac283acd"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9cbfacf36cb0ec2897ce0ebc5d08ca44213af24265bd56eca54bee7923c48fd6"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18dd2e350387c87dabe711b86f83c9c78af772c748904d372ade190b5c7c9d4d"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8075c35cd58273fee266c58c0c9b670947c19df5fb98e7b66710e04ad4e9ff86"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5bf4545e3b962767e5c06fe1738f951f77d27967cb2caa64c28be7c4563e162c"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7a6ab32f7210554a96cd9e33abe3ddd86732beeafc7a28e9955cdf22ffadbab0"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b33de11b92e9f75a2b545d6e9b6f37e398d86c3e9e9653c4864eb7e89c5773ef"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8755483f3c00d6c9a77f490c17e6ab0c8729e39e6390328e42521ef175380ae6"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:68a328e5f55ec37c57f19ebb1fdc56a248db2e3e9ad769919a58672958e8f366"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:21b2899062867b0e1fde9b724f8aecb1af14f2778d69aacd1a5a1853a597a5db"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-win32.whl", hash = "sha256:e8082b26888e2f8b36a042a58307d5b917ef2b1cacab921ad3323ef91901c71a"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:f69a27e45c43520f5487f27627059b64aaf160415589230992cec34c5e18a509"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:be1e352acbe3c78727a16a455126d9ff83ea2dfdcbc83148d2982305a04714c2"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa88ca0b1932e93f2d961bf3addbb2db902198dca337d88c89e1559e066e7645"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d524ba3f1581b35c03cb42beebab4a13e6cdad7b36246bd22541fa585a56cccd"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28a1005facc94196e1fb3e82a3d442a9d9110b8434fc1ded7a24a2983c9888d8"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdb20a30fe1175ecabed17cbf7812f7b804b8a315a25f24678bcdf120a90077f"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f5d9ed7f254402c9e7d35d2f5972c9bbea9040e99cd2861bd77dc68263277c7"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:efd387a49825780ff861998cd959767800d54f8308936b21025326de4b5a42b9"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f0aa37f3c979cf2546b73e8222bbfa3dc07a641585340179d768068e3455e544"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e70e990b2137b29dc5564715de1e12701815dacc1d056308e2b17e9095372a82"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0c8c57f84ccfc871a48a47321cfa49ae1df56cd1d965a09abe84066f6853b9c0"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6b66f92b17849b85cad91259efc341dce9c1af48e2173bf38a85c6329f1033e5"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-win32.whl", hash = "sha256:daac4765328a919a805fa5e2720f3e94767abd632ae410a9062dff5412bae65a"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:e53efc7c7cee4c1e70661e2e112ca46a575f90ed9ae3fef200f2a25e954f4b28"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0c29de6a1a95f24b9a1aa7aefd27d2487263f00dfd55a77719b530788f75cff7"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cddf7bd982eaa998934a91f69d182aec997c6c468898efe6679af88283b498d3"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcbe676a55d7445b22c10967bceaaf0ee69407fbe0ece4d032b6eb8d4565982a"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d41c4d287cfc69060fa91cae9683eacffad989f1a10811995fa309df656ec214"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e594135de17ab3866138f496755f302b72157d115086d100c3f19370839dd3a"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf713fe9a71ef6fd5adf7a79670135081cd4431c2943864757f0fa3a65b1fafd"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a370b3e078e418187da8c3674eddb9d983ec09445c99a3a263c2011993522981"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a955b438e62efdf7e0b7b52a64dc5c3396e2634baa62471768a64bc2adb73d5c"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7222ffd5e4de8e57e03ce2cef95a4c43c98fcb72ad86909abdfc2c17d227fc1b"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:bee093bf902e1d8fc0ac143c88902c3dfc8941f7ea1d6a8dd2bcb786d33db03d"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb8adb91d11846ee08bec4c8236c8549ac721c245678282dcb06b221aab59f"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-win32.whl", hash = "sha256:db4c7bf0e07fc3b7d89ac2a5880a6a8062056801b83ff56d8464b70f65482b6c"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:5a9979887252a82fefd3d3ed2a8e3b937a7a809f65dcb1e068b090e165bbe99e"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:926ca93accd5d36ccdabd803392ddc3e03e6d4cd1cf17deff3b989ab8e9dbcf0"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eba9904b0f38a143592d9fc0e19e2df0fa2e41c3c3745554761c5f6447eedabf"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3fddb7e2c84ac87ac3a947cb4e66d143ca5863ef48e4a5ecb83bd48619e4634e"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98f862da73774290f251b9df8d11161b6cf25b599a66baf087c1ffe340e9bfd1"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c9379d65defcab82d07b2a9dfbfc2e95bc8fe0ebb1b176a3190230a3ef0e07c"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e635b87f01ebc977342e2697d05b56632f5f879a4f15955dfe8cef2448b51691"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1c95a1e2902a8b722868587c0e1184ad5c55631de5afc0eb96bc4b0d738092c0"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ef8de666d6179b009dce7bcb2ad4c4a779f113f12caf8dc77f0162c29d20490b"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:32fc0341d72e0f73f80acb0a2c94216bd704f4f0bce10aedea38f30502b271ff"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:289200a18fa698949d2b39c671c2cc7a24d44096784e76614899a7ccf2574b7b"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a476b06fbcf359ad25d34a057b7219281286ae2477cc5ff5e3f70a246971148"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-win32.whl", hash = "sha256:aaeeb6a479c7667fbe1099af9617c83aaca22182d6cf8c53966491a0f1b7ffb7"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:aa6af9e7d59f9c12b33ae4e9450619cf2488e2bbe9b44030905877f0b2324980"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cad5f45b3146325bb38d6855642f6fd609c3f7cad4dbaf75549bf3b904d3184"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2680962a4848b3c4f155dc2ee64505a9c57186d0d56b43123b17ca3de18f0fa"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:36b31da18b8890a76ec181c3cf44326bf2c48e36d393ca1b72b3f484113ea344"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4074c5a429281bf056ddd4c5d3b740ebca4d43ffffe2ef4bf4d2d05114299da"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9e36a97bee9b86ef9a1cf7bb96747eb7a15c2f22bdb5b516434b00f2a599f02"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:1b1bde144d98e446b056ef98e59c256e9294f6b74d7af6846bf5ffdafd687a7d"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:915f3849a011c1f593ab99092f3cecfcb4d65d8feb4a64cf1bf2d22074dc0ec4"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:fb707f3e15060adf5b7ada797624a6c6e0138e2a26baa089df64c68ee98e040f"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:25a23ea5c7edc53e0f29bae2c44fcb5a1aa10591aae107f2a2b2583a9c5cbc64"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:770cab594ecf99ae64c236bc9ee3439c3f46be49796e265ce0cc8bc17b10294f"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-win32.whl", hash = "sha256:6a0289e4589e8bdfef02a80478f1dfcb14f0ab696b5a00e1f4b8a14a307a3c58"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6fc1f5b51fa4cecaa18f2bd7a003f3dd039dd615cd69a2afd6d3b19aed6775f2"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:76af085e67e56c8816c3ccf256ebd136def2ed9654525348cfa744b6802b69eb"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e45ba65510e2647721e35323d6ef54c7974959f6081b58d4ef5d87c60c84919a"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:046595208aae0120559a67693ecc65dd75d46f7bf687f159127046628178dc45"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75d10d37a47afee94919c4fab4c22b9bc2a8bf7d4f46f87363bcf0573f3ff4f5"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6333b3aa5a12c26b2a4d4e7335a28f1475e0e5e17d69d55141ee3cab736f66d1"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8323a9b031aa0393768b87f04b4164a40037fb2a3c11ac06a03ffecd3618027"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:24498ba8ed6c2e0b56d4acbf83f2d989720a93b41d712ebd4f4979660db4417b"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:844da2b5728b5ce0e32d863af26f32b5ce61bc4273a9c720a9f3aa9df73b1455"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:65c981bdbd3f57670af8b59777cbfae75364b483fa8a9f420f08094531d54a01"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:3c21d4fca343c805a52c0c78edc01e3477f6dd1ad7c47653241cf2a206d4fc58"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:dc7039885fa1baf9be153a0626e337aa7ec8bf96b0128605fb0d77788ddc1681"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-win32.whl", hash = "sha256:8272b73e1c5603666618805fe821edba66892e2870058c94c53147602eab29c7"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:70f7172939fdf8790425ba31915bfbe8335030f05b9913d7ae00a87d4395620a"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:005fa3432484527f9732ebd315da8da8001593e2cf46a3d817669f062c3d9ed4"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e92fca20c46e9f5e1bb485887d074918b13543b1c2a1185e69bb8d17ab6236a7"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50bf98d5e563b83cc29471fa114366e6806bc06bc7a25fd59641e41445327836"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:721c76e84fe669be19c5791da68232ca2e05ba5185575086e384352e2c309597"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82d8fd25b7f4675d0c47cf95b594d4e7b158aca33b76aa63d07186e13c0e0ab7"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3daeac64d5b371dea99714f08ffc2c208522ec6b06fbc7866a450dd446f5c0f"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dccab8d5fa1ef9bfba0590ecf4d46df048d18ffe3eec01eeb73a42e0d9e7a8ba"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:aaf27faa992bfee0264dc1f03f4c75e9fcdda66a519db6b957a3f826e285cf12"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:eb30abc20df9ab0814b5a2524f23d75dcf83cde762c161917a2b4b7b55b1e518"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:c72fbbe68c6f32f251bdc08b8611c7b3060612236e960ef848e0a517ddbe76c5"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:982bb1e8b4ffda883b3d0a521e23abcd6fd17418f6d2c4118d257a10199c0ce3"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-win32.whl", hash = "sha256:43e0933a0eff183ee85833f341ec567c0980dae57c464d8a508e1b2ceb336471"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:d11b54acf878eef558599658b0ffca78138c8c3655cf4f3a4a673c437e67732e"}, + {file = "charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0"}, + {file = "charset_normalizer-3.4.2.tar.gz", hash = "sha256:5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63"}, ] [[package]] @@ -854,74 +854,74 @@ requests = "*" [[package]] name = "coverage" -version = "7.6.12" +version = "7.8.0" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.9" files = [ - {file = "coverage-7.6.12-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:704c8c8c6ce6569286ae9622e534b4f5b9759b6f2cd643f1c1a61f666d534fe8"}, - {file = "coverage-7.6.12-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ad7525bf0241e5502168ae9c643a2f6c219fa0a283001cee4cf23a9b7da75879"}, - {file = "coverage-7.6.12-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06097c7abfa611c91edb9e6920264e5be1d6ceb374efb4986f38b09eed4cb2fe"}, - {file = "coverage-7.6.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:220fa6c0ad7d9caef57f2c8771918324563ef0d8272c94974717c3909664e674"}, - {file = "coverage-7.6.12-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3688b99604a24492bcfe1c106278c45586eb819bf66a654d8a9a1433022fb2eb"}, - {file = "coverage-7.6.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d1a987778b9c71da2fc8948e6f2656da6ef68f59298b7e9786849634c35d2c3c"}, - {file = "coverage-7.6.12-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:cec6b9ce3bd2b7853d4a4563801292bfee40b030c05a3d29555fd2a8ee9bd68c"}, - {file = "coverage-7.6.12-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ace9048de91293e467b44bce0f0381345078389814ff6e18dbac8fdbf896360e"}, - {file = "coverage-7.6.12-cp310-cp310-win32.whl", hash = "sha256:ea31689f05043d520113e0552f039603c4dd71fa4c287b64cb3606140c66f425"}, - {file = "coverage-7.6.12-cp310-cp310-win_amd64.whl", hash = "sha256:676f92141e3c5492d2a1596d52287d0d963df21bf5e55c8b03075a60e1ddf8aa"}, - {file = "coverage-7.6.12-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e18aafdfb3e9ec0d261c942d35bd7c28d031c5855dadb491d2723ba54f4c3015"}, - {file = "coverage-7.6.12-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:66fe626fd7aa5982cdebad23e49e78ef7dbb3e3c2a5960a2b53632f1f703ea45"}, - {file = "coverage-7.6.12-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ef01d70198431719af0b1f5dcbefc557d44a190e749004042927b2a3fed0702"}, - {file = "coverage-7.6.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e92ae5a289a4bc4c0aae710c0948d3c7892e20fd3588224ebe242039573bf0"}, - {file = "coverage-7.6.12-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e695df2c58ce526eeab11a2e915448d3eb76f75dffe338ea613c1201b33bab2f"}, - {file = "coverage-7.6.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d74c08e9aaef995f8c4ef6d202dbd219c318450fe2a76da624f2ebb9c8ec5d9f"}, - {file = "coverage-7.6.12-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e995b3b76ccedc27fe4f477b349b7d64597e53a43fc2961db9d3fbace085d69d"}, - {file = "coverage-7.6.12-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b1f097878d74fe51e1ddd1be62d8e3682748875b461232cf4b52ddc6e6db0bba"}, - {file = "coverage-7.6.12-cp311-cp311-win32.whl", hash = "sha256:1f7ffa05da41754e20512202c866d0ebfc440bba3b0ed15133070e20bf5aeb5f"}, - {file = "coverage-7.6.12-cp311-cp311-win_amd64.whl", hash = "sha256:e216c5c45f89ef8971373fd1c5d8d1164b81f7f5f06bbf23c37e7908d19e8558"}, - {file = "coverage-7.6.12-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b172f8e030e8ef247b3104902cc671e20df80163b60a203653150d2fc204d1ad"}, - {file = "coverage-7.6.12-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:641dfe0ab73deb7069fb972d4d9725bf11c239c309ce694dd50b1473c0f641c3"}, - {file = "coverage-7.6.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e549f54ac5f301e8e04c569dfdb907f7be71b06b88b5063ce9d6953d2d58574"}, - {file = "coverage-7.6.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:959244a17184515f8c52dcb65fb662808767c0bd233c1d8a166e7cf74c9ea985"}, - {file = "coverage-7.6.12-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bda1c5f347550c359f841d6614fb8ca42ae5cb0b74d39f8a1e204815ebe25750"}, - {file = "coverage-7.6.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1ceeb90c3eda1f2d8c4c578c14167dbd8c674ecd7d38e45647543f19839dd6ea"}, - {file = "coverage-7.6.12-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f16f44025c06792e0fb09571ae454bcc7a3ec75eeb3c36b025eccf501b1a4c3"}, - {file = "coverage-7.6.12-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b076e625396e787448d27a411aefff867db2bffac8ed04e8f7056b07024eed5a"}, - {file = "coverage-7.6.12-cp312-cp312-win32.whl", hash = "sha256:00b2086892cf06c7c2d74983c9595dc511acca00665480b3ddff749ec4fb2a95"}, - {file = "coverage-7.6.12-cp312-cp312-win_amd64.whl", hash = "sha256:7ae6eabf519bc7871ce117fb18bf14e0e343eeb96c377667e3e5dd12095e0288"}, - {file = "coverage-7.6.12-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:488c27b3db0ebee97a830e6b5a3ea930c4a6e2c07f27a5e67e1b3532e76b9ef1"}, - {file = "coverage-7.6.12-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5d1095bbee1851269f79fd8e0c9b5544e4c00c0c24965e66d8cba2eb5bb535fd"}, - {file = "coverage-7.6.12-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0533adc29adf6a69c1baa88c3d7dbcaadcffa21afbed3ca7a225a440e4744bf9"}, - {file = "coverage-7.6.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53c56358d470fa507a2b6e67a68fd002364d23c83741dbc4c2e0680d80ca227e"}, - {file = "coverage-7.6.12-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64cbb1a3027c79ca6310bf101014614f6e6e18c226474606cf725238cf5bc2d4"}, - {file = "coverage-7.6.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:79cac3390bfa9836bb795be377395f28410811c9066bc4eefd8015258a7578c6"}, - {file = "coverage-7.6.12-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9b148068e881faa26d878ff63e79650e208e95cf1c22bd3f77c3ca7b1d9821a3"}, - {file = "coverage-7.6.12-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8bec2ac5da793c2685ce5319ca9bcf4eee683b8a1679051f8e6ec04c4f2fd7dc"}, - {file = "coverage-7.6.12-cp313-cp313-win32.whl", hash = "sha256:200e10beb6ddd7c3ded322a4186313d5ca9e63e33d8fab4faa67ef46d3460af3"}, - {file = "coverage-7.6.12-cp313-cp313-win_amd64.whl", hash = "sha256:2b996819ced9f7dbb812c701485d58f261bef08f9b85304d41219b1496b591ef"}, - {file = "coverage-7.6.12-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:299cf973a7abff87a30609879c10df0b3bfc33d021e1adabc29138a48888841e"}, - {file = "coverage-7.6.12-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4b467a8c56974bf06e543e69ad803c6865249d7a5ccf6980457ed2bc50312703"}, - {file = "coverage-7.6.12-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2458f275944db8129f95d91aee32c828a408481ecde3b30af31d552c2ce284a0"}, - {file = "coverage-7.6.12-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a9d8be07fb0832636a0f72b80d2a652fe665e80e720301fb22b191c3434d924"}, - {file = "coverage-7.6.12-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14d47376a4f445e9743f6c83291e60adb1b127607a3618e3185bbc8091f0467b"}, - {file = "coverage-7.6.12-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b95574d06aa9d2bd6e5cc35a5bbe35696342c96760b69dc4287dbd5abd4ad51d"}, - {file = "coverage-7.6.12-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:ecea0c38c9079570163d663c0433a9af4094a60aafdca491c6a3d248c7432827"}, - {file = "coverage-7.6.12-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2251fabcfee0a55a8578a9d29cecfee5f2de02f11530e7d5c5a05859aa85aee9"}, - {file = "coverage-7.6.12-cp313-cp313t-win32.whl", hash = "sha256:eb5507795caabd9b2ae3f1adc95f67b1104971c22c624bb354232d65c4fc90b3"}, - {file = "coverage-7.6.12-cp313-cp313t-win_amd64.whl", hash = "sha256:f60a297c3987c6c02ffb29effc70eadcbb412fe76947d394a1091a3615948e2f"}, - {file = "coverage-7.6.12-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e7575ab65ca8399c8c4f9a7d61bbd2d204c8b8e447aab9d355682205c9dd948d"}, - {file = "coverage-7.6.12-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8161d9fbc7e9fe2326de89cd0abb9f3599bccc1287db0aba285cb68d204ce929"}, - {file = "coverage-7.6.12-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a1e465f398c713f1b212400b4e79a09829cd42aebd360362cd89c5bdc44eb87"}, - {file = "coverage-7.6.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f25d8b92a4e31ff1bd873654ec367ae811b3a943583e05432ea29264782dc32c"}, - {file = "coverage-7.6.12-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a936309a65cc5ca80fa9f20a442ff9e2d06927ec9a4f54bcba9c14c066323f2"}, - {file = "coverage-7.6.12-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:aa6f302a3a0b5f240ee201297fff0bbfe2fa0d415a94aeb257d8b461032389bd"}, - {file = "coverage-7.6.12-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f973643ef532d4f9be71dd88cf7588936685fdb576d93a79fe9f65bc337d9d73"}, - {file = "coverage-7.6.12-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:78f5243bb6b1060aed6213d5107744c19f9571ec76d54c99cc15938eb69e0e86"}, - {file = "coverage-7.6.12-cp39-cp39-win32.whl", hash = "sha256:69e62c5034291c845fc4df7f8155e8544178b6c774f97a99e2734b05eb5bed31"}, - {file = "coverage-7.6.12-cp39-cp39-win_amd64.whl", hash = "sha256:b01a840ecc25dce235ae4c1b6a0daefb2a203dba0e6e980637ee9c2f6ee0df57"}, - {file = "coverage-7.6.12-pp39.pp310-none-any.whl", hash = "sha256:7e39e845c4d764208e7b8f6a21c541ade741e2c41afabdfa1caa28687a3c98cf"}, - {file = "coverage-7.6.12-py3-none-any.whl", hash = "sha256:eb8668cfbc279a536c633137deeb9435d2962caec279c3f8cf8b91fff6ff8953"}, - {file = "coverage-7.6.12.tar.gz", hash = "sha256:48cfc4641d95d34766ad41d9573cc0f22a48aa88d22657a1fe01dca0dbae4de2"}, + {file = "coverage-7.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2931f66991175369859b5fd58529cd4b73582461877ecfd859b6549869287ffe"}, + {file = "coverage-7.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:52a523153c568d2c0ef8826f6cc23031dc86cffb8c6aeab92c4ff776e7951b28"}, + {file = "coverage-7.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c8a5c139aae4c35cbd7cadca1df02ea8cf28a911534fc1b0456acb0b14234f3"}, + {file = "coverage-7.8.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a26c0c795c3e0b63ec7da6efded5f0bc856d7c0b24b2ac84b4d1d7bc578d676"}, + {file = "coverage-7.8.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:821f7bcbaa84318287115d54becb1915eece6918136c6f91045bb84e2f88739d"}, + {file = "coverage-7.8.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a321c61477ff8ee705b8a5fed370b5710c56b3a52d17b983d9215861e37b642a"}, + {file = "coverage-7.8.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:ed2144b8a78f9d94d9515963ed273d620e07846acd5d4b0a642d4849e8d91a0c"}, + {file = "coverage-7.8.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:042e7841a26498fff7a37d6fda770d17519982f5b7d8bf5278d140b67b61095f"}, + {file = "coverage-7.8.0-cp310-cp310-win32.whl", hash = "sha256:f9983d01d7705b2d1f7a95e10bbe4091fabc03a46881a256c2787637b087003f"}, + {file = "coverage-7.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:5a570cd9bd20b85d1a0d7b009aaf6c110b52b5755c17be6962f8ccd65d1dbd23"}, + {file = "coverage-7.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e7ac22a0bb2c7c49f441f7a6d46c9c80d96e56f5a8bc6972529ed43c8b694e27"}, + {file = "coverage-7.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bf13d564d310c156d1c8e53877baf2993fb3073b2fc9f69790ca6a732eb4bfea"}, + {file = "coverage-7.8.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5761c70c017c1b0d21b0815a920ffb94a670c8d5d409d9b38857874c21f70d7"}, + {file = "coverage-7.8.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ff52d790c7e1628241ffbcaeb33e07d14b007b6eb00a19320c7b8a7024c040"}, + {file = "coverage-7.8.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d39fc4817fd67b3915256af5dda75fd4ee10621a3d484524487e33416c6f3543"}, + {file = "coverage-7.8.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b44674870709017e4b4036e3d0d6c17f06a0e6d4436422e0ad29b882c40697d2"}, + {file = "coverage-7.8.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8f99eb72bf27cbb167b636eb1726f590c00e1ad375002230607a844d9e9a2318"}, + {file = "coverage-7.8.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b571bf5341ba8c6bc02e0baeaf3b061ab993bf372d982ae509807e7f112554e9"}, + {file = "coverage-7.8.0-cp311-cp311-win32.whl", hash = "sha256:e75a2ad7b647fd8046d58c3132d7eaf31b12d8a53c0e4b21fa9c4d23d6ee6d3c"}, + {file = "coverage-7.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:3043ba1c88b2139126fc72cb48574b90e2e0546d4c78b5299317f61b7f718b78"}, + {file = "coverage-7.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bbb5cc845a0292e0c520656d19d7ce40e18d0e19b22cb3e0409135a575bf79fc"}, + {file = "coverage-7.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4dfd9a93db9e78666d178d4f08a5408aa3f2474ad4d0e0378ed5f2ef71640cb6"}, + {file = "coverage-7.8.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f017a61399f13aa6d1039f75cd467be388d157cd81f1a119b9d9a68ba6f2830d"}, + {file = "coverage-7.8.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0915742f4c82208ebf47a2b154a5334155ed9ef9fe6190674b8a46c2fb89cb05"}, + {file = "coverage-7.8.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a40fcf208e021eb14b0fac6bdb045c0e0cab53105f93ba0d03fd934c956143a"}, + {file = "coverage-7.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a1f406a8e0995d654b2ad87c62caf6befa767885301f3b8f6f73e6f3c31ec3a6"}, + {file = "coverage-7.8.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:77af0f6447a582fdc7de5e06fa3757a3ef87769fbb0fdbdeba78c23049140a47"}, + {file = "coverage-7.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f2d32f95922927186c6dbc8bc60df0d186b6edb828d299ab10898ef3f40052fe"}, + {file = "coverage-7.8.0-cp312-cp312-win32.whl", hash = "sha256:769773614e676f9d8e8a0980dd7740f09a6ea386d0f383db6821df07d0f08545"}, + {file = "coverage-7.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:e5d2b9be5b0693cf21eb4ce0ec8d211efb43966f6657807f6859aab3814f946b"}, + {file = "coverage-7.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5ac46d0c2dd5820ce93943a501ac5f6548ea81594777ca585bf002aa8854cacd"}, + {file = "coverage-7.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:771eb7587a0563ca5bb6f622b9ed7f9d07bd08900f7589b4febff05f469bea00"}, + {file = "coverage-7.8.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42421e04069fb2cbcbca5a696c4050b84a43b05392679d4068acbe65449b5c64"}, + {file = "coverage-7.8.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:554fec1199d93ab30adaa751db68acec2b41c5602ac944bb19187cb9a41a8067"}, + {file = "coverage-7.8.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aaeb00761f985007b38cf463b1d160a14a22c34eb3f6a39d9ad6fc27cb73008"}, + {file = "coverage-7.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:581a40c7b94921fffd6457ffe532259813fc68eb2bdda60fa8cc343414ce3733"}, + {file = "coverage-7.8.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f319bae0321bc838e205bf9e5bc28f0a3165f30c203b610f17ab5552cff90323"}, + {file = "coverage-7.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04bfec25a8ef1c5f41f5e7e5c842f6b615599ca8ba8391ec33a9290d9d2db3a3"}, + {file = "coverage-7.8.0-cp313-cp313-win32.whl", hash = "sha256:dd19608788b50eed889e13a5d71d832edc34fc9dfce606f66e8f9f917eef910d"}, + {file = "coverage-7.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:a9abbccd778d98e9c7e85038e35e91e67f5b520776781d9a1e2ee9d400869487"}, + {file = "coverage-7.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:18c5ae6d061ad5b3e7eef4363fb27a0576012a7447af48be6c75b88494c6cf25"}, + {file = "coverage-7.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:95aa6ae391a22bbbce1b77ddac846c98c5473de0372ba5c463480043a07bff42"}, + {file = "coverage-7.8.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e013b07ba1c748dacc2a80e69a46286ff145935f260eb8c72df7185bf048f502"}, + {file = "coverage-7.8.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d766a4f0e5aa1ba056ec3496243150698dc0481902e2b8559314368717be82b1"}, + {file = "coverage-7.8.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad80e6b4a0c3cb6f10f29ae4c60e991f424e6b14219d46f1e7d442b938ee68a4"}, + {file = "coverage-7.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b87eb6fc9e1bb8f98892a2458781348fa37e6925f35bb6ceb9d4afd54ba36c73"}, + {file = "coverage-7.8.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:d1ba00ae33be84066cfbe7361d4e04dec78445b2b88bdb734d0d1cbab916025a"}, + {file = "coverage-7.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f3c38e4e5ccbdc9198aecc766cedbb134b2d89bf64533973678dfcf07effd883"}, + {file = "coverage-7.8.0-cp313-cp313t-win32.whl", hash = "sha256:379fe315e206b14e21db5240f89dc0774bdd3e25c3c58c2c733c99eca96f1ada"}, + {file = "coverage-7.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2e4b6b87bb0c846a9315e3ab4be2d52fac905100565f4b92f02c445c8799e257"}, + {file = "coverage-7.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa260de59dfb143af06dcf30c2be0b200bed2a73737a8a59248fcb9fa601ef0f"}, + {file = "coverage-7.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:96121edfa4c2dfdda409877ea8608dd01de816a4dc4a0523356067b305e4e17a"}, + {file = "coverage-7.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b8af63b9afa1031c0ef05b217faa598f3069148eeee6bb24b79da9012423b82"}, + {file = "coverage-7.8.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:89b1f4af0d4afe495cd4787a68e00f30f1d15939f550e869de90a86efa7e0814"}, + {file = "coverage-7.8.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94ec0be97723ae72d63d3aa41961a0b9a6f5a53ff599813c324548d18e3b9e8c"}, + {file = "coverage-7.8.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8a1d96e780bdb2d0cbb297325711701f7c0b6f89199a57f2049e90064c29f6bd"}, + {file = "coverage-7.8.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f1d8a2a57b47142b10374902777e798784abf400a004b14f1b0b9eaf1e528ba4"}, + {file = "coverage-7.8.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:cf60dd2696b457b710dd40bf17ad269d5f5457b96442f7f85722bdb16fa6c899"}, + {file = "coverage-7.8.0-cp39-cp39-win32.whl", hash = "sha256:be945402e03de47ba1872cd5236395e0f4ad635526185a930735f66710e1bd3f"}, + {file = "coverage-7.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:90e7fbc6216ecaffa5a880cdc9c77b7418c1dcb166166b78dbc630d07f278cc3"}, + {file = "coverage-7.8.0-pp39.pp310.pp311-none-any.whl", hash = "sha256:b8194fb8e50d556d5849753de991d390c5a1edeeba50f68e3a9253fbd8bf8ccd"}, + {file = "coverage-7.8.0-py3-none-any.whl", hash = "sha256:dbf364b4c5e7bae9250528167dfe40219b62e2d573c854d74be213e1e52069f7"}, + {file = "coverage-7.8.0.tar.gz", hash = "sha256:7a3d62b3b03b4b6fd41a085f3574874cf946cb4604d2b4d3e8dca8cd570ca501"}, ] [package.extras] @@ -1097,13 +1097,13 @@ cython = ["cython"] [[package]] name = "deepdiff" -version = "8.2.0" +version = "8.4.2" description = "Deep Difference and Search of any Python object/data. Recreate objects by adding adding deltas to each other." optional = false python-versions = ">=3.8" files = [ - {file = "deepdiff-8.2.0-py3-none-any.whl", hash = "sha256:5091f2cdfd372b1b9f6bfd8065ba323ae31118dc4e42594371b38c8bea3fd0a4"}, - {file = "deepdiff-8.2.0.tar.gz", hash = "sha256:6ec78f65031485735545ffbe7a61e716c3c2d12ca6416886d5e9291fc76c46c3"}, + {file = "deepdiff-8.4.2-py3-none-any.whl", hash = "sha256:7e39e5b26f3747c54f9d0e8b9b29daab670c3100166b77cc0185d5793121b099"}, + {file = "deepdiff-8.4.2.tar.gz", hash = "sha256:5c741c0867ebc7fcb83950ad5ed958369c17f424e14dee32a11c56073f4ee92a"}, ] [package.dependencies] @@ -1412,13 +1412,13 @@ all = ["email-validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)" [[package]] name = "filelock" -version = "3.17.0" +version = "3.18.0" description = "A platform independent file lock." optional = false python-versions = ">=3.9" files = [ - {file = "filelock-3.17.0-py3-none-any.whl", hash = "sha256:533dc2f7ba78dc2f0f531fc6c4940addf7b70a481e269a5a3b93be94ffbe8338"}, - {file = "filelock-3.17.0.tar.gz", hash = "sha256:ee4e77401ef576ebb38cd7f13b9b28893194acc20a8e68e18730ba9c0e54660e"}, + {file = "filelock-3.18.0-py3-none-any.whl", hash = "sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de"}, + {file = "filelock-3.18.0.tar.gz", hash = "sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2"}, ] [package.extras] @@ -1547,20 +1547,20 @@ files = [ [[package]] name = "googleapis-common-protos" -version = "1.68.0" +version = "1.70.0" description = "Common protobufs used in Google APIs" optional = false python-versions = ">=3.7" files = [ - {file = "googleapis_common_protos-1.68.0-py2.py3-none-any.whl", hash = "sha256:aaf179b2f81df26dfadac95def3b16a95064c76a5f45f07e4c68a21bb371c4ac"}, - {file = "googleapis_common_protos-1.68.0.tar.gz", hash = "sha256:95d38161f4f9af0d9423eed8fb7b64ffd2568c3464eb542ff02c5bfa1953ab3c"}, + {file = "googleapis_common_protos-1.70.0-py3-none-any.whl", hash = "sha256:b8bfcca8c25a2bb253e0e0b0adaf8c00773e5e6af6fd92397576680b807e0fd8"}, + {file = "googleapis_common_protos-1.70.0.tar.gz", hash = "sha256:0e1b44e0ea153e6594f9f394fef15193a68aaaea2d843f83e2742717ca753257"}, ] [package.dependencies] -protobuf = ">=3.20.2,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<6.0.0.dev0" +protobuf = ">=3.20.2,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<7.0.0" [package.extras] -grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"] +grpc = ["grpcio (>=1.44.0,<2.0.0)"] [[package]] name = "gql" @@ -1606,80 +1606,76 @@ typing-extensions = {version = ">=4,<5", markers = "python_version < \"3.10\""} [[package]] name = "grpcio" -version = "1.70.0" +version = "1.71.0" description = "HTTP/2-based RPC framework" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "grpcio-1.70.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:95469d1977429f45fe7df441f586521361e235982a0b39e33841549143ae2851"}, - {file = "grpcio-1.70.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:ed9718f17fbdb472e33b869c77a16d0b55e166b100ec57b016dc7de9c8d236bf"}, - {file = "grpcio-1.70.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:374d014f29f9dfdb40510b041792e0e2828a1389281eb590df066e1cc2b404e5"}, - {file = "grpcio-1.70.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2af68a6f5c8f78d56c145161544ad0febbd7479524a59c16b3e25053f39c87f"}, - {file = "grpcio-1.70.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce7df14b2dcd1102a2ec32f621cc9fab6695effef516efbc6b063ad749867295"}, - {file = "grpcio-1.70.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c78b339869f4dbf89881e0b6fbf376313e4f845a42840a7bdf42ee6caed4b11f"}, - {file = "grpcio-1.70.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:58ad9ba575b39edef71f4798fdb5c7b6d02ad36d47949cd381d4392a5c9cbcd3"}, - {file = "grpcio-1.70.0-cp310-cp310-win32.whl", hash = "sha256:2b0d02e4b25a5c1f9b6c7745d4fa06efc9fd6a611af0fb38d3ba956786b95199"}, - {file = "grpcio-1.70.0-cp310-cp310-win_amd64.whl", hash = "sha256:0de706c0a5bb9d841e353f6343a9defc9fc35ec61d6eb6111802f3aa9fef29e1"}, - {file = "grpcio-1.70.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:17325b0be0c068f35770f944124e8839ea3185d6d54862800fc28cc2ffad205a"}, - {file = "grpcio-1.70.0-cp311-cp311-macosx_10_14_universal2.whl", hash = "sha256:dbe41ad140df911e796d4463168e33ef80a24f5d21ef4d1e310553fcd2c4a386"}, - {file = "grpcio-1.70.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:5ea67c72101d687d44d9c56068328da39c9ccba634cabb336075fae2eab0d04b"}, - {file = "grpcio-1.70.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cb5277db254ab7586769e490b7b22f4ddab3876c490da0a1a9d7c695ccf0bf77"}, - {file = "grpcio-1.70.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7831a0fc1beeeb7759f737f5acd9fdcda520e955049512d68fda03d91186eea"}, - {file = "grpcio-1.70.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:27cc75e22c5dba1fbaf5a66c778e36ca9b8ce850bf58a9db887754593080d839"}, - {file = "grpcio-1.70.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d63764963412e22f0491d0d32833d71087288f4e24cbcddbae82476bfa1d81fd"}, - {file = "grpcio-1.70.0-cp311-cp311-win32.whl", hash = "sha256:bb491125103c800ec209d84c9b51f1c60ea456038e4734688004f377cfacc113"}, - {file = "grpcio-1.70.0-cp311-cp311-win_amd64.whl", hash = "sha256:d24035d49e026353eb042bf7b058fb831db3e06d52bee75c5f2f3ab453e71aca"}, - {file = "grpcio-1.70.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:ef4c14508299b1406c32bdbb9fb7b47612ab979b04cf2b27686ea31882387cff"}, - {file = "grpcio-1.70.0-cp312-cp312-macosx_10_14_universal2.whl", hash = "sha256:aa47688a65643afd8b166928a1da6247d3f46a2784d301e48ca1cc394d2ffb40"}, - {file = "grpcio-1.70.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:880bfb43b1bb8905701b926274eafce5c70a105bc6b99e25f62e98ad59cb278e"}, - {file = "grpcio-1.70.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e654c4b17d07eab259d392e12b149c3a134ec52b11ecdc6a515b39aceeec898"}, - {file = "grpcio-1.70.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2394e3381071045a706ee2eeb6e08962dd87e8999b90ac15c55f56fa5a8c9597"}, - {file = "grpcio-1.70.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:b3c76701428d2df01964bc6479422f20e62fcbc0a37d82ebd58050b86926ef8c"}, - {file = "grpcio-1.70.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ac073fe1c4cd856ebcf49e9ed6240f4f84d7a4e6ee95baa5d66ea05d3dd0df7f"}, - {file = "grpcio-1.70.0-cp312-cp312-win32.whl", hash = "sha256:cd24d2d9d380fbbee7a5ac86afe9787813f285e684b0271599f95a51bce33528"}, - {file = "grpcio-1.70.0-cp312-cp312-win_amd64.whl", hash = "sha256:0495c86a55a04a874c7627fd33e5beaee771917d92c0e6d9d797628ac40e7655"}, - {file = "grpcio-1.70.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:aa573896aeb7d7ce10b1fa425ba263e8dddd83d71530d1322fd3a16f31257b4a"}, - {file = "grpcio-1.70.0-cp313-cp313-macosx_10_14_universal2.whl", hash = "sha256:d405b005018fd516c9ac529f4b4122342f60ec1cee181788249372524e6db429"}, - {file = "grpcio-1.70.0-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:f32090238b720eb585248654db8e3afc87b48d26ac423c8dde8334a232ff53c9"}, - {file = "grpcio-1.70.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfa089a734f24ee5f6880c83d043e4f46bf812fcea5181dcb3a572db1e79e01c"}, - {file = "grpcio-1.70.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f19375f0300b96c0117aca118d400e76fede6db6e91f3c34b7b035822e06c35f"}, - {file = "grpcio-1.70.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:7c73c42102e4a5ec76608d9b60227d917cea46dff4d11d372f64cbeb56d259d0"}, - {file = "grpcio-1.70.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:0a5c78d5198a1f0aa60006cd6eb1c912b4a1520b6a3968e677dbcba215fabb40"}, - {file = "grpcio-1.70.0-cp313-cp313-win32.whl", hash = "sha256:fe9dbd916df3b60e865258a8c72ac98f3ac9e2a9542dcb72b7a34d236242a5ce"}, - {file = "grpcio-1.70.0-cp313-cp313-win_amd64.whl", hash = "sha256:4119fed8abb7ff6c32e3d2255301e59c316c22d31ab812b3fbcbaf3d0d87cc68"}, - {file = "grpcio-1.70.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:8058667a755f97407fca257c844018b80004ae8035565ebc2812cc550110718d"}, - {file = "grpcio-1.70.0-cp38-cp38-macosx_10_14_universal2.whl", hash = "sha256:879a61bf52ff8ccacbedf534665bb5478ec8e86ad483e76fe4f729aaef867cab"}, - {file = "grpcio-1.70.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:0ba0a173f4feacf90ee618fbc1a27956bfd21260cd31ced9bc707ef551ff7dc7"}, - {file = "grpcio-1.70.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:558c386ecb0148f4f99b1a65160f9d4b790ed3163e8610d11db47838d452512d"}, - {file = "grpcio-1.70.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:412faabcc787bbc826f51be261ae5fa996b21263de5368a55dc2cf824dc5090e"}, - {file = "grpcio-1.70.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3b0f01f6ed9994d7a0b27eeddea43ceac1b7e6f3f9d86aeec0f0064b8cf50fdb"}, - {file = "grpcio-1.70.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7385b1cb064734005204bc8994eed7dcb801ed6c2eda283f613ad8c6c75cf873"}, - {file = "grpcio-1.70.0-cp38-cp38-win32.whl", hash = "sha256:07269ff4940f6fb6710951116a04cd70284da86d0a4368fd5a3b552744511f5a"}, - {file = "grpcio-1.70.0-cp38-cp38-win_amd64.whl", hash = "sha256:aba19419aef9b254e15011b230a180e26e0f6864c90406fdbc255f01d83bc83c"}, - {file = "grpcio-1.70.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:4f1937f47c77392ccd555728f564a49128b6a197a05a5cd527b796d36f3387d0"}, - {file = "grpcio-1.70.0-cp39-cp39-macosx_10_14_universal2.whl", hash = "sha256:0cd430b9215a15c10b0e7d78f51e8a39d6cf2ea819fd635a7214fae600b1da27"}, - {file = "grpcio-1.70.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:e27585831aa6b57b9250abaf147003e126cd3a6c6ca0c531a01996f31709bed1"}, - {file = "grpcio-1.70.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c1af8e15b0f0fe0eac75195992a63df17579553b0c4af9f8362cc7cc99ccddf4"}, - {file = "grpcio-1.70.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cbce24409beaee911c574a3d75d12ffb8c3e3dd1b813321b1d7a96bbcac46bf4"}, - {file = "grpcio-1.70.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ff4a8112a79464919bb21c18e956c54add43ec9a4850e3949da54f61c241a4a6"}, - {file = "grpcio-1.70.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5413549fdf0b14046c545e19cfc4eb1e37e9e1ebba0ca390a8d4e9963cab44d2"}, - {file = "grpcio-1.70.0-cp39-cp39-win32.whl", hash = "sha256:b745d2c41b27650095e81dea7091668c040457483c9bdb5d0d9de8f8eb25e59f"}, - {file = "grpcio-1.70.0-cp39-cp39-win_amd64.whl", hash = "sha256:a31d7e3b529c94e930a117b2175b2efd179d96eb3c7a21ccb0289a8ab05b645c"}, - {file = "grpcio-1.70.0.tar.gz", hash = "sha256:8d1584a68d5922330025881e63a6c1b54cc8117291d382e4fa69339b6d914c56"}, + {file = "grpcio-1.71.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:c200cb6f2393468142eb50ab19613229dcc7829b5ccee8b658a36005f6669fdd"}, + {file = "grpcio-1.71.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:b2266862c5ad664a380fbbcdbdb8289d71464c42a8c29053820ee78ba0119e5d"}, + {file = "grpcio-1.71.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:0ab8b2864396663a5b0b0d6d79495657ae85fa37dcb6498a2669d067c65c11ea"}, + {file = "grpcio-1.71.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c30f393f9d5ff00a71bb56de4aa75b8fe91b161aeb61d39528db6b768d7eac69"}, + {file = "grpcio-1.71.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f250ff44843d9a0615e350c77f890082102a0318d66a99540f54769c8766ab73"}, + {file = "grpcio-1.71.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e6d8de076528f7c43a2f576bc311799f89d795aa6c9b637377cc2b1616473804"}, + {file = "grpcio-1.71.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:9b91879d6da1605811ebc60d21ab6a7e4bae6c35f6b63a061d61eb818c8168f6"}, + {file = "grpcio-1.71.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f71574afdf944e6652203cd1badcda195b2a27d9c83e6d88dc1ce3cfb73b31a5"}, + {file = "grpcio-1.71.0-cp310-cp310-win32.whl", hash = "sha256:8997d6785e93308f277884ee6899ba63baafa0dfb4729748200fcc537858a509"}, + {file = "grpcio-1.71.0-cp310-cp310-win_amd64.whl", hash = "sha256:7d6ac9481d9d0d129224f6d5934d5832c4b1cddb96b59e7eba8416868909786a"}, + {file = "grpcio-1.71.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:d6aa986318c36508dc1d5001a3ff169a15b99b9f96ef5e98e13522c506b37eef"}, + {file = "grpcio-1.71.0-cp311-cp311-macosx_10_14_universal2.whl", hash = "sha256:d2c170247315f2d7e5798a22358e982ad6eeb68fa20cf7a820bb74c11f0736e7"}, + {file = "grpcio-1.71.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:e6f83a583ed0a5b08c5bc7a3fe860bb3c2eac1f03f1f63e0bc2091325605d2b7"}, + {file = "grpcio-1.71.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4be74ddeeb92cc87190e0e376dbc8fc7736dbb6d3d454f2fa1f5be1dee26b9d7"}, + {file = "grpcio-1.71.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4dd0dfbe4d5eb1fcfec9490ca13f82b089a309dc3678e2edabc144051270a66e"}, + {file = "grpcio-1.71.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a2242d6950dc892afdf9e951ed7ff89473aaf744b7d5727ad56bdaace363722b"}, + {file = "grpcio-1.71.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0fa05ee31a20456b13ae49ad2e5d585265f71dd19fbd9ef983c28f926d45d0a7"}, + {file = "grpcio-1.71.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3d081e859fb1ebe176de33fc3adb26c7d46b8812f906042705346b314bde32c3"}, + {file = "grpcio-1.71.0-cp311-cp311-win32.whl", hash = "sha256:d6de81c9c00c8a23047136b11794b3584cdc1460ed7cbc10eada50614baa1444"}, + {file = "grpcio-1.71.0-cp311-cp311-win_amd64.whl", hash = "sha256:24e867651fc67717b6f896d5f0cac0ec863a8b5fb7d6441c2ab428f52c651c6b"}, + {file = "grpcio-1.71.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:0ff35c8d807c1c7531d3002be03221ff9ae15712b53ab46e2a0b4bb271f38537"}, + {file = "grpcio-1.71.0-cp312-cp312-macosx_10_14_universal2.whl", hash = "sha256:b78a99cd1ece4be92ab7c07765a0b038194ded2e0a26fd654591ee136088d8d7"}, + {file = "grpcio-1.71.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:dc1a1231ed23caac1de9f943d031f1bc38d0f69d2a3b243ea0d664fc1fbd7fec"}, + {file = "grpcio-1.71.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e6beeea5566092c5e3c4896c6d1d307fb46b1d4bdf3e70c8340b190a69198594"}, + {file = "grpcio-1.71.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5170929109450a2c031cfe87d6716f2fae39695ad5335d9106ae88cc32dc84c"}, + {file = "grpcio-1.71.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5b08d03ace7aca7b2fadd4baf291139b4a5f058805a8327bfe9aece7253b6d67"}, + {file = "grpcio-1.71.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:f903017db76bf9cc2b2d8bdd37bf04b505bbccad6be8a81e1542206875d0e9db"}, + {file = "grpcio-1.71.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:469f42a0b410883185eab4689060a20488a1a0a00f8bbb3cbc1061197b4c5a79"}, + {file = "grpcio-1.71.0-cp312-cp312-win32.whl", hash = "sha256:ad9f30838550695b5eb302add33f21f7301b882937460dd24f24b3cc5a95067a"}, + {file = "grpcio-1.71.0-cp312-cp312-win_amd64.whl", hash = "sha256:652350609332de6dac4ece254e5d7e1ff834e203d6afb769601f286886f6f3a8"}, + {file = "grpcio-1.71.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:cebc1b34ba40a312ab480ccdb396ff3c529377a2fce72c45a741f7215bfe8379"}, + {file = "grpcio-1.71.0-cp313-cp313-macosx_10_14_universal2.whl", hash = "sha256:85da336e3649a3d2171e82f696b5cad2c6231fdd5bad52616476235681bee5b3"}, + {file = "grpcio-1.71.0-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:f9a412f55bb6e8f3bb000e020dbc1e709627dcb3a56f6431fa7076b4c1aab0db"}, + {file = "grpcio-1.71.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47be9584729534660416f6d2a3108aaeac1122f6b5bdbf9fd823e11fe6fbaa29"}, + {file = "grpcio-1.71.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c9c80ac6091c916db81131d50926a93ab162a7e97e4428ffc186b6e80d6dda4"}, + {file = "grpcio-1.71.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:789d5e2a3a15419374b7b45cd680b1e83bbc1e52b9086e49308e2c0b5bbae6e3"}, + {file = "grpcio-1.71.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:1be857615e26a86d7363e8a163fade914595c81fec962b3d514a4b1e8760467b"}, + {file = "grpcio-1.71.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:a76d39b5fafd79ed604c4be0a869ec3581a172a707e2a8d7a4858cb05a5a7637"}, + {file = "grpcio-1.71.0-cp313-cp313-win32.whl", hash = "sha256:74258dce215cb1995083daa17b379a1a5a87d275387b7ffe137f1d5131e2cfbb"}, + {file = "grpcio-1.71.0-cp313-cp313-win_amd64.whl", hash = "sha256:22c3bc8d488c039a199f7a003a38cb7635db6656fa96437a8accde8322ce2366"}, + {file = "grpcio-1.71.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:c6a0a28450c16809f94e0b5bfe52cabff63e7e4b97b44123ebf77f448534d07d"}, + {file = "grpcio-1.71.0-cp39-cp39-macosx_10_14_universal2.whl", hash = "sha256:a371e6b6a5379d3692cc4ea1cb92754d2a47bdddeee755d3203d1f84ae08e03e"}, + {file = "grpcio-1.71.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:39983a9245d37394fd59de71e88c4b295eb510a3555e0a847d9965088cdbd033"}, + {file = "grpcio-1.71.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9182e0063112e55e74ee7584769ec5a0b4f18252c35787f48738627e23a62b97"}, + {file = "grpcio-1.71.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693bc706c031aeb848849b9d1c6b63ae6bcc64057984bb91a542332b75aa4c3d"}, + {file = "grpcio-1.71.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:20e8f653abd5ec606be69540f57289274c9ca503ed38388481e98fa396ed0b41"}, + {file = "grpcio-1.71.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:8700a2a57771cc43ea295296330daaddc0d93c088f0a35cc969292b6db959bf3"}, + {file = "grpcio-1.71.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d35a95f05a8a2cbe8e02be137740138b3b2ea5f80bd004444e4f9a1ffc511e32"}, + {file = "grpcio-1.71.0-cp39-cp39-win32.whl", hash = "sha256:f9c30c464cb2ddfbc2ddf9400287701270fdc0f14be5f08a1e3939f1e749b455"}, + {file = "grpcio-1.71.0-cp39-cp39-win_amd64.whl", hash = "sha256:63e41b91032f298b3e973b3fa4093cbbc620c875e2da7b93e249d4728b54559a"}, + {file = "grpcio-1.71.0.tar.gz", hash = "sha256:2b85f7820475ad3edec209d3d89a7909ada16caab05d3f2e08a7e8ae3200a55c"}, ] [package.extras] -protobuf = ["grpcio-tools (>=1.70.0)"] +protobuf = ["grpcio-tools (>=1.71.0)"] [[package]] name = "h11" -version = "0.14.0" +version = "0.16.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, - {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, + {file = "h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86"}, + {file = "h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1"}, ] [[package]] @@ -1722,18 +1718,18 @@ test = ["eth-utils (>=1.0.1,<3)", "hypothesis (>=3.44.24,<=6.31.6)", "pytest (>= [[package]] name = "httpcore" -version = "1.0.7" +version = "1.0.9" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, - {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, + {file = "httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55"}, + {file = "httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8"}, ] [package.dependencies] certifi = "*" -h11 = ">=0.13,<0.15" +h11 = ">=0.16" [package.extras] asyncio = ["anyio (>=4.0,<5.0)"] @@ -1782,13 +1778,13 @@ all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2 [[package]] name = "importlib-metadata" -version = "8.6.1" +version = "8.7.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.9" files = [ - {file = "importlib_metadata-8.6.1-py3-none-any.whl", hash = "sha256:02a89390c1e15fdfdc0d7c6b25cb3e62650d0494005c97d6f148bf5b9787525e"}, - {file = "importlib_metadata-8.6.1.tar.gz", hash = "sha256:310b41d755445d74569f993ccfc22838295d9fe005425094fad953d7f15c8580"}, + {file = "importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd"}, + {file = "importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000"}, ] [package.dependencies] @@ -1805,13 +1801,13 @@ type = ["pytest-mypy"] [[package]] name = "iniconfig" -version = "2.0.0" +version = "2.1.0" description = "brain-dead simple config-ini parsing" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, + {file = "iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"}, + {file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"}, ] [[package]] @@ -1842,13 +1838,13 @@ files = [ [[package]] name = "jinja2" -version = "3.1.5" +version = "3.1.6" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, - {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, + {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"}, + {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"}, ] [package.dependencies] @@ -1985,149 +1981,140 @@ test = ["pytest"] [[package]] name = "lxml" -version = "5.3.1" +version = "5.4.0" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." optional = false python-versions = ">=3.6" files = [ - {file = "lxml-5.3.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a4058f16cee694577f7e4dd410263cd0ef75644b43802a689c2b3c2a7e69453b"}, - {file = "lxml-5.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:364de8f57d6eda0c16dcfb999af902da31396949efa0e583e12675d09709881b"}, - {file = "lxml-5.3.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:528f3a0498a8edc69af0559bdcf8a9f5a8bf7c00051a6ef3141fdcf27017bbf5"}, - {file = "lxml-5.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db4743e30d6f5f92b6d2b7c86b3ad250e0bad8dee4b7ad8a0c44bfb276af89a3"}, - {file = "lxml-5.3.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:17b5d7f8acf809465086d498d62a981fa6a56d2718135bb0e4aa48c502055f5c"}, - {file = "lxml-5.3.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:928e75a7200a4c09e6efc7482a1337919cc61fe1ba289f297827a5b76d8969c2"}, - {file = "lxml-5.3.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a997b784a639e05b9d4053ef3b20c7e447ea80814a762f25b8ed5a89d261eac"}, - {file = "lxml-5.3.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:7b82e67c5feb682dbb559c3e6b78355f234943053af61606af126df2183b9ef9"}, - {file = "lxml-5.3.1-cp310-cp310-manylinux_2_28_ppc64le.whl", hash = "sha256:f1de541a9893cf8a1b1db9bf0bf670a2decab42e3e82233d36a74eda7822b4c9"}, - {file = "lxml-5.3.1-cp310-cp310-manylinux_2_28_s390x.whl", hash = "sha256:de1fc314c3ad6bc2f6bd5b5a5b9357b8c6896333d27fdbb7049aea8bd5af2d79"}, - {file = "lxml-5.3.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:7c0536bd9178f754b277a3e53f90f9c9454a3bd108b1531ffff720e082d824f2"}, - {file = "lxml-5.3.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:68018c4c67d7e89951a91fbd371e2e34cd8cfc71f0bb43b5332db38497025d51"}, - {file = "lxml-5.3.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:aa826340a609d0c954ba52fd831f0fba2a4165659ab0ee1a15e4aac21f302406"}, - {file = "lxml-5.3.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:796520afa499732191e39fc95b56a3b07f95256f2d22b1c26e217fb69a9db5b5"}, - {file = "lxml-5.3.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3effe081b3135237da6e4c4530ff2a868d3f80be0bda027e118a5971285d42d0"}, - {file = "lxml-5.3.1-cp310-cp310-win32.whl", hash = "sha256:a22f66270bd6d0804b02cd49dae2b33d4341015545d17f8426f2c4e22f557a23"}, - {file = "lxml-5.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:0bcfadea3cdc68e678d2b20cb16a16716887dd00a881e16f7d806c2138b8ff0c"}, - {file = "lxml-5.3.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e220f7b3e8656ab063d2eb0cd536fafef396829cafe04cb314e734f87649058f"}, - {file = "lxml-5.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0f2cfae0688fd01f7056a17367e3b84f37c545fb447d7282cf2c242b16262607"}, - {file = "lxml-5.3.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:67d2f8ad9dcc3a9e826bdc7802ed541a44e124c29b7d95a679eeb58c1c14ade8"}, - {file = "lxml-5.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db0c742aad702fd5d0c6611a73f9602f20aec2007c102630c06d7633d9c8f09a"}, - {file = "lxml-5.3.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:198bb4b4dd888e8390afa4f170d4fa28467a7eaf857f1952589f16cfbb67af27"}, - {file = "lxml-5.3.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d2a3e412ce1849be34b45922bfef03df32d1410a06d1cdeb793a343c2f1fd666"}, - {file = "lxml-5.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b8969dbc8d09d9cd2ae06362c3bad27d03f433252601ef658a49bd9f2b22d79"}, - {file = "lxml-5.3.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:5be8f5e4044146a69c96077c7e08f0709c13a314aa5315981185c1f00235fe65"}, - {file = "lxml-5.3.1-cp311-cp311-manylinux_2_28_ppc64le.whl", hash = "sha256:133f3493253a00db2c870d3740bc458ebb7d937bd0a6a4f9328373e0db305709"}, - {file = "lxml-5.3.1-cp311-cp311-manylinux_2_28_s390x.whl", hash = "sha256:52d82b0d436edd6a1d22d94a344b9a58abd6c68c357ed44f22d4ba8179b37629"}, - {file = "lxml-5.3.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:1b6f92e35e2658a5ed51c6634ceb5ddae32053182851d8cad2a5bc102a359b33"}, - {file = "lxml-5.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:203b1d3eaebd34277be06a3eb880050f18a4e4d60861efba4fb946e31071a295"}, - {file = "lxml-5.3.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:155e1a5693cf4b55af652f5c0f78ef36596c7f680ff3ec6eb4d7d85367259b2c"}, - {file = "lxml-5.3.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:22ec2b3c191f43ed21f9545e9df94c37c6b49a5af0a874008ddc9132d49a2d9c"}, - {file = "lxml-5.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7eda194dd46e40ec745bf76795a7cccb02a6a41f445ad49d3cf66518b0bd9cff"}, - {file = "lxml-5.3.1-cp311-cp311-win32.whl", hash = "sha256:fb7c61d4be18e930f75948705e9718618862e6fc2ed0d7159b2262be73f167a2"}, - {file = "lxml-5.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:c809eef167bf4a57af4b03007004896f5c60bd38dc3852fcd97a26eae3d4c9e6"}, - {file = "lxml-5.3.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:e69add9b6b7b08c60d7ff0152c7c9a6c45b4a71a919be5abde6f98f1ea16421c"}, - {file = "lxml-5.3.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4e52e1b148867b01c05e21837586ee307a01e793b94072d7c7b91d2c2da02ffe"}, - {file = "lxml-5.3.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4b382e0e636ed54cd278791d93fe2c4f370772743f02bcbe431a160089025c9"}, - {file = "lxml-5.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2e49dc23a10a1296b04ca9db200c44d3eb32c8d8ec532e8c1fd24792276522a"}, - {file = "lxml-5.3.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4399b4226c4785575fb20998dc571bc48125dc92c367ce2602d0d70e0c455eb0"}, - {file = "lxml-5.3.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5412500e0dc5481b1ee9cf6b38bb3b473f6e411eb62b83dc9b62699c3b7b79f7"}, - {file = "lxml-5.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c93ed3c998ea8472be98fb55aed65b5198740bfceaec07b2eba551e55b7b9ae"}, - {file = "lxml-5.3.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:63d57fc94eb0bbb4735e45517afc21ef262991d8758a8f2f05dd6e4174944519"}, - {file = "lxml-5.3.1-cp312-cp312-manylinux_2_28_ppc64le.whl", hash = "sha256:b450d7cabcd49aa7ab46a3c6aa3ac7e1593600a1a0605ba536ec0f1b99a04322"}, - {file = "lxml-5.3.1-cp312-cp312-manylinux_2_28_s390x.whl", hash = "sha256:4df0ec814b50275ad6a99bc82a38b59f90e10e47714ac9871e1b223895825468"}, - {file = "lxml-5.3.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:d184f85ad2bb1f261eac55cddfcf62a70dee89982c978e92b9a74a1bfef2e367"}, - {file = "lxml-5.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b725e70d15906d24615201e650d5b0388b08a5187a55f119f25874d0103f90dd"}, - {file = "lxml-5.3.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:a31fa7536ec1fb7155a0cd3a4e3d956c835ad0a43e3610ca32384d01f079ea1c"}, - {file = "lxml-5.3.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3c3c8b55c7fc7b7e8877b9366568cc73d68b82da7fe33d8b98527b73857a225f"}, - {file = "lxml-5.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d61ec60945d694df806a9aec88e8f29a27293c6e424f8ff91c80416e3c617645"}, - {file = "lxml-5.3.1-cp312-cp312-win32.whl", hash = "sha256:f4eac0584cdc3285ef2e74eee1513a6001681fd9753b259e8159421ed28a72e5"}, - {file = "lxml-5.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:29bfc8d3d88e56ea0a27e7c4897b642706840247f59f4377d81be8f32aa0cfbf"}, - {file = "lxml-5.3.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c093c7088b40d8266f57ed71d93112bd64c6724d31f0794c1e52cc4857c28e0e"}, - {file = "lxml-5.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b0884e3f22d87c30694e625b1e62e6f30d39782c806287450d9dc2fdf07692fd"}, - {file = "lxml-5.3.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1637fa31ec682cd5760092adfabe86d9b718a75d43e65e211d5931809bc111e7"}, - {file = "lxml-5.3.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a364e8e944d92dcbf33b6b494d4e0fb3499dcc3bd9485beb701aa4b4201fa414"}, - {file = "lxml-5.3.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:779e851fd0e19795ccc8a9bb4d705d6baa0ef475329fe44a13cf1e962f18ff1e"}, - {file = "lxml-5.3.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c4393600915c308e546dc7003d74371744234e8444a28622d76fe19b98fa59d1"}, - {file = "lxml-5.3.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:673b9d8e780f455091200bba8534d5f4f465944cbdd61f31dc832d70e29064a5"}, - {file = "lxml-5.3.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:2e4a570f6a99e96c457f7bec5ad459c9c420ee80b99eb04cbfcfe3fc18ec6423"}, - {file = "lxml-5.3.1-cp313-cp313-manylinux_2_28_ppc64le.whl", hash = "sha256:71f31eda4e370f46af42fc9f264fafa1b09f46ba07bdbee98f25689a04b81c20"}, - {file = "lxml-5.3.1-cp313-cp313-manylinux_2_28_s390x.whl", hash = "sha256:42978a68d3825eaac55399eb37a4d52012a205c0c6262199b8b44fcc6fd686e8"}, - {file = "lxml-5.3.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:8b1942b3e4ed9ed551ed3083a2e6e0772de1e5e3aca872d955e2e86385fb7ff9"}, - {file = "lxml-5.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:85c4f11be9cf08917ac2a5a8b6e1ef63b2f8e3799cec194417e76826e5f1de9c"}, - {file = "lxml-5.3.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:231cf4d140b22a923b1d0a0a4e0b4f972e5893efcdec188934cc65888fd0227b"}, - {file = "lxml-5.3.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:5865b270b420eda7b68928d70bb517ccbe045e53b1a428129bb44372bf3d7dd5"}, - {file = "lxml-5.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:dbf7bebc2275016cddf3c997bf8a0f7044160714c64a9b83975670a04e6d2252"}, - {file = "lxml-5.3.1-cp313-cp313-win32.whl", hash = "sha256:d0751528b97d2b19a388b302be2a0ee05817097bab46ff0ed76feeec24951f78"}, - {file = "lxml-5.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:91fb6a43d72b4f8863d21f347a9163eecbf36e76e2f51068d59cd004c506f332"}, - {file = "lxml-5.3.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:016b96c58e9a4528219bb563acf1aaaa8bc5452e7651004894a973f03b84ba81"}, - {file = "lxml-5.3.1-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82a4bb10b0beef1434fb23a09f001ab5ca87895596b4581fd53f1e5145a8934a"}, - {file = "lxml-5.3.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d68eeef7b4d08a25e51897dac29bcb62aba830e9ac6c4e3297ee7c6a0cf6439"}, - {file = "lxml-5.3.1-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:f12582b8d3b4c6be1d298c49cb7ae64a3a73efaf4c2ab4e37db182e3545815ac"}, - {file = "lxml-5.3.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2df7ed5edeb6bd5590914cd61df76eb6cce9d590ed04ec7c183cf5509f73530d"}, - {file = "lxml-5.3.1-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:585c4dc429deebc4307187d2b71ebe914843185ae16a4d582ee030e6cfbb4d8a"}, - {file = "lxml-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:06a20d607a86fccab2fc15a77aa445f2bdef7b49ec0520a842c5c5afd8381576"}, - {file = "lxml-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:057e30d0012439bc54ca427a83d458752ccda725c1c161cc283db07bcad43cf9"}, - {file = "lxml-5.3.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4867361c049761a56bd21de507cab2c2a608c55102311d142ade7dab67b34f32"}, - {file = "lxml-5.3.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3dddf0fb832486cc1ea71d189cb92eb887826e8deebe128884e15020bb6e3f61"}, - {file = "lxml-5.3.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bcc211542f7af6f2dfb705f5f8b74e865592778e6cafdfd19c792c244ccce19"}, - {file = "lxml-5.3.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aaca5a812f050ab55426c32177091130b1e49329b3f002a32934cd0245571307"}, - {file = "lxml-5.3.1-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:236610b77589faf462337b3305a1be91756c8abc5a45ff7ca8f245a71c5dab70"}, - {file = "lxml-5.3.1-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:aed57b541b589fa05ac248f4cb1c46cbb432ab82cbd467d1c4f6a2bdc18aecf9"}, - {file = "lxml-5.3.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:75fa3d6946d317ffc7016a6fcc44f42db6d514b7fdb8b4b28cbe058303cb6e53"}, - {file = "lxml-5.3.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:96eef5b9f336f623ffc555ab47a775495e7e8846dde88de5f941e2906453a1ce"}, - {file = "lxml-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:ef45f31aec9be01379fc6c10f1d9c677f032f2bac9383c827d44f620e8a88407"}, - {file = "lxml-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0611da6b07dd3720f492db1b463a4d1175b096b49438761cc9f35f0d9eaaef5"}, - {file = "lxml-5.3.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b2aca14c235c7a08558fe0a4786a1a05873a01e86b474dfa8f6df49101853a4e"}, - {file = "lxml-5.3.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae82fce1d964f065c32c9517309f0c7be588772352d2f40b1574a214bd6e6098"}, - {file = "lxml-5.3.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7aae7a3d63b935babfdc6864b31196afd5145878ddd22f5200729006366bc4d5"}, - {file = "lxml-5.3.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8e0d177b1fe251c3b1b914ab64135475c5273c8cfd2857964b2e3bb0fe196a7"}, - {file = "lxml-5.3.1-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:6c4dd3bfd0c82400060896717dd261137398edb7e524527438c54a8c34f736bf"}, - {file = "lxml-5.3.1-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:f1208c1c67ec9e151d78aa3435aa9b08a488b53d9cfac9b699f15255a3461ef2"}, - {file = "lxml-5.3.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:c6aacf00d05b38a5069826e50ae72751cb5bc27bdc4d5746203988e429b385bb"}, - {file = "lxml-5.3.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5881aaa4bf3a2d086c5f20371d3a5856199a0d8ac72dd8d0dbd7a2ecfc26ab73"}, - {file = "lxml-5.3.1-cp38-cp38-win32.whl", hash = "sha256:45fbb70ccbc8683f2fb58bea89498a7274af1d9ec7995e9f4af5604e028233fc"}, - {file = "lxml-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:7512b4d0fc5339d5abbb14d1843f70499cab90d0b864f790e73f780f041615d7"}, - {file = "lxml-5.3.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5885bc586f1edb48e5d68e7a4b4757b5feb2a496b64f462b4d65950f5af3364f"}, - {file = "lxml-5.3.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1b92fe86e04f680b848fff594a908edfa72b31bfc3499ef7433790c11d4c8cd8"}, - {file = "lxml-5.3.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a091026c3bf7519ab1e64655a3f52a59ad4a4e019a6f830c24d6430695b1cf6a"}, - {file = "lxml-5.3.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8ffb141361108e864ab5f1813f66e4e1164181227f9b1f105b042729b6c15125"}, - {file = "lxml-5.3.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3715cdf0dd31b836433af9ee9197af10e3df41d273c19bb249230043667a5dfd"}, - {file = "lxml-5.3.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88b72eb7222d918c967202024812c2bfb4048deeb69ca328363fb8e15254c549"}, - {file = "lxml-5.3.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa59974880ab5ad8ef3afaa26f9bda148c5f39e06b11a8ada4660ecc9fb2feb3"}, - {file = "lxml-5.3.1-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:3bb8149840daf2c3f97cebf00e4ed4a65a0baff888bf2605a8d0135ff5cf764e"}, - {file = "lxml-5.3.1-cp39-cp39-manylinux_2_28_ppc64le.whl", hash = "sha256:0d6b2fa86becfa81f0a0271ccb9eb127ad45fb597733a77b92e8a35e53414914"}, - {file = "lxml-5.3.1-cp39-cp39-manylinux_2_28_s390x.whl", hash = "sha256:136bf638d92848a939fd8f0e06fcf92d9f2e4b57969d94faae27c55f3d85c05b"}, - {file = "lxml-5.3.1-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:89934f9f791566e54c1d92cdc8f8fd0009447a5ecdb1ec6b810d5f8c4955f6be"}, - {file = "lxml-5.3.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a8ade0363f776f87f982572c2860cc43c65ace208db49c76df0a21dde4ddd16e"}, - {file = "lxml-5.3.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:bfbbab9316330cf81656fed435311386610f78b6c93cc5db4bebbce8dd146675"}, - {file = "lxml-5.3.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:172d65f7c72a35a6879217bcdb4bb11bc88d55fb4879e7569f55616062d387c2"}, - {file = "lxml-5.3.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e3c623923967f3e5961d272718655946e5322b8d058e094764180cdee7bab1af"}, - {file = "lxml-5.3.1-cp39-cp39-win32.whl", hash = "sha256:ce0930a963ff593e8bb6fda49a503911accc67dee7e5445eec972668e672a0f0"}, - {file = "lxml-5.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:f7b64fcd670bca8800bc10ced36620c6bbb321e7bc1214b9c0c0df269c1dddc2"}, - {file = "lxml-5.3.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:afa578b6524ff85fb365f454cf61683771d0170470c48ad9d170c48075f86725"}, - {file = "lxml-5.3.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67f5e80adf0aafc7b5454f2c1cb0cde920c9b1f2cbd0485f07cc1d0497c35c5d"}, - {file = "lxml-5.3.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dd0b80ac2d8f13ffc906123a6f20b459cb50a99222d0da492360512f3e50f84"}, - {file = "lxml-5.3.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:422c179022ecdedbe58b0e242607198580804253da220e9454ffe848daa1cfd2"}, - {file = "lxml-5.3.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:524ccfded8989a6595dbdda80d779fb977dbc9a7bc458864fc9a0c2fc15dc877"}, - {file = "lxml-5.3.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:48fd46bf7155def2e15287c6f2b133a2f78e2d22cdf55647269977b873c65499"}, - {file = "lxml-5.3.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:05123fad495a429f123307ac6d8fd6f977b71e9a0b6d9aeeb8f80c017cb17131"}, - {file = "lxml-5.3.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a243132767150a44e6a93cd1dde41010036e1cbc63cc3e9fe1712b277d926ce3"}, - {file = "lxml-5.3.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c92ea6d9dd84a750b2bae72ff5e8cf5fdd13e58dda79c33e057862c29a8d5b50"}, - {file = "lxml-5.3.1-pp37-pypy37_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:2f1be45d4c15f237209bbf123a0e05b5d630c8717c42f59f31ea9eae2ad89394"}, - {file = "lxml-5.3.1-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:a83d3adea1e0ee36dac34627f78ddd7f093bb9cfc0a8e97f1572a949b695cb98"}, - {file = "lxml-5.3.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:3edbb9c9130bac05d8c3fe150c51c337a471cc7fdb6d2a0a7d3a88e88a829314"}, - {file = "lxml-5.3.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2f23cf50eccb3255b6e913188291af0150d89dab44137a69e14e4dcb7be981f1"}, - {file = "lxml-5.3.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df7e5edac4778127f2bf452e0721a58a1cfa4d1d9eac63bdd650535eb8543615"}, - {file = "lxml-5.3.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:094b28ed8a8a072b9e9e2113a81fda668d2053f2ca9f2d202c2c8c7c2d6516b1"}, - {file = "lxml-5.3.1-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:514fe78fc4b87e7a7601c92492210b20a1b0c6ab20e71e81307d9c2e377c64de"}, - {file = "lxml-5.3.1-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:8fffc08de02071c37865a155e5ea5fce0282e1546fd5bde7f6149fcaa32558ac"}, - {file = "lxml-5.3.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:4b0d5cdba1b655d5b18042ac9c9ff50bda33568eb80feaaca4fc237b9c4fbfde"}, - {file = "lxml-5.3.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3031e4c16b59424e8d78522c69b062d301d951dc55ad8685736c3335a97fc270"}, - {file = "lxml-5.3.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb659702a45136c743bc130760c6f137870d4df3a9e14386478b8a0511abcfca"}, - {file = "lxml-5.3.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a11b16a33656ffc43c92a5343a28dc71eefe460bcc2a4923a96f292692709f6"}, - {file = "lxml-5.3.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c5ae125276f254b01daa73e2c103363d3e99e3e10505686ac7d9d2442dd4627a"}, - {file = "lxml-5.3.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c76722b5ed4a31ba103e0dc77ab869222ec36efe1a614e42e9bcea88a36186fe"}, - {file = "lxml-5.3.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:33e06717c00c788ab4e79bc4726ecc50c54b9bfb55355eae21473c145d83c2d2"}, - {file = "lxml-5.3.1.tar.gz", hash = "sha256:106b7b5d2977b339f1e97efe2778e2ab20e99994cbb0ec5e55771ed0795920c8"}, + {file = "lxml-5.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e7bc6df34d42322c5289e37e9971d6ed114e3776b45fa879f734bded9d1fea9c"}, + {file = "lxml-5.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6854f8bd8a1536f8a1d9a3655e6354faa6406621cf857dc27b681b69860645c7"}, + {file = "lxml-5.4.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:696ea9e87442467819ac22394ca36cb3d01848dad1be6fac3fb612d3bd5a12cf"}, + {file = "lxml-5.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ef80aeac414f33c24b3815ecd560cee272786c3adfa5f31316d8b349bfade28"}, + {file = "lxml-5.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b9c2754cef6963f3408ab381ea55f47dabc6f78f4b8ebb0f0b25cf1ac1f7609"}, + {file = "lxml-5.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7a62cc23d754bb449d63ff35334acc9f5c02e6dae830d78dab4dd12b78a524f4"}, + {file = "lxml-5.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f82125bc7203c5ae8633a7d5d20bcfdff0ba33e436e4ab0abc026a53a8960b7"}, + {file = "lxml-5.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:b67319b4aef1a6c56576ff544b67a2a6fbd7eaee485b241cabf53115e8908b8f"}, + {file = "lxml-5.4.0-cp310-cp310-manylinux_2_28_ppc64le.whl", hash = "sha256:a8ef956fce64c8551221f395ba21d0724fed6b9b6242ca4f2f7beb4ce2f41997"}, + {file = "lxml-5.4.0-cp310-cp310-manylinux_2_28_s390x.whl", hash = "sha256:0a01ce7d8479dce84fc03324e3b0c9c90b1ece9a9bb6a1b6c9025e7e4520e78c"}, + {file = "lxml-5.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:91505d3ddebf268bb1588eb0f63821f738d20e1e7f05d3c647a5ca900288760b"}, + {file = "lxml-5.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a3bcdde35d82ff385f4ede021df801b5c4a5bcdfb61ea87caabcebfc4945dc1b"}, + {file = "lxml-5.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:aea7c06667b987787c7d1f5e1dfcd70419b711cdb47d6b4bb4ad4b76777a0563"}, + {file = "lxml-5.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:a7fb111eef4d05909b82152721a59c1b14d0f365e2be4c742a473c5d7372f4f5"}, + {file = "lxml-5.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:43d549b876ce64aa18b2328faff70f5877f8c6dede415f80a2f799d31644d776"}, + {file = "lxml-5.4.0-cp310-cp310-win32.whl", hash = "sha256:75133890e40d229d6c5837b0312abbe5bac1c342452cf0e12523477cd3aa21e7"}, + {file = "lxml-5.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:de5b4e1088523e2b6f730d0509a9a813355b7f5659d70eb4f319c76beea2e250"}, + {file = "lxml-5.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:98a3912194c079ef37e716ed228ae0dcb960992100461b704aea4e93af6b0bb9"}, + {file = "lxml-5.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0ea0252b51d296a75f6118ed0d8696888e7403408ad42345d7dfd0d1e93309a7"}, + {file = "lxml-5.4.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b92b69441d1bd39f4940f9eadfa417a25862242ca2c396b406f9272ef09cdcaa"}, + {file = "lxml-5.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20e16c08254b9b6466526bc1828d9370ee6c0d60a4b64836bc3ac2917d1e16df"}, + {file = "lxml-5.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7605c1c32c3d6e8c990dd28a0970a3cbbf1429d5b92279e37fda05fb0c92190e"}, + {file = "lxml-5.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ecf4c4b83f1ab3d5a7ace10bafcb6f11df6156857a3c418244cef41ca9fa3e44"}, + {file = "lxml-5.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0cef4feae82709eed352cd7e97ae062ef6ae9c7b5dbe3663f104cd2c0e8d94ba"}, + {file = "lxml-5.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:df53330a3bff250f10472ce96a9af28628ff1f4efc51ccba351a8820bca2a8ba"}, + {file = "lxml-5.4.0-cp311-cp311-manylinux_2_28_ppc64le.whl", hash = "sha256:aefe1a7cb852fa61150fcb21a8c8fcea7b58c4cb11fbe59c97a0a4b31cae3c8c"}, + {file = "lxml-5.4.0-cp311-cp311-manylinux_2_28_s390x.whl", hash = "sha256:ef5a7178fcc73b7d8c07229e89f8eb45b2908a9238eb90dcfc46571ccf0383b8"}, + {file = "lxml-5.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d2ed1b3cb9ff1c10e6e8b00941bb2e5bb568b307bfc6b17dffbbe8be5eecba86"}, + {file = "lxml-5.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:72ac9762a9f8ce74c9eed4a4e74306f2f18613a6b71fa065495a67ac227b3056"}, + {file = "lxml-5.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f5cb182f6396706dc6cc1896dd02b1c889d644c081b0cdec38747573db88a7d7"}, + {file = "lxml-5.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:3a3178b4873df8ef9457a4875703488eb1622632a9cee6d76464b60e90adbfcd"}, + {file = "lxml-5.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e094ec83694b59d263802ed03a8384594fcce477ce484b0cbcd0008a211ca751"}, + {file = "lxml-5.4.0-cp311-cp311-win32.whl", hash = "sha256:4329422de653cdb2b72afa39b0aa04252fca9071550044904b2e7036d9d97fe4"}, + {file = "lxml-5.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:fd3be6481ef54b8cfd0e1e953323b7aa9d9789b94842d0e5b142ef4bb7999539"}, + {file = "lxml-5.4.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b5aff6f3e818e6bdbbb38e5967520f174b18f539c2b9de867b1e7fde6f8d95a4"}, + {file = "lxml-5.4.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:942a5d73f739ad7c452bf739a62a0f83e2578afd6b8e5406308731f4ce78b16d"}, + {file = "lxml-5.4.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:460508a4b07364d6abf53acaa0a90b6d370fafde5693ef37602566613a9b0779"}, + {file = "lxml-5.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:529024ab3a505fed78fe3cc5ddc079464e709f6c892733e3f5842007cec8ac6e"}, + {file = "lxml-5.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ca56ebc2c474e8f3d5761debfd9283b8b18c76c4fc0967b74aeafba1f5647f9"}, + {file = "lxml-5.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a81e1196f0a5b4167a8dafe3a66aa67c4addac1b22dc47947abd5d5c7a3f24b5"}, + {file = "lxml-5.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00b8686694423ddae324cf614e1b9659c2edb754de617703c3d29ff568448df5"}, + {file = "lxml-5.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:c5681160758d3f6ac5b4fea370495c48aac0989d6a0f01bb9a72ad8ef5ab75c4"}, + {file = "lxml-5.4.0-cp312-cp312-manylinux_2_28_ppc64le.whl", hash = "sha256:2dc191e60425ad70e75a68c9fd90ab284df64d9cd410ba8d2b641c0c45bc006e"}, + {file = "lxml-5.4.0-cp312-cp312-manylinux_2_28_s390x.whl", hash = "sha256:67f779374c6b9753ae0a0195a892a1c234ce8416e4448fe1e9f34746482070a7"}, + {file = "lxml-5.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:79d5bfa9c1b455336f52343130b2067164040604e41f6dc4d8313867ed540079"}, + {file = "lxml-5.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3d3c30ba1c9b48c68489dc1829a6eede9873f52edca1dda900066542528d6b20"}, + {file = "lxml-5.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1af80c6316ae68aded77e91cd9d80648f7dd40406cef73df841aa3c36f6907c8"}, + {file = "lxml-5.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4d885698f5019abe0de3d352caf9466d5de2baded00a06ef3f1216c1a58ae78f"}, + {file = "lxml-5.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:aea53d51859b6c64e7c51d522c03cc2c48b9b5d6172126854cc7f01aa11f52bc"}, + {file = "lxml-5.4.0-cp312-cp312-win32.whl", hash = "sha256:d90b729fd2732df28130c064aac9bb8aff14ba20baa4aee7bd0795ff1187545f"}, + {file = "lxml-5.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1dc4ca99e89c335a7ed47d38964abcb36c5910790f9bd106f2a8fa2ee0b909d2"}, + {file = "lxml-5.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:773e27b62920199c6197130632c18fb7ead3257fce1ffb7d286912e56ddb79e0"}, + {file = "lxml-5.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ce9c671845de9699904b1e9df95acfe8dfc183f2310f163cdaa91a3535af95de"}, + {file = "lxml-5.4.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9454b8d8200ec99a224df8854786262b1bd6461f4280064c807303c642c05e76"}, + {file = "lxml-5.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cccd007d5c95279e529c146d095f1d39ac05139de26c098166c4beb9374b0f4d"}, + {file = "lxml-5.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0fce1294a0497edb034cb416ad3e77ecc89b313cff7adbee5334e4dc0d11f422"}, + {file = "lxml-5.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:24974f774f3a78ac12b95e3a20ef0931795ff04dbb16db81a90c37f589819551"}, + {file = "lxml-5.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:497cab4d8254c2a90bf988f162ace2ddbfdd806fce3bda3f581b9d24c852e03c"}, + {file = "lxml-5.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:e794f698ae4c5084414efea0f5cc9f4ac562ec02d66e1484ff822ef97c2cadff"}, + {file = "lxml-5.4.0-cp313-cp313-manylinux_2_28_ppc64le.whl", hash = "sha256:2c62891b1ea3094bb12097822b3d44b93fc6c325f2043c4d2736a8ff09e65f60"}, + {file = "lxml-5.4.0-cp313-cp313-manylinux_2_28_s390x.whl", hash = "sha256:142accb3e4d1edae4b392bd165a9abdee8a3c432a2cca193df995bc3886249c8"}, + {file = "lxml-5.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:1a42b3a19346e5601d1b8296ff6ef3d76038058f311902edd574461e9c036982"}, + {file = "lxml-5.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4291d3c409a17febf817259cb37bc62cb7eb398bcc95c1356947e2871911ae61"}, + {file = "lxml-5.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4f5322cf38fe0e21c2d73901abf68e6329dc02a4994e483adbcf92b568a09a54"}, + {file = "lxml-5.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:0be91891bdb06ebe65122aa6bf3fc94489960cf7e03033c6f83a90863b23c58b"}, + {file = "lxml-5.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:15a665ad90054a3d4f397bc40f73948d48e36e4c09f9bcffc7d90c87410e478a"}, + {file = "lxml-5.4.0-cp313-cp313-win32.whl", hash = "sha256:d5663bc1b471c79f5c833cffbc9b87d7bf13f87e055a5c86c363ccd2348d7e82"}, + {file = "lxml-5.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:bcb7a1096b4b6b24ce1ac24d4942ad98f983cd3810f9711bcd0293f43a9d8b9f"}, + {file = "lxml-5.4.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:7be701c24e7f843e6788353c055d806e8bd8466b52907bafe5d13ec6a6dbaecd"}, + {file = "lxml-5.4.0-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb54f7c6bafaa808f27166569b1511fc42701a7713858dddc08afdde9746849e"}, + {file = "lxml-5.4.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97dac543661e84a284502e0cf8a67b5c711b0ad5fb661d1bd505c02f8cf716d7"}, + {file = "lxml-5.4.0-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:c70e93fba207106cb16bf852e421c37bbded92acd5964390aad07cb50d60f5cf"}, + {file = "lxml-5.4.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:9c886b481aefdf818ad44846145f6eaf373a20d200b5ce1a5c8e1bc2d8745410"}, + {file = "lxml-5.4.0-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:fa0e294046de09acd6146be0ed6727d1f42ded4ce3ea1e9a19c11b6774eea27c"}, + {file = "lxml-5.4.0-cp36-cp36m-win32.whl", hash = "sha256:61c7bbf432f09ee44b1ccaa24896d21075e533cd01477966a5ff5a71d88b2f56"}, + {file = "lxml-5.4.0-cp36-cp36m-win_amd64.whl", hash = "sha256:7ce1a171ec325192c6a636b64c94418e71a1964f56d002cc28122fceff0b6121"}, + {file = "lxml-5.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:795f61bcaf8770e1b37eec24edf9771b307df3af74d1d6f27d812e15a9ff3872"}, + {file = "lxml-5.4.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:29f451a4b614a7b5b6c2e043d7b64a15bd8304d7e767055e8ab68387a8cacf4e"}, + {file = "lxml-5.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4aa412a82e460571fad592d0f93ce9935a20090029ba08eca05c614f99b0cc92"}, + {file = "lxml-5.4.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:c5d32f5284012deaccd37da1e2cd42f081feaa76981f0eaa474351b68df813c5"}, + {file = "lxml-5.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:31e63621e073e04697c1b2d23fcb89991790eef370ec37ce4d5d469f40924ed6"}, + {file = "lxml-5.4.0-cp37-cp37m-win32.whl", hash = "sha256:be2ba4c3c5b7900246a8f866580700ef0d538f2ca32535e991027bdaba944063"}, + {file = "lxml-5.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:09846782b1ef650b321484ad429217f5154da4d6e786636c38e434fa32e94e49"}, + {file = "lxml-5.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:eaf24066ad0b30917186420d51e2e3edf4b0e2ea68d8cd885b14dc8afdcf6556"}, + {file = "lxml-5.4.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b31a3a77501d86d8ade128abb01082724c0dfd9524f542f2f07d693c9f1175f"}, + {file = "lxml-5.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e108352e203c7afd0eb91d782582f00a0b16a948d204d4dec8565024fafeea5"}, + {file = "lxml-5.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a11a96c3b3f7551c8a8109aa65e8594e551d5a84c76bf950da33d0fb6dfafab7"}, + {file = "lxml-5.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:ca755eebf0d9e62d6cb013f1261e510317a41bf4650f22963474a663fdfe02aa"}, + {file = "lxml-5.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:4cd915c0fb1bed47b5e6d6edd424ac25856252f09120e3e8ba5154b6b921860e"}, + {file = "lxml-5.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:226046e386556a45ebc787871d6d2467b32c37ce76c2680f5c608e25823ffc84"}, + {file = "lxml-5.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:b108134b9667bcd71236c5a02aad5ddd073e372fb5d48ea74853e009fe38acb6"}, + {file = "lxml-5.4.0-cp38-cp38-win32.whl", hash = "sha256:1320091caa89805df7dcb9e908add28166113dcd062590668514dbd510798c88"}, + {file = "lxml-5.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:073eb6dcdf1f587d9b88c8c93528b57eccda40209cf9be549d469b942b41d70b"}, + {file = "lxml-5.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bda3ea44c39eb74e2488297bb39d47186ed01342f0022c8ff407c250ac3f498e"}, + {file = "lxml-5.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9ceaf423b50ecfc23ca00b7f50b64baba85fb3fb91c53e2c9d00bc86150c7e40"}, + {file = "lxml-5.4.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:664cdc733bc87449fe781dbb1f309090966c11cc0c0cd7b84af956a02a8a4729"}, + {file = "lxml-5.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67ed8a40665b84d161bae3181aa2763beea3747f748bca5874b4af4d75998f87"}, + {file = "lxml-5.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b4a3bd174cc9cdaa1afbc4620c049038b441d6ba07629d89a83b408e54c35cd"}, + {file = "lxml-5.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:b0989737a3ba6cf2a16efb857fb0dfa20bc5c542737fddb6d893fde48be45433"}, + {file = "lxml-5.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:dc0af80267edc68adf85f2a5d9be1cdf062f973db6790c1d065e45025fa26140"}, + {file = "lxml-5.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:639978bccb04c42677db43c79bdaa23785dc7f9b83bfd87570da8207872f1ce5"}, + {file = "lxml-5.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5a99d86351f9c15e4a901fc56404b485b1462039db59288b203f8c629260a142"}, + {file = "lxml-5.4.0-cp39-cp39-win32.whl", hash = "sha256:3e6d5557989cdc3ebb5302bbdc42b439733a841891762ded9514e74f60319ad6"}, + {file = "lxml-5.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:a8c9b7f16b63e65bbba889acb436a1034a82d34fa09752d754f88d708eca80e1"}, + {file = "lxml-5.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1b717b00a71b901b4667226bba282dd462c42ccf618ade12f9ba3674e1fabc55"}, + {file = "lxml-5.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27a9ded0f0b52098ff89dd4c418325b987feed2ea5cc86e8860b0f844285d740"}, + {file = "lxml-5.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b7ce10634113651d6f383aa712a194179dcd496bd8c41e191cec2099fa09de5"}, + {file = "lxml-5.4.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:53370c26500d22b45182f98847243efb518d268374a9570409d2e2276232fd37"}, + {file = "lxml-5.4.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c6364038c519dffdbe07e3cf42e6a7f8b90c275d4d1617a69bb59734c1a2d571"}, + {file = "lxml-5.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b12cb6527599808ada9eb2cd6e0e7d3d8f13fe7bbb01c6311255a15ded4c7ab4"}, + {file = "lxml-5.4.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5f11a1526ebd0dee85e7b1e39e39a0cc0d9d03fb527f56d8457f6df48a10dc0c"}, + {file = "lxml-5.4.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48b4afaf38bf79109bb060d9016fad014a9a48fb244e11b94f74ae366a64d252"}, + {file = "lxml-5.4.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de6f6bb8a7840c7bf216fb83eec4e2f79f7325eca8858167b68708b929ab2172"}, + {file = "lxml-5.4.0-pp37-pypy37_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5cca36a194a4eb4e2ed6be36923d3cffd03dcdf477515dea687185506583d4c9"}, + {file = "lxml-5.4.0-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b7c86884ad23d61b025989d99bfdd92a7351de956e01c61307cb87035960bcb1"}, + {file = "lxml-5.4.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:53d9469ab5460402c19553b56c3648746774ecd0681b1b27ea74d5d8a3ef5590"}, + {file = "lxml-5.4.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:56dbdbab0551532bb26c19c914848d7251d73edb507c3079d6805fa8bba5b706"}, + {file = "lxml-5.4.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14479c2ad1cb08b62bb941ba8e0e05938524ee3c3114644df905d2331c76cd57"}, + {file = "lxml-5.4.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32697d2ea994e0db19c1df9e40275ffe84973e4232b5c274f47e7c1ec9763cdd"}, + {file = "lxml-5.4.0-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:24f6df5f24fc3385f622c0c9d63fe34604893bc1a5bdbb2dbf5870f85f9a404a"}, + {file = "lxml-5.4.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:151d6c40bc9db11e960619d2bf2ec5829f0aaffb10b41dcf6ad2ce0f3c0b2325"}, + {file = "lxml-5.4.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:4025bf2884ac4370a3243c5aa8d66d3cb9e15d3ddd0af2d796eccc5f0244390e"}, + {file = "lxml-5.4.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:9459e6892f59ecea2e2584ee1058f5d8f629446eab52ba2305ae13a32a059530"}, + {file = "lxml-5.4.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47fb24cc0f052f0576ea382872b3fc7e1f7e3028e53299ea751839418ade92a6"}, + {file = "lxml-5.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50441c9de951a153c698b9b99992e806b71c1f36d14b154592580ff4a9d0d877"}, + {file = "lxml-5.4.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:ab339536aa798b1e17750733663d272038bf28069761d5be57cb4a9b0137b4f8"}, + {file = "lxml-5.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:9776af1aad5a4b4a1317242ee2bea51da54b2a7b7b48674be736d463c999f37d"}, + {file = "lxml-5.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:63e7968ff83da2eb6fdda967483a7a023aa497d85ad8f05c3ad9b1f2e8c84987"}, + {file = "lxml-5.4.0.tar.gz", hash = "sha256:d12832e1dbea4be280b22fd0ea7c9b87f0d8fc51ba06e92dc62d52f804f78ebd"}, ] [package.extras] @@ -2520,13 +2507,13 @@ cli = ["click (>=8.1.0,<9)", "coverage (>=6.4.4,<8.0.0)", "open-aea-cli-ipfs (== [[package]] name = "orderly-set" -version = "5.3.0" +version = "5.4.0" description = "Orderly set" optional = false python-versions = ">=3.8" files = [ - {file = "orderly_set-5.3.0-py3-none-any.whl", hash = "sha256:c2c0bfe604f5d3d9b24e8262a06feb612594f37aa3845650548befd7772945d1"}, - {file = "orderly_set-5.3.0.tar.gz", hash = "sha256:80b3d8fdd3d39004d9aad389eaa0eab02c71f0a0511ba3a6d54a935a6c6a0acc"}, + {file = "orderly_set-5.4.0-py3-none-any.whl", hash = "sha256:f0192a7f9ae3385b587b71688353fae491d1ca45878496eb71ea118be1623639"}, + {file = "orderly_set-5.4.0.tar.gz", hash = "sha256:c8ff5ba824abe4eebcbbdd3f646ff3648ad0dd52239319d90056d8d30b6cccdd"}, ] [[package]] @@ -2588,19 +2575,19 @@ files = [ [[package]] name = "platformdirs" -version = "4.3.6" +version = "4.3.7" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, - {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, + {file = "platformdirs-4.3.7-py3-none-any.whl", hash = "sha256:a03875334331946f13c549dbd8f4bac7a13a50a895a0eb1e8c6a8ace80d40a94"}, + {file = "platformdirs-4.3.7.tar.gz", hash = "sha256:eb437d586b6a0986388f0d6f74aa0cde27b48d0e3d66843640bfb6bdcdb6e351"}, ] [package.extras] -docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] -type = ["mypy (>=1.11.2)"] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.1.3)", "sphinx-autodoc-typehints (>=3)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.4)", "pytest-cov (>=6)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.14.1)"] [[package]] name = "pluggy" @@ -2619,109 +2606,109 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "propcache" -version = "0.3.0" +version = "0.3.1" description = "Accelerated property cache" optional = false python-versions = ">=3.9" files = [ - {file = "propcache-0.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:efa44f64c37cc30c9f05932c740a8b40ce359f51882c70883cc95feac842da4d"}, - {file = "propcache-0.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2383a17385d9800b6eb5855c2f05ee550f803878f344f58b6e194de08b96352c"}, - {file = "propcache-0.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d3e7420211f5a65a54675fd860ea04173cde60a7cc20ccfbafcccd155225f8bc"}, - {file = "propcache-0.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3302c5287e504d23bb0e64d2a921d1eb4a03fb93a0a0aa3b53de059f5a5d737d"}, - {file = "propcache-0.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7e2e068a83552ddf7a39a99488bcba05ac13454fb205c847674da0352602082f"}, - {file = "propcache-0.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d913d36bdaf368637b4f88d554fb9cb9d53d6920b9c5563846555938d5450bf"}, - {file = "propcache-0.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ee1983728964d6070ab443399c476de93d5d741f71e8f6e7880a065f878e0b9"}, - {file = "propcache-0.3.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:36ca5e9a21822cc1746023e88f5c0af6fce3af3b85d4520efb1ce4221bed75cc"}, - {file = "propcache-0.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9ecde3671e62eeb99e977f5221abcf40c208f69b5eb986b061ccec317c82ebd0"}, - {file = "propcache-0.3.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d383bf5e045d7f9d239b38e6acadd7b7fdf6c0087259a84ae3475d18e9a2ae8b"}, - {file = "propcache-0.3.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:8cb625bcb5add899cb8ba7bf716ec1d3e8f7cdea9b0713fa99eadf73b6d4986f"}, - {file = "propcache-0.3.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:5fa159dcee5dba00c1def3231c249cf261185189205073bde13797e57dd7540a"}, - {file = "propcache-0.3.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:a7080b0159ce05f179cfac592cda1a82898ca9cd097dacf8ea20ae33474fbb25"}, - {file = "propcache-0.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ed7161bccab7696a473fe7ddb619c1d75963732b37da4618ba12e60899fefe4f"}, - {file = "propcache-0.3.0-cp310-cp310-win32.whl", hash = "sha256:bf0d9a171908f32d54f651648c7290397b8792f4303821c42a74e7805bfb813c"}, - {file = "propcache-0.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:42924dc0c9d73e49908e35bbdec87adedd651ea24c53c29cac103ede0ea1d340"}, - {file = "propcache-0.3.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9ddd49258610499aab83b4f5b61b32e11fce873586282a0e972e5ab3bcadee51"}, - {file = "propcache-0.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2578541776769b500bada3f8a4eeaf944530516b6e90c089aa368266ed70c49e"}, - {file = "propcache-0.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8074c5dd61c8a3e915fa8fc04754fa55cfa5978200d2daa1e2d4294c1f136aa"}, - {file = "propcache-0.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b58229a844931bca61b3a20efd2be2a2acb4ad1622fc026504309a6883686fbf"}, - {file = "propcache-0.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e45377d5d6fefe1677da2a2c07b024a6dac782088e37c0b1efea4cfe2b1be19b"}, - {file = "propcache-0.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ec5060592d83454e8063e487696ac3783cc48c9a329498bafae0d972bc7816c9"}, - {file = "propcache-0.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15010f29fbed80e711db272909a074dc79858c6d28e2915704cfc487a8ac89c6"}, - {file = "propcache-0.3.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a254537b9b696ede293bfdbc0a65200e8e4507bc9f37831e2a0318a9b333c85c"}, - {file = "propcache-0.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2b975528998de037dfbc10144b8aed9b8dd5a99ec547f14d1cb7c5665a43f075"}, - {file = "propcache-0.3.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:19d36bb351ad5554ff20f2ae75f88ce205b0748c38b146c75628577020351e3c"}, - {file = "propcache-0.3.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:6032231d4a5abd67c7f71168fd64a47b6b451fbcb91c8397c2f7610e67683810"}, - {file = "propcache-0.3.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6985a593417cdbc94c7f9c3403747335e450c1599da1647a5af76539672464d3"}, - {file = "propcache-0.3.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:6a1948df1bb1d56b5e7b0553c0fa04fd0e320997ae99689488201f19fa90d2e7"}, - {file = "propcache-0.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8319293e85feadbbfe2150a5659dbc2ebc4afdeaf7d98936fb9a2f2ba0d4c35c"}, - {file = "propcache-0.3.0-cp311-cp311-win32.whl", hash = "sha256:63f26258a163c34542c24808f03d734b338da66ba91f410a703e505c8485791d"}, - {file = "propcache-0.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:cacea77ef7a2195f04f9279297684955e3d1ae4241092ff0cfcef532bb7a1c32"}, - {file = "propcache-0.3.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e53d19c2bf7d0d1e6998a7e693c7e87300dd971808e6618964621ccd0e01fe4e"}, - {file = "propcache-0.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a61a68d630e812b67b5bf097ab84e2cd79b48c792857dc10ba8a223f5b06a2af"}, - {file = "propcache-0.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fb91d20fa2d3b13deea98a690534697742029f4fb83673a3501ae6e3746508b5"}, - {file = "propcache-0.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67054e47c01b7b349b94ed0840ccae075449503cf1fdd0a1fdd98ab5ddc2667b"}, - {file = "propcache-0.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:997e7b8f173a391987df40f3b52c423e5850be6f6df0dcfb5376365440b56667"}, - {file = "propcache-0.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d663fd71491dde7dfdfc899d13a067a94198e90695b4321084c6e450743b8c7"}, - {file = "propcache-0.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8884ba1a0fe7210b775106b25850f5e5a9dc3c840d1ae9924ee6ea2eb3acbfe7"}, - {file = "propcache-0.3.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa806bbc13eac1ab6291ed21ecd2dd426063ca5417dd507e6be58de20e58dfcf"}, - {file = "propcache-0.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6f4d7a7c0aff92e8354cceca6fe223973ddf08401047920df0fcb24be2bd5138"}, - {file = "propcache-0.3.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:9be90eebc9842a93ef8335291f57b3b7488ac24f70df96a6034a13cb58e6ff86"}, - {file = "propcache-0.3.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:bf15fc0b45914d9d1b706f7c9c4f66f2b7b053e9517e40123e137e8ca8958b3d"}, - {file = "propcache-0.3.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5a16167118677d94bb48bfcd91e420088854eb0737b76ec374b91498fb77a70e"}, - {file = "propcache-0.3.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:41de3da5458edd5678b0f6ff66691507f9885f5fe6a0fb99a5d10d10c0fd2d64"}, - {file = "propcache-0.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:728af36011bb5d344c4fe4af79cfe186729efb649d2f8b395d1572fb088a996c"}, - {file = "propcache-0.3.0-cp312-cp312-win32.whl", hash = "sha256:6b5b7fd6ee7b54e01759f2044f936dcf7dea6e7585f35490f7ca0420fe723c0d"}, - {file = "propcache-0.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:2d15bc27163cd4df433e75f546b9ac31c1ba7b0b128bfb1b90df19082466ff57"}, - {file = "propcache-0.3.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a2b9bf8c79b660d0ca1ad95e587818c30ccdb11f787657458d6f26a1ea18c568"}, - {file = "propcache-0.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b0c1a133d42c6fc1f5fbcf5c91331657a1ff822e87989bf4a6e2e39b818d0ee9"}, - {file = "propcache-0.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bb2f144c6d98bb5cbc94adeb0447cfd4c0f991341baa68eee3f3b0c9c0e83767"}, - {file = "propcache-0.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1323cd04d6e92150bcc79d0174ce347ed4b349d748b9358fd2e497b121e03c8"}, - {file = "propcache-0.3.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b812b3cb6caacd072276ac0492d249f210006c57726b6484a1e1805b3cfeea0"}, - {file = "propcache-0.3.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:742840d1d0438eb7ea4280f3347598f507a199a35a08294afdcc560c3739989d"}, - {file = "propcache-0.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c6e7e4f9167fddc438cd653d826f2222222564daed4116a02a184b464d3ef05"}, - {file = "propcache-0.3.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a94ffc66738da99232ddffcf7910e0f69e2bbe3a0802e54426dbf0714e1c2ffe"}, - {file = "propcache-0.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3c6ec957025bf32b15cbc6b67afe233c65b30005e4c55fe5768e4bb518d712f1"}, - {file = "propcache-0.3.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:549722908de62aa0b47a78b90531c022fa6e139f9166be634f667ff45632cc92"}, - {file = "propcache-0.3.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5d62c4f6706bff5d8a52fd51fec6069bef69e7202ed481486c0bc3874912c787"}, - {file = "propcache-0.3.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:24c04f8fbf60094c531667b8207acbae54146661657a1b1be6d3ca7773b7a545"}, - {file = "propcache-0.3.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:7c5f5290799a3f6539cc5e6f474c3e5c5fbeba74a5e1e5be75587746a940d51e"}, - {file = "propcache-0.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4fa0e7c9c3cf7c276d4f6ab9af8adddc127d04e0fcabede315904d2ff76db626"}, - {file = "propcache-0.3.0-cp313-cp313-win32.whl", hash = "sha256:ee0bd3a7b2e184e88d25c9baa6a9dc609ba25b76daae942edfb14499ac7ec374"}, - {file = "propcache-0.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:1c8f7d896a16da9455f882870a507567d4f58c53504dc2d4b1e1d386dfe4588a"}, - {file = "propcache-0.3.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:e560fd75aaf3e5693b91bcaddd8b314f4d57e99aef8a6c6dc692f935cc1e6bbf"}, - {file = "propcache-0.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:65a37714b8ad9aba5780325228598a5b16c47ba0f8aeb3dc0514701e4413d7c0"}, - {file = "propcache-0.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:07700939b2cbd67bfb3b76a12e1412405d71019df00ca5697ce75e5ef789d829"}, - {file = "propcache-0.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c0fdbdf6983526e269e5a8d53b7ae3622dd6998468821d660d0daf72779aefa"}, - {file = "propcache-0.3.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:794c3dd744fad478b6232289c866c25406ecdfc47e294618bdf1697e69bd64a6"}, - {file = "propcache-0.3.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4544699674faf66fb6b4473a1518ae4999c1b614f0b8297b1cef96bac25381db"}, - {file = "propcache-0.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fddb8870bdb83456a489ab67c6b3040a8d5a55069aa6f72f9d872235fbc52f54"}, - {file = "propcache-0.3.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f857034dc68d5ceb30fb60afb6ff2103087aea10a01b613985610e007053a121"}, - {file = "propcache-0.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:02df07041e0820cacc8f739510078f2aadcfd3fc57eaeeb16d5ded85c872c89e"}, - {file = "propcache-0.3.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:f47d52fd9b2ac418c4890aad2f6d21a6b96183c98021f0a48497a904199f006e"}, - {file = "propcache-0.3.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:9ff4e9ecb6e4b363430edf2c6e50173a63e0820e549918adef70515f87ced19a"}, - {file = "propcache-0.3.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:ecc2920630283e0783c22e2ac94427f8cca29a04cfdf331467d4f661f4072dac"}, - {file = "propcache-0.3.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:c441c841e82c5ba7a85ad25986014be8d7849c3cfbdb6004541873505929a74e"}, - {file = "propcache-0.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6c929916cbdb540d3407c66f19f73387f43e7c12fa318a66f64ac99da601bcdf"}, - {file = "propcache-0.3.0-cp313-cp313t-win32.whl", hash = "sha256:0c3e893c4464ebd751b44ae76c12c5f5c1e4f6cbd6fbf67e3783cd93ad221863"}, - {file = "propcache-0.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:75e872573220d1ee2305b35c9813626e620768248425f58798413e9c39741f46"}, - {file = "propcache-0.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:03c091bb752349402f23ee43bb2bff6bd80ccab7c9df6b88ad4322258d6960fc"}, - {file = "propcache-0.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:46ed02532cb66612d42ae5c3929b5e98ae330ea0f3900bc66ec5f4862069519b"}, - {file = "propcache-0.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:11ae6a8a01b8a4dc79093b5d3ca2c8a4436f5ee251a9840d7790dccbd96cb649"}, - {file = "propcache-0.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df03cd88f95b1b99052b52b1bb92173229d7a674df0ab06d2b25765ee8404bce"}, - {file = "propcache-0.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:03acd9ff19021bd0567582ac88f821b66883e158274183b9e5586f678984f8fe"}, - {file = "propcache-0.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd54895e4ae7d32f1e3dd91261df46ee7483a735017dc6f987904f194aa5fd14"}, - {file = "propcache-0.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26a67e5c04e3119594d8cfae517f4b9330c395df07ea65eab16f3d559b7068fe"}, - {file = "propcache-0.3.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee25f1ac091def37c4b59d192bbe3a206298feeb89132a470325bf76ad122a1e"}, - {file = "propcache-0.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:58e6d2a5a7cb3e5f166fd58e71e9a4ff504be9dc61b88167e75f835da5764d07"}, - {file = "propcache-0.3.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:be90c94570840939fecedf99fa72839aed70b0ced449b415c85e01ae67422c90"}, - {file = "propcache-0.3.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:49ea05212a529c2caffe411e25a59308b07d6e10bf2505d77da72891f9a05641"}, - {file = "propcache-0.3.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:119e244ab40f70a98c91906d4c1f4c5f2e68bd0b14e7ab0a06922038fae8a20f"}, - {file = "propcache-0.3.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:507c5357a8d8b4593b97fb669c50598f4e6cccbbf77e22fa9598aba78292b4d7"}, - {file = "propcache-0.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:8526b0941ec5a40220fc4dfde76aed58808e2b309c03e9fa8e2260083ef7157f"}, - {file = "propcache-0.3.0-cp39-cp39-win32.whl", hash = "sha256:7cedd25e5f678f7738da38037435b340694ab34d424938041aa630d8bac42663"}, - {file = "propcache-0.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:bf4298f366ca7e1ad1d21bbb58300a6985015909964077afd37559084590c929"}, - {file = "propcache-0.3.0-py3-none-any.whl", hash = "sha256:67dda3c7325691c2081510e92c561f465ba61b975f481735aefdfc845d2cd043"}, - {file = "propcache-0.3.0.tar.gz", hash = "sha256:a8fd93de4e1d278046345f49e2238cdb298589325849b2645d4a94c53faeffc5"}, + {file = "propcache-0.3.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f27785888d2fdd918bc36de8b8739f2d6c791399552333721b58193f68ea3e98"}, + {file = "propcache-0.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4e89cde74154c7b5957f87a355bb9c8ec929c167b59c83d90654ea36aeb6180"}, + {file = "propcache-0.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:730178f476ef03d3d4d255f0c9fa186cb1d13fd33ffe89d39f2cda4da90ceb71"}, + {file = "propcache-0.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:967a8eec513dbe08330f10137eacb427b2ca52118769e82ebcfcab0fba92a649"}, + {file = "propcache-0.3.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b9145c35cc87313b5fd480144f8078716007656093d23059e8993d3a8fa730f"}, + {file = "propcache-0.3.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9e64e948ab41411958670f1093c0a57acfdc3bee5cf5b935671bbd5313bcf229"}, + {file = "propcache-0.3.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:319fa8765bfd6a265e5fa661547556da381e53274bc05094fc9ea50da51bfd46"}, + {file = "propcache-0.3.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c66d8ccbc902ad548312b96ed8d5d266d0d2c6d006fd0f66323e9d8f2dd49be7"}, + {file = "propcache-0.3.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2d219b0dbabe75e15e581fc1ae796109b07c8ba7d25b9ae8d650da582bed01b0"}, + {file = "propcache-0.3.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:cd6a55f65241c551eb53f8cf4d2f4af33512c39da5d9777694e9d9c60872f519"}, + {file = "propcache-0.3.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9979643ffc69b799d50d3a7b72b5164a2e97e117009d7af6dfdd2ab906cb72cd"}, + {file = "propcache-0.3.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4cf9e93a81979f1424f1a3d155213dc928f1069d697e4353edb8a5eba67c6259"}, + {file = "propcache-0.3.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2fce1df66915909ff6c824bbb5eb403d2d15f98f1518e583074671a30fe0c21e"}, + {file = "propcache-0.3.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4d0dfdd9a2ebc77b869a0b04423591ea8823f791293b527dc1bb896c1d6f1136"}, + {file = "propcache-0.3.1-cp310-cp310-win32.whl", hash = "sha256:1f6cc0ad7b4560e5637eb2c994e97b4fa41ba8226069c9277eb5ea7101845b42"}, + {file = "propcache-0.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:47ef24aa6511e388e9894ec16f0fbf3313a53ee68402bc428744a367ec55b833"}, + {file = "propcache-0.3.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7f30241577d2fef2602113b70ef7231bf4c69a97e04693bde08ddab913ba0ce5"}, + {file = "propcache-0.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:43593c6772aa12abc3af7784bff4a41ffa921608dd38b77cf1dfd7f5c4e71371"}, + {file = "propcache-0.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a75801768bbe65499495660b777e018cbe90c7980f07f8aa57d6be79ea6f71da"}, + {file = "propcache-0.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6f1324db48f001c2ca26a25fa25af60711e09b9aaf4b28488602776f4f9a744"}, + {file = "propcache-0.3.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cdb0f3e1eb6dfc9965d19734d8f9c481b294b5274337a8cb5cb01b462dcb7e0"}, + {file = "propcache-0.3.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1eb34d90aac9bfbced9a58b266f8946cb5935869ff01b164573a7634d39fbcb5"}, + {file = "propcache-0.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f35c7070eeec2cdaac6fd3fe245226ed2a6292d3ee8c938e5bb645b434c5f256"}, + {file = "propcache-0.3.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b23c11c2c9e6d4e7300c92e022046ad09b91fd00e36e83c44483df4afa990073"}, + {file = "propcache-0.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3e19ea4ea0bf46179f8a3652ac1426e6dcbaf577ce4b4f65be581e237340420d"}, + {file = "propcache-0.3.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:bd39c92e4c8f6cbf5f08257d6360123af72af9f4da75a690bef50da77362d25f"}, + {file = "propcache-0.3.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:b0313e8b923b3814d1c4a524c93dfecea5f39fa95601f6a9b1ac96cd66f89ea0"}, + {file = "propcache-0.3.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e861ad82892408487be144906a368ddbe2dc6297074ade2d892341b35c59844a"}, + {file = "propcache-0.3.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:61014615c1274df8da5991a1e5da85a3ccb00c2d4701ac6f3383afd3ca47ab0a"}, + {file = "propcache-0.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:71ebe3fe42656a2328ab08933d420df5f3ab121772eef78f2dc63624157f0ed9"}, + {file = "propcache-0.3.1-cp311-cp311-win32.whl", hash = "sha256:58aa11f4ca8b60113d4b8e32d37e7e78bd8af4d1a5b5cb4979ed856a45e62005"}, + {file = "propcache-0.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:9532ea0b26a401264b1365146c440a6d78269ed41f83f23818d4b79497aeabe7"}, + {file = "propcache-0.3.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f78eb8422acc93d7b69964012ad7048764bb45a54ba7a39bb9e146c72ea29723"}, + {file = "propcache-0.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:89498dd49c2f9a026ee057965cdf8192e5ae070ce7d7a7bd4b66a8e257d0c976"}, + {file = "propcache-0.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:09400e98545c998d57d10035ff623266927cb784d13dd2b31fd33b8a5316b85b"}, + {file = "propcache-0.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa8efd8c5adc5a2c9d3b952815ff8f7710cefdcaf5f2c36d26aff51aeca2f12f"}, + {file = "propcache-0.3.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2fe5c910f6007e716a06d269608d307b4f36e7babee5f36533722660e8c4a70"}, + {file = "propcache-0.3.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a0ab8cf8cdd2194f8ff979a43ab43049b1df0b37aa64ab7eca04ac14429baeb7"}, + {file = "propcache-0.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:563f9d8c03ad645597b8d010ef4e9eab359faeb11a0a2ac9f7b4bc8c28ebef25"}, + {file = "propcache-0.3.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb6e0faf8cb6b4beea5d6ed7b5a578254c6d7df54c36ccd3d8b3eb00d6770277"}, + {file = "propcache-0.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1c5c7ab7f2bb3f573d1cb921993006ba2d39e8621019dffb1c5bc94cdbae81e8"}, + {file = "propcache-0.3.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:050b571b2e96ec942898f8eb46ea4bfbb19bd5502424747e83badc2d4a99a44e"}, + {file = "propcache-0.3.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e1c4d24b804b3a87e9350f79e2371a705a188d292fd310e663483af6ee6718ee"}, + {file = "propcache-0.3.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e4fe2a6d5ce975c117a6bb1e8ccda772d1e7029c1cca1acd209f91d30fa72815"}, + {file = "propcache-0.3.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:feccd282de1f6322f56f6845bf1207a537227812f0a9bf5571df52bb418d79d5"}, + {file = "propcache-0.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ec314cde7314d2dd0510c6787326bbffcbdc317ecee6b7401ce218b3099075a7"}, + {file = "propcache-0.3.1-cp312-cp312-win32.whl", hash = "sha256:7d2d5a0028d920738372630870e7d9644ce437142197f8c827194fca404bf03b"}, + {file = "propcache-0.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:88c423efef9d7a59dae0614eaed718449c09a5ac79a5f224a8b9664d603f04a3"}, + {file = "propcache-0.3.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f1528ec4374617a7a753f90f20e2f551121bb558fcb35926f99e3c42367164b8"}, + {file = "propcache-0.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dc1915ec523b3b494933b5424980831b636fe483d7d543f7afb7b3bf00f0c10f"}, + {file = "propcache-0.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a110205022d077da24e60b3df8bcee73971be9575dec5573dd17ae5d81751111"}, + {file = "propcache-0.3.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d249609e547c04d190e820d0d4c8ca03ed4582bcf8e4e160a6969ddfb57b62e5"}, + {file = "propcache-0.3.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ced33d827625d0a589e831126ccb4f5c29dfdf6766cac441d23995a65825dcb"}, + {file = "propcache-0.3.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4114c4ada8f3181af20808bedb250da6bae56660e4b8dfd9cd95d4549c0962f7"}, + {file = "propcache-0.3.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:975af16f406ce48f1333ec5e912fe11064605d5c5b3f6746969077cc3adeb120"}, + {file = "propcache-0.3.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a34aa3a1abc50740be6ac0ab9d594e274f59960d3ad253cd318af76b996dd654"}, + {file = "propcache-0.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9cec3239c85ed15bfaded997773fdad9fb5662b0a7cbc854a43f291eb183179e"}, + {file = "propcache-0.3.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:05543250deac8e61084234d5fc54f8ebd254e8f2b39a16b1dce48904f45b744b"}, + {file = "propcache-0.3.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5cb5918253912e088edbf023788de539219718d3b10aef334476b62d2b53de53"}, + {file = "propcache-0.3.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f3bbecd2f34d0e6d3c543fdb3b15d6b60dd69970c2b4c822379e5ec8f6f621d5"}, + {file = "propcache-0.3.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aca63103895c7d960a5b9b044a83f544b233c95e0dcff114389d64d762017af7"}, + {file = "propcache-0.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5a0a9898fdb99bf11786265468571e628ba60af80dc3f6eb89a3545540c6b0ef"}, + {file = "propcache-0.3.1-cp313-cp313-win32.whl", hash = "sha256:3a02a28095b5e63128bcae98eb59025924f121f048a62393db682f049bf4ac24"}, + {file = "propcache-0.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:813fbb8b6aea2fc9659815e585e548fe706d6f663fa73dff59a1677d4595a037"}, + {file = "propcache-0.3.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:a444192f20f5ce8a5e52761a031b90f5ea6288b1eef42ad4c7e64fef33540b8f"}, + {file = "propcache-0.3.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0fbe94666e62ebe36cd652f5fc012abfbc2342de99b523f8267a678e4dfdee3c"}, + {file = "propcache-0.3.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f011f104db880f4e2166bcdcf7f58250f7a465bc6b068dc84c824a3d4a5c94dc"}, + {file = "propcache-0.3.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e584b6d388aeb0001d6d5c2bd86b26304adde6d9bb9bfa9c4889805021b96de"}, + {file = "propcache-0.3.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a17583515a04358b034e241f952f1715243482fc2c2945fd99a1b03a0bd77d6"}, + {file = "propcache-0.3.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5aed8d8308215089c0734a2af4f2e95eeb360660184ad3912686c181e500b2e7"}, + {file = "propcache-0.3.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d8e309ff9a0503ef70dc9a0ebd3e69cf7b3894c9ae2ae81fc10943c37762458"}, + {file = "propcache-0.3.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b655032b202028a582d27aeedc2e813299f82cb232f969f87a4fde491a233f11"}, + {file = "propcache-0.3.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9f64d91b751df77931336b5ff7bafbe8845c5770b06630e27acd5dbb71e1931c"}, + {file = "propcache-0.3.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:19a06db789a4bd896ee91ebc50d059e23b3639c25d58eb35be3ca1cbe967c3bf"}, + {file = "propcache-0.3.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:bef100c88d8692864651b5f98e871fb090bd65c8a41a1cb0ff2322db39c96c27"}, + {file = "propcache-0.3.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:87380fb1f3089d2a0b8b00f006ed12bd41bd858fabfa7330c954c70f50ed8757"}, + {file = "propcache-0.3.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e474fc718e73ba5ec5180358aa07f6aded0ff5f2abe700e3115c37d75c947e18"}, + {file = "propcache-0.3.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:17d1c688a443355234f3c031349da69444be052613483f3e4158eef751abcd8a"}, + {file = "propcache-0.3.1-cp313-cp313t-win32.whl", hash = "sha256:359e81a949a7619802eb601d66d37072b79b79c2505e6d3fd8b945538411400d"}, + {file = "propcache-0.3.1-cp313-cp313t-win_amd64.whl", hash = "sha256:e7fb9a84c9abbf2b2683fa3e7b0d7da4d8ecf139a1c635732a8bda29c5214b0e"}, + {file = "propcache-0.3.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ed5f6d2edbf349bd8d630e81f474d33d6ae5d07760c44d33cd808e2f5c8f4ae6"}, + {file = "propcache-0.3.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:668ddddc9f3075af019f784456267eb504cb77c2c4bd46cc8402d723b4d200bf"}, + {file = "propcache-0.3.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0c86e7ceea56376216eba345aa1fc6a8a6b27ac236181f840d1d7e6a1ea9ba5c"}, + {file = "propcache-0.3.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83be47aa4e35b87c106fc0c84c0fc069d3f9b9b06d3c494cd404ec6747544894"}, + {file = "propcache-0.3.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:27c6ac6aa9fc7bc662f594ef380707494cb42c22786a558d95fcdedb9aa5d035"}, + {file = "propcache-0.3.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64a956dff37080b352c1c40b2966b09defb014347043e740d420ca1eb7c9b908"}, + {file = "propcache-0.3.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82de5da8c8893056603ac2d6a89eb8b4df49abf1a7c19d536984c8dd63f481d5"}, + {file = "propcache-0.3.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c3c3a203c375b08fd06a20da3cf7aac293b834b6f4f4db71190e8422750cca5"}, + {file = "propcache-0.3.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b303b194c2e6f171cfddf8b8ba30baefccf03d36a4d9cab7fd0bb68ba476a3d7"}, + {file = "propcache-0.3.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:916cd229b0150129d645ec51614d38129ee74c03293a9f3f17537be0029a9641"}, + {file = "propcache-0.3.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:a461959ead5b38e2581998700b26346b78cd98540b5524796c175722f18b0294"}, + {file = "propcache-0.3.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:069e7212890b0bcf9b2be0a03afb0c2d5161d91e1bf51569a64f629acc7defbf"}, + {file = "propcache-0.3.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ef2e4e91fb3945769e14ce82ed53007195e616a63aa43b40fb7ebaaf907c8d4c"}, + {file = "propcache-0.3.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:8638f99dca15b9dff328fb6273e09f03d1c50d9b6512f3b65a4154588a7595fe"}, + {file = "propcache-0.3.1-cp39-cp39-win32.whl", hash = "sha256:6f173bbfe976105aaa890b712d1759de339d8a7cef2fc0a1714cc1a1e1c47f64"}, + {file = "propcache-0.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:603f1fe4144420374f1a69b907494c3acbc867a581c2d49d4175b0de7cc64566"}, + {file = "propcache-0.3.1-py3-none-any.whl", hash = "sha256:9a8ecf38de50a7f518c21568c80f985e776397b902f1ce0b01f799aba1608b40"}, + {file = "propcache-0.3.1.tar.gz", hash = "sha256:40d980c33765359098837527e18eddefc9a24cea5b45e078a7f3bb5b032c6ecf"}, ] [[package]] @@ -2830,60 +2817,58 @@ files = [ [[package]] name = "pycryptodome" -version = "3.21.0" +version = "3.22.0" description = "Cryptographic library for Python" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" -files = [ - {file = "pycryptodome-3.21.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:dad9bf36eda068e89059d1f07408e397856be9511d7113ea4b586642a429a4fd"}, - {file = "pycryptodome-3.21.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:a1752eca64c60852f38bb29e2c86fca30d7672c024128ef5d70cc15868fa10f4"}, - {file = "pycryptodome-3.21.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:3ba4cc304eac4d4d458f508d4955a88ba25026890e8abff9b60404f76a62c55e"}, - {file = "pycryptodome-3.21.0-cp27-cp27m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7cb087b8612c8a1a14cf37dd754685be9a8d9869bed2ffaaceb04850a8aeef7e"}, - {file = "pycryptodome-3.21.0-cp27-cp27m-musllinux_1_1_aarch64.whl", hash = "sha256:26412b21df30b2861424a6c6d5b1d8ca8107612a4cfa4d0183e71c5d200fb34a"}, - {file = "pycryptodome-3.21.0-cp27-cp27m-win32.whl", hash = "sha256:cc2269ab4bce40b027b49663d61d816903a4bd90ad88cb99ed561aadb3888dd3"}, - {file = "pycryptodome-3.21.0-cp27-cp27m-win_amd64.whl", hash = "sha256:0fa0a05a6a697ccbf2a12cec3d6d2650b50881899b845fac6e87416f8cb7e87d"}, - {file = "pycryptodome-3.21.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:6cce52e196a5f1d6797ff7946cdff2038d3b5f0aba4a43cb6bf46b575fd1b5bb"}, - {file = "pycryptodome-3.21.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:a915597ffccabe902e7090e199a7bf7a381c5506a747d5e9d27ba55197a2c568"}, - {file = "pycryptodome-3.21.0-cp27-cp27mu-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4e74c522d630766b03a836c15bff77cb657c5fdf098abf8b1ada2aebc7d0819"}, - {file = "pycryptodome-3.21.0-cp27-cp27mu-musllinux_1_1_aarch64.whl", hash = "sha256:a3804675283f4764a02db05f5191eb8fec2bb6ca34d466167fc78a5f05bbe6b3"}, - {file = "pycryptodome-3.21.0-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:2480ec2c72438430da9f601ebc12c518c093c13111a5c1644c82cdfc2e50b1e4"}, - {file = "pycryptodome-3.21.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:de18954104667f565e2fbb4783b56667f30fb49c4d79b346f52a29cb198d5b6b"}, - {file = "pycryptodome-3.21.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2de4b7263a33947ff440412339cb72b28a5a4c769b5c1ca19e33dd6cd1dcec6e"}, - {file = "pycryptodome-3.21.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0714206d467fc911042d01ea3a1847c847bc10884cf674c82e12915cfe1649f8"}, - {file = "pycryptodome-3.21.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d85c1b613121ed3dbaa5a97369b3b757909531a959d229406a75b912dd51dd1"}, - {file = "pycryptodome-3.21.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:8898a66425a57bcf15e25fc19c12490b87bd939800f39a03ea2de2aea5e3611a"}, - {file = "pycryptodome-3.21.0-cp36-abi3-musllinux_1_2_i686.whl", hash = "sha256:932c905b71a56474bff8a9c014030bc3c882cee696b448af920399f730a650c2"}, - {file = "pycryptodome-3.21.0-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:18caa8cfbc676eaaf28613637a89980ad2fd96e00c564135bf90bc3f0b34dd93"}, - {file = "pycryptodome-3.21.0-cp36-abi3-win32.whl", hash = "sha256:280b67d20e33bb63171d55b1067f61fbd932e0b1ad976b3a184303a3dad22764"}, - {file = "pycryptodome-3.21.0-cp36-abi3-win_amd64.whl", hash = "sha256:b7aa25fc0baa5b1d95b7633af4f5f1838467f1815442b22487426f94e0d66c53"}, - {file = "pycryptodome-3.21.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:2cb635b67011bc147c257e61ce864879ffe6d03342dc74b6045059dfbdedafca"}, - {file = "pycryptodome-3.21.0-pp27-pypy_73-win32.whl", hash = "sha256:4c26a2f0dc15f81ea3afa3b0c87b87e501f235d332b7f27e2225ecb80c0b1cdd"}, - {file = "pycryptodome-3.21.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:d5ebe0763c982f069d3877832254f64974139f4f9655058452603ff559c482e8"}, - {file = "pycryptodome-3.21.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ee86cbde706be13f2dec5a42b52b1c1d1cbb90c8e405c68d0755134735c8dc6"}, - {file = "pycryptodome-3.21.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0fd54003ec3ce4e0f16c484a10bc5d8b9bd77fa662a12b85779a2d2d85d67ee0"}, - {file = "pycryptodome-3.21.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5dfafca172933506773482b0e18f0cd766fd3920bd03ec85a283df90d8a17bc6"}, - {file = "pycryptodome-3.21.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:590ef0898a4b0a15485b05210b4a1c9de8806d3ad3d47f74ab1dc07c67a6827f"}, - {file = "pycryptodome-3.21.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f35e442630bc4bc2e1878482d6f59ea22e280d7121d7adeaedba58c23ab6386b"}, - {file = "pycryptodome-3.21.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff99f952db3db2fbe98a0b355175f93ec334ba3d01bbde25ad3a5a33abc02b58"}, - {file = "pycryptodome-3.21.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:8acd7d34af70ee63f9a849f957558e49a98f8f1634f86a59d2be62bb8e93f71c"}, - {file = "pycryptodome-3.21.0.tar.gz", hash = "sha256:f7787e0d469bdae763b876174cf2e6c0f7be79808af26b1da96f1a64bcf47297"}, +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "pycryptodome-3.22.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:96e73527c9185a3d9b4c6d1cfb4494f6ced418573150be170f6580cb975a7f5a"}, + {file = "pycryptodome-3.22.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:9e1bb165ea1dc83a11e5dbbe00ef2c378d148f3a2d3834fb5ba4e0f6fd0afe4b"}, + {file = "pycryptodome-3.22.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:d4d1174677855c266eed5c4b4e25daa4225ad0c9ffe7584bb1816767892545d0"}, + {file = "pycryptodome-3.22.0-cp27-cp27m-win32.whl", hash = "sha256:9dbb749cef71c28271484cbef684f9b5b19962153487735411e1020ca3f59cb1"}, + {file = "pycryptodome-3.22.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:f1ae7beb64d4fc4903a6a6cca80f1f448e7a8a95b77d106f8a29f2eb44d17547"}, + {file = "pycryptodome-3.22.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:a26bcfee1293b7257c83b0bd13235a4ee58165352be4f8c45db851ba46996dc6"}, + {file = "pycryptodome-3.22.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:009e1c80eea42401a5bd5983c4bab8d516aef22e014a4705622e24e6d9d703c6"}, + {file = "pycryptodome-3.22.0-cp37-abi3-macosx_10_9_x86_64.whl", hash = "sha256:3b76fa80daeff9519d7e9f6d9e40708f2fce36b9295a847f00624a08293f4f00"}, + {file = "pycryptodome-3.22.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a31fa5914b255ab62aac9265654292ce0404f6b66540a065f538466474baedbc"}, + {file = "pycryptodome-3.22.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0092fd476701eeeb04df5cc509d8b739fa381583cda6a46ff0a60639b7cd70d"}, + {file = "pycryptodome-3.22.0-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18d5b0ddc7cf69231736d778bd3ae2b3efb681ae33b64b0c92fb4626bb48bb89"}, + {file = "pycryptodome-3.22.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:f6cf6aa36fcf463e622d2165a5ad9963b2762bebae2f632d719dfb8544903cf5"}, + {file = "pycryptodome-3.22.0-cp37-abi3-musllinux_1_2_i686.whl", hash = "sha256:aec7b40a7ea5af7c40f8837adf20a137d5e11a6eb202cde7e588a48fb2d871a8"}, + {file = "pycryptodome-3.22.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d21c1eda2f42211f18a25db4eaf8056c94a8563cd39da3683f89fe0d881fb772"}, + {file = "pycryptodome-3.22.0-cp37-abi3-win32.whl", hash = "sha256:f02baa9f5e35934c6e8dcec91fcde96612bdefef6e442813b8ea34e82c84bbfb"}, + {file = "pycryptodome-3.22.0-cp37-abi3-win_amd64.whl", hash = "sha256:d086aed307e96d40c23c42418cbbca22ecc0ab4a8a0e24f87932eeab26c08627"}, + {file = "pycryptodome-3.22.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:98fd9da809d5675f3a65dcd9ed384b9dc67edab6a4cda150c5870a8122ec961d"}, + {file = "pycryptodome-3.22.0-pp27-pypy_73-win32.whl", hash = "sha256:37ddcd18284e6b36b0a71ea495a4c4dca35bb09ccc9bfd5b91bfaf2321f131c1"}, + {file = "pycryptodome-3.22.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b4bdce34af16c1dcc7f8c66185684be15f5818afd2a82b75a4ce6b55f9783e13"}, + {file = "pycryptodome-3.22.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2988ffcd5137dc2d27eb51cd18c0f0f68e5b009d5fec56fbccb638f90934f333"}, + {file = "pycryptodome-3.22.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e653519dedcd1532788547f00eeb6108cc7ce9efdf5cc9996abce0d53f95d5a9"}, + {file = "pycryptodome-3.22.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5810bc7494e4ac12a4afef5a32218129e7d3890ce3f2b5ec520cc69eb1102ad"}, + {file = "pycryptodome-3.22.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e7514a1aebee8e85802d154fdb261381f1cb9b7c5a54594545145b8ec3056ae6"}, + {file = "pycryptodome-3.22.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:56c6f9342fcb6c74e205fbd2fee568ec4cdbdaa6165c8fde55dbc4ba5f584464"}, + {file = "pycryptodome-3.22.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87a88dc543b62b5c669895caf6c5a958ac7abc8863919e94b7a6cafd2f64064f"}, + {file = "pycryptodome-3.22.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7a683bc9fa585c0dfec7fa4801c96a48d30b30b096e3297f9374f40c2fedafc"}, + {file = "pycryptodome-3.22.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8f4f6f47a7f411f2c157e77bbbda289e0c9f9e1e9944caa73c1c2e33f3f92d6e"}, + {file = "pycryptodome-3.22.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6cf9553b29624961cab0785a3177a333e09e37ba62ad22314ebdbb01ca79840"}, + {file = "pycryptodome-3.22.0.tar.gz", hash = "sha256:fd7ab568b3ad7b77c908d7c3f7e167ec5a8f035c64ff74f10d47a4edd043d723"}, ] [[package]] name = "pydantic" -version = "2.10.6" +version = "2.11.4" description = "Data validation using Python type hints" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584"}, - {file = "pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236"}, + {file = "pydantic-2.11.4-py3-none-any.whl", hash = "sha256:d9615eaa9ac5a063471da949c8fc16376a84afb5024688b3ff885693506764eb"}, + {file = "pydantic-2.11.4.tar.gz", hash = "sha256:32738d19d63a226a52eed76645a98ee07c1f410ee41d93b4afbfa85ed8111c2d"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.27.2" +pydantic-core = "2.33.2" typing-extensions = ">=4.12.2" +typing-inspection = ">=0.4.0" [package.extras] email = ["email-validator (>=2.0.0)"] @@ -2891,111 +2876,110 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.27.2" +version = "2.33.2" description = "Core functionality for Pydantic validation and serialization" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, - {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, - {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a"}, - {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5"}, - {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c"}, - {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7"}, - {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a"}, - {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236"}, - {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962"}, - {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9"}, - {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af"}, - {file = "pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4"}, - {file = "pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31"}, - {file = "pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc"}, - {file = "pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7"}, - {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15"}, - {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306"}, - {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99"}, - {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459"}, - {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048"}, - {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d"}, - {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b"}, - {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474"}, - {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6"}, - {file = "pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c"}, - {file = "pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc"}, - {file = "pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4"}, - {file = "pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0"}, - {file = "pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef"}, - {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7"}, - {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934"}, - {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6"}, - {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c"}, - {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2"}, - {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4"}, - {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3"}, - {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4"}, - {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57"}, - {file = "pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc"}, - {file = "pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9"}, - {file = "pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b"}, - {file = "pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b"}, - {file = "pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154"}, - {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9"}, - {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9"}, - {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1"}, - {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a"}, - {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e"}, - {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4"}, - {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27"}, - {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee"}, - {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1"}, - {file = "pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130"}, - {file = "pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee"}, - {file = "pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b"}, - {file = "pydantic_core-2.27.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506"}, - {file = "pydantic_core-2.27.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320"}, - {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145"}, - {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1"}, - {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228"}, - {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046"}, - {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5"}, - {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a"}, - {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d"}, - {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9"}, - {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da"}, - {file = "pydantic_core-2.27.2-cp38-cp38-win32.whl", hash = "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b"}, - {file = "pydantic_core-2.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad"}, - {file = "pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993"}, - {file = "pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308"}, - {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4"}, - {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf"}, - {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76"}, - {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118"}, - {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630"}, - {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54"}, - {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f"}, - {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362"}, - {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96"}, - {file = "pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e"}, - {file = "pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67"}, - {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e"}, - {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8"}, - {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3"}, - {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f"}, - {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133"}, - {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc"}, - {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50"}, - {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9"}, - {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151"}, - {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656"}, - {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278"}, - {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb"}, - {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd"}, - {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc"}, - {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b"}, - {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b"}, - {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2"}, - {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35"}, - {file = "pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39"}, + {file = "pydantic_core-2.33.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2b3d326aaef0c0399d9afffeb6367d5e26ddc24d351dbc9c636840ac355dc5d8"}, + {file = "pydantic_core-2.33.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e5b2671f05ba48b94cb90ce55d8bdcaaedb8ba00cc5359f6810fc918713983d"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0069c9acc3f3981b9ff4cdfaf088e98d83440a4c7ea1bc07460af3d4dc22e72d"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d53b22f2032c42eaaf025f7c40c2e3b94568ae077a606f006d206a463bc69572"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0405262705a123b7ce9f0b92f123334d67b70fd1f20a9372b907ce1080c7ba02"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b25d91e288e2c4e0662b8038a28c6a07eaac3e196cfc4ff69de4ea3db992a1b"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bdfe4b3789761f3bcb4b1ddf33355a71079858958e3a552f16d5af19768fef2"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:efec8db3266b76ef9607c2c4c419bdb06bf335ae433b80816089ea7585816f6a"}, + {file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:031c57d67ca86902726e0fae2214ce6770bbe2f710dc33063187a68744a5ecac"}, + {file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:f8de619080e944347f5f20de29a975c2d815d9ddd8be9b9b7268e2e3ef68605a"}, + {file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:73662edf539e72a9440129f231ed3757faab89630d291b784ca99237fb94db2b"}, + {file = "pydantic_core-2.33.2-cp310-cp310-win32.whl", hash = "sha256:0a39979dcbb70998b0e505fb1556a1d550a0781463ce84ebf915ba293ccb7e22"}, + {file = "pydantic_core-2.33.2-cp310-cp310-win_amd64.whl", hash = "sha256:b0379a2b24882fef529ec3b4987cb5d003b9cda32256024e6fe1586ac45fc640"}, + {file = "pydantic_core-2.33.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4c5b0a576fb381edd6d27f0a85915c6daf2f8138dc5c267a57c08a62900758c7"}, + {file = "pydantic_core-2.33.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e799c050df38a639db758c617ec771fd8fb7a5f8eaaa4b27b101f266b216a246"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc46a01bf8d62f227d5ecee74178ffc448ff4e5197c756331f71efcc66dc980f"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a144d4f717285c6d9234a66778059f33a89096dfb9b39117663fd8413d582dcc"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cf6373c21bc80b2e0dc88444f41ae60b2f070ed02095754eb5a01df12256de"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dc625f4aa79713512d1976fe9f0bc99f706a9dee21dfd1810b4bbbf228d0e8a"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b21b5549499972441da4758d662aeea93f1923f953e9cbaff14b8b9565aef"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bdc25f3681f7b78572699569514036afe3c243bc3059d3942624e936ec93450e"}, + {file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fe5b32187cbc0c862ee201ad66c30cf218e5ed468ec8dc1cf49dec66e160cc4d"}, + {file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:bc7aee6f634a6f4a95676fcb5d6559a2c2a390330098dba5e5a5f28a2e4ada30"}, + {file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:235f45e5dbcccf6bd99f9f472858849f73d11120d76ea8707115415f8e5ebebf"}, + {file = "pydantic_core-2.33.2-cp311-cp311-win32.whl", hash = "sha256:6368900c2d3ef09b69cb0b913f9f8263b03786e5b2a387706c5afb66800efd51"}, + {file = "pydantic_core-2.33.2-cp311-cp311-win_amd64.whl", hash = "sha256:1e063337ef9e9820c77acc768546325ebe04ee38b08703244c1309cccc4f1bab"}, + {file = "pydantic_core-2.33.2-cp311-cp311-win_arm64.whl", hash = "sha256:6b99022f1d19bc32a4c2a0d544fc9a76e3be90f0b3f4af413f87d38749300e65"}, + {file = "pydantic_core-2.33.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc"}, + {file = "pydantic_core-2.33.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b"}, + {file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1"}, + {file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6"}, + {file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea"}, + {file = "pydantic_core-2.33.2-cp312-cp312-win32.whl", hash = "sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290"}, + {file = "pydantic_core-2.33.2-cp312-cp312-win_amd64.whl", hash = "sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2"}, + {file = "pydantic_core-2.33.2-cp312-cp312-win_arm64.whl", hash = "sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab"}, + {file = "pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f"}, + {file = "pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56"}, + {file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5"}, + {file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e"}, + {file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162"}, + {file = "pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849"}, + {file = "pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9"}, + {file = "pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9"}, + {file = "pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac"}, + {file = "pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5"}, + {file = "pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9"}, + {file = "pydantic_core-2.33.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a2b911a5b90e0374d03813674bf0a5fbbb7741570dcd4b4e85a2e48d17def29d"}, + {file = "pydantic_core-2.33.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6fa6dfc3e4d1f734a34710f391ae822e0a8eb8559a85c6979e14e65ee6ba2954"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c54c939ee22dc8e2d545da79fc5381f1c020d6d3141d3bd747eab59164dc89fb"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53a57d2ed685940a504248187d5685e49eb5eef0f696853647bf37c418c538f7"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09fb9dd6571aacd023fe6aaca316bd01cf60ab27240d7eb39ebd66a3a15293b4"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0e6116757f7959a712db11f3e9c0a99ade00a5bbedae83cb801985aa154f071b"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d55ab81c57b8ff8548c3e4947f119551253f4e3787a7bbc0b6b3ca47498a9d3"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c20c462aa4434b33a2661701b861604913f912254e441ab8d78d30485736115a"}, + {file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:44857c3227d3fb5e753d5fe4a3420d6376fa594b07b621e220cd93703fe21782"}, + {file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:eb9b459ca4df0e5c87deb59d37377461a538852765293f9e6ee834f0435a93b9"}, + {file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9fcd347d2cc5c23b06de6d3b7b8275be558a0c90549495c699e379a80bf8379e"}, + {file = "pydantic_core-2.33.2-cp39-cp39-win32.whl", hash = "sha256:83aa99b1285bc8f038941ddf598501a86f1536789740991d7d8756e34f1e74d9"}, + {file = "pydantic_core-2.33.2-cp39-cp39-win_amd64.whl", hash = "sha256:f481959862f57f29601ccced557cc2e817bce7533ab8e01a797a48b49c9692b3"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5c4aa4e82353f65e548c476b37e64189783aa5384903bfea4f41580f255fddfa"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d946c8bf0d5c24bf4fe333af284c59a19358aa3ec18cb3dc4370080da1e8ad29"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87b31b6846e361ef83fedb187bb5b4372d0da3f7e28d85415efa92d6125d6e6d"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa9d91b338f2df0508606f7009fde642391425189bba6d8c653afd80fd6bb64e"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2058a32994f1fde4ca0480ab9d1e75a0e8c87c22b53a3ae66554f9af78f2fe8c"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:0e03262ab796d986f978f79c943fc5f620381be7287148b8010b4097f79a39ec"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1a8695a8d00c73e50bff9dfda4d540b7dee29ff9b8053e38380426a85ef10052"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:fa754d1850735a0b0e03bcffd9d4b4343eb417e47196e4485d9cca326073a42c"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a11c8d26a50bfab49002947d3d237abe4d9e4b5bdc8846a63537b6488e197808"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:dd14041875d09cc0f9308e37a6f8b65f5585cf2598a53aa0123df8b129d481f8"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d87c561733f66531dced0da6e864f44ebf89a8fba55f31407b00c2f7f9449593"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f82865531efd18d6e07a04a17331af02cb7a651583c418df8266f17a63c6612"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bfb5112df54209d820d7bf9317c7a6c9025ea52e49f46b6a2060104bba37de7"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:64632ff9d614e5eecfb495796ad51b0ed98c453e447a76bcbeeb69615079fc7e"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f889f7a40498cc077332c7ab6b4608d296d852182211787d4f3ee377aaae66e8"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:de4b83bb311557e439b9e186f733f6c645b9417c84e2eb8203f3f820a4b988bf"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f68293f055f51b51ea42fafc74b6aad03e70e191799430b90c13d643059ebb"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:329467cecfb529c925cf2bbd4d60d2c509bc2fb52a20c1045bf09bb70971a9c1"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:87acbfcf8e90ca885206e98359d7dca4bcbb35abdc0ff66672a293e1d7a19101"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7f92c15cd1e97d4b12acd1cc9004fa092578acfa57b67ad5e43a197175d01a64"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3f26877a748dc4251cfcfda9dfb5f13fcb034f5308388066bcfe9031b63ae7d"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac89aea9af8cd672fa7b510e7b8c33b0bba9a43186680550ccf23020f32d535"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:970919794d126ba8645f3837ab6046fb4e72bbc057b3709144066204c19a455d"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3eb3fe62804e8f859c49ed20a8451342de53ed764150cb14ca71357c765dc2a6"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:3abcd9392a36025e3bd55f9bd38d908bd17962cc49bc6da8e7e96285336e2bca"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:3a1c81334778f9e3af2f8aeb7a960736e5cab1dfebfb26aabca09afd2906c039"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2807668ba86cb38c6817ad9bc66215ab8584d1d304030ce4f0887336f28a5e27"}, + {file = "pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc"}, ] [package.dependencies] @@ -3003,32 +2987,32 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pyinstaller" -version = "6.12.0" +version = "6.13.0" description = "PyInstaller bundles a Python application and all its dependencies into a single package." optional = false python-versions = "<3.14,>=3.8" files = [ - {file = "pyinstaller-6.12.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:68f1e4cecf88a6272063977fa2a2c69ad37cf568e5901769d7206d0314c74f47"}, - {file = "pyinstaller-6.12.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:fea76fc9b55ffa730fcf90beb897cce4399938460b0b6f40507fbebfc752c753"}, - {file = "pyinstaller-6.12.0-py3-none-manylinux2014_i686.whl", hash = "sha256:dac8a27988dbc33cdc34f2046803258bc3f6829de24de52745a5daa22bdba0f1"}, - {file = "pyinstaller-6.12.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:83c7f3bde9871b4a6aa71c66a96e8ba5c21668ce711ed97f510b9382d10aac6c"}, - {file = "pyinstaller-6.12.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:a69818815c6e0711c727edc30680cb1f81c691b59de35db81a2d9e0ae26a9ef1"}, - {file = "pyinstaller-6.12.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a2abf5fde31a8b38b6df7939bcef8ac1d0c51e97e25317ce3555cd675259750f"}, - {file = "pyinstaller-6.12.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:8e92e9873a616547bbabbb5a3a9843d5f2ab40c3d8b26810acdf0fe257bee4cf"}, - {file = "pyinstaller-6.12.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:aefe502d55c9cf6aeaed7feba80b5f8491ce43f8f2b5fe2d9aadca3ee5a05bc4"}, - {file = "pyinstaller-6.12.0-py3-none-win32.whl", hash = "sha256:138856a5a503bb69c066377e0a22671b0db063e9cc14d5cf5c798a53561200d3"}, - {file = "pyinstaller-6.12.0-py3-none-win_amd64.whl", hash = "sha256:0e62d3906309248409f215b386f33afec845214e69cc0f296b93222b26a88f43"}, - {file = "pyinstaller-6.12.0-py3-none-win_arm64.whl", hash = "sha256:0c271896a3a168f4f91827145702543db9c5427f4c7372a6df8c75925a3ac18a"}, - {file = "pyinstaller-6.12.0.tar.gz", hash = "sha256:1834797be48ce1b26015af68bdeb3c61a6c7500136f04e0fc65e468115dec777"}, + {file = "pyinstaller-6.13.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:aa404f0b02cd57948098055e76ee190b8e65ccf7a2a3f048e5000f668317069f"}, + {file = "pyinstaller-6.13.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:92efcf2f09e78f07b568c5cb7ed48c9940f5dad627af4b49bede6320fab2a06e"}, + {file = "pyinstaller-6.13.0-py3-none-manylinux2014_i686.whl", hash = "sha256:9f82f113c463f012faa0e323d952ca30a6f922685d9636e754bd3a256c7ed200"}, + {file = "pyinstaller-6.13.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:db0e7945ebe276f604eb7c36e536479556ab32853412095e19172a5ec8fca1c5"}, + {file = "pyinstaller-6.13.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:92fe7337c5aa08d42b38d7a79614492cb571489f2cb0a8f91dc9ef9ccbe01ed3"}, + {file = "pyinstaller-6.13.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:bc09795f5954135dd4486c1535650958c8218acb954f43860e4b05fb515a21c0"}, + {file = "pyinstaller-6.13.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:589937548d34978c568cfdc39f31cf386f45202bc27fdb8facb989c79dfb4c02"}, + {file = "pyinstaller-6.13.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:b7260832f7501ba1d2ce1834d4cddc0f2b94315282bc89c59333433715015447"}, + {file = "pyinstaller-6.13.0-py3-none-win32.whl", hash = "sha256:80c568848529635aa7ca46d8d525f68486d53e03f68b7bb5eba2c88d742e302c"}, + {file = "pyinstaller-6.13.0-py3-none-win_amd64.whl", hash = "sha256:8d4296236b85aae570379488c2da833b28828b17c57c2cc21fccd7e3811fe372"}, + {file = "pyinstaller-6.13.0-py3-none-win_arm64.whl", hash = "sha256:d9f21d56ca2443aa6a1e255e7ad285c76453893a454105abe1b4d45e92bb9a20"}, + {file = "pyinstaller-6.13.0.tar.gz", hash = "sha256:38911feec2c5e215e5159a7e66fdb12400168bd116143b54a8a7a37f08733456"}, ] [package.dependencies] altgraph = "*" -importlib-metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} +importlib_metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} macholib = {version = ">=1.8", markers = "sys_platform == \"darwin\""} packaging = ">=22.0" pefile = {version = ">=2022.5.30,<2024.8.26 || >2024.8.26", markers = "sys_platform == \"win32\""} -pyinstaller-hooks-contrib = ">=2025.1" +pyinstaller-hooks-contrib = ">=2025.2" pywin32-ctypes = {version = ">=0.2.1", markers = "sys_platform == \"win32\""} setuptools = ">=42.0.0" @@ -3038,13 +3022,13 @@ hook-testing = ["execnet (>=1.5.0)", "psutil", "pytest (>=2.7.3)"] [[package]] name = "pyinstaller-hooks-contrib" -version = "2025.1" +version = "2025.4" description = "Community maintained hooks for PyInstaller" optional = false python-versions = ">=3.8" files = [ - {file = "pyinstaller_hooks_contrib-2025.1-py3-none-any.whl", hash = "sha256:d3c799470cbc0bda60dcc8e6b4ab976777532b77621337f2037f558905e3a8e9"}, - {file = "pyinstaller_hooks_contrib-2025.1.tar.gz", hash = "sha256:130818f9e9a0a7f2261f1fd66054966a3a50c99d000981c5d1db11d3ad0c6ab2"}, + {file = "pyinstaller_hooks_contrib-2025.4-py3-none-any.whl", hash = "sha256:6c2d73269b4c484eb40051fc1acee0beb113c2cfb3b37437b8394faae6f0d072"}, + {file = "pyinstaller_hooks_contrib-2025.4.tar.gz", hash = "sha256:5ce1afd1997b03e70f546207031cfdf2782030aabacc102190677059e2856446"}, ] [package.dependencies] @@ -3222,29 +3206,27 @@ cli = ["click (>=5.0)"] [[package]] name = "pywin32" -version = "308" +version = "310" description = "Python for Window Extensions" optional = false python-versions = "*" files = [ - {file = "pywin32-308-cp310-cp310-win32.whl", hash = "sha256:796ff4426437896550d2981b9c2ac0ffd75238ad9ea2d3bfa67a1abd546d262e"}, - {file = "pywin32-308-cp310-cp310-win_amd64.whl", hash = "sha256:4fc888c59b3c0bef905ce7eb7e2106a07712015ea1c8234b703a088d46110e8e"}, - {file = "pywin32-308-cp310-cp310-win_arm64.whl", hash = "sha256:a5ab5381813b40f264fa3495b98af850098f814a25a63589a8e9eb12560f450c"}, - {file = "pywin32-308-cp311-cp311-win32.whl", hash = "sha256:5d8c8015b24a7d6855b1550d8e660d8daa09983c80e5daf89a273e5c6fb5095a"}, - {file = "pywin32-308-cp311-cp311-win_amd64.whl", hash = "sha256:575621b90f0dc2695fec346b2d6302faebd4f0f45c05ea29404cefe35d89442b"}, - {file = "pywin32-308-cp311-cp311-win_arm64.whl", hash = "sha256:100a5442b7332070983c4cd03f2e906a5648a5104b8a7f50175f7906efd16bb6"}, - {file = "pywin32-308-cp312-cp312-win32.whl", hash = "sha256:587f3e19696f4bf96fde9d8a57cec74a57021ad5f204c9e627e15c33ff568897"}, - {file = "pywin32-308-cp312-cp312-win_amd64.whl", hash = "sha256:00b3e11ef09ede56c6a43c71f2d31857cf7c54b0ab6e78ac659497abd2834f47"}, - {file = "pywin32-308-cp312-cp312-win_arm64.whl", hash = "sha256:9b4de86c8d909aed15b7011182c8cab38c8850de36e6afb1f0db22b8959e3091"}, - {file = "pywin32-308-cp313-cp313-win32.whl", hash = "sha256:1c44539a37a5b7b21d02ab34e6a4d314e0788f1690d65b48e9b0b89f31abbbed"}, - {file = "pywin32-308-cp313-cp313-win_amd64.whl", hash = "sha256:fd380990e792eaf6827fcb7e187b2b4b1cede0585e3d0c9e84201ec27b9905e4"}, - {file = "pywin32-308-cp313-cp313-win_arm64.whl", hash = "sha256:ef313c46d4c18dfb82a2431e3051ac8f112ccee1a34f29c263c583c568db63cd"}, - {file = "pywin32-308-cp37-cp37m-win32.whl", hash = "sha256:1f696ab352a2ddd63bd07430080dd598e6369152ea13a25ebcdd2f503a38f1ff"}, - {file = "pywin32-308-cp37-cp37m-win_amd64.whl", hash = "sha256:13dcb914ed4347019fbec6697a01a0aec61019c1046c2b905410d197856326a6"}, - {file = "pywin32-308-cp38-cp38-win32.whl", hash = "sha256:5794e764ebcabf4ff08c555b31bd348c9025929371763b2183172ff4708152f0"}, - {file = "pywin32-308-cp38-cp38-win_amd64.whl", hash = "sha256:3b92622e29d651c6b783e368ba7d6722b1634b8e70bd376fd7610fe1992e19de"}, - {file = "pywin32-308-cp39-cp39-win32.whl", hash = "sha256:7873ca4dc60ab3287919881a7d4f88baee4a6e639aa6962de25a98ba6b193341"}, - {file = "pywin32-308-cp39-cp39-win_amd64.whl", hash = "sha256:71b3322d949b4cc20776436a9c9ba0eeedcbc9c650daa536df63f0ff111bb920"}, + {file = "pywin32-310-cp310-cp310-win32.whl", hash = "sha256:6dd97011efc8bf51d6793a82292419eba2c71cf8e7250cfac03bba284454abc1"}, + {file = "pywin32-310-cp310-cp310-win_amd64.whl", hash = "sha256:c3e78706e4229b915a0821941a84e7ef420bf2b77e08c9dae3c76fd03fd2ae3d"}, + {file = "pywin32-310-cp310-cp310-win_arm64.whl", hash = "sha256:33babed0cf0c92a6f94cc6cc13546ab24ee13e3e800e61ed87609ab91e4c8213"}, + {file = "pywin32-310-cp311-cp311-win32.whl", hash = "sha256:1e765f9564e83011a63321bb9d27ec456a0ed90d3732c4b2e312b855365ed8bd"}, + {file = "pywin32-310-cp311-cp311-win_amd64.whl", hash = "sha256:126298077a9d7c95c53823934f000599f66ec9296b09167810eb24875f32689c"}, + {file = "pywin32-310-cp311-cp311-win_arm64.whl", hash = "sha256:19ec5fc9b1d51c4350be7bb00760ffce46e6c95eaf2f0b2f1150657b1a43c582"}, + {file = "pywin32-310-cp312-cp312-win32.whl", hash = "sha256:8a75a5cc3893e83a108c05d82198880704c44bbaee4d06e442e471d3c9ea4f3d"}, + {file = "pywin32-310-cp312-cp312-win_amd64.whl", hash = "sha256:bf5c397c9a9a19a6f62f3fb821fbf36cac08f03770056711f765ec1503972060"}, + {file = "pywin32-310-cp312-cp312-win_arm64.whl", hash = "sha256:2349cc906eae872d0663d4d6290d13b90621eaf78964bb1578632ff20e152966"}, + {file = "pywin32-310-cp313-cp313-win32.whl", hash = "sha256:5d241a659c496ada3253cd01cfaa779b048e90ce4b2b38cd44168ad555ce74ab"}, + {file = "pywin32-310-cp313-cp313-win_amd64.whl", hash = "sha256:667827eb3a90208ddbdcc9e860c81bde63a135710e21e4cb3348968e4bd5249e"}, + {file = "pywin32-310-cp313-cp313-win_arm64.whl", hash = "sha256:e308f831de771482b7cf692a1f308f8fca701b2d8f9dde6cc440c7da17e47b33"}, + {file = "pywin32-310-cp38-cp38-win32.whl", hash = "sha256:0867beb8addefa2e3979d4084352e4ac6e991ca45373390775f7084cc0209b9c"}, + {file = "pywin32-310-cp38-cp38-win_amd64.whl", hash = "sha256:30f0a9b3138fb5e07eb4973b7077e1883f558e40c578c6925acc7a94c34eaa36"}, + {file = "pywin32-310-cp39-cp39-win32.whl", hash = "sha256:851c8d927af0d879221e616ae1f66145253537bbdd321a77e8ef701b443a9a1a"}, + {file = "pywin32-310-cp39-cp39-win_amd64.whl", hash = "sha256:96867217335559ac619f00ad70e513c0fcf84b8a3af9fc2bba3b59b97da70475"}, ] [[package]] @@ -3490,18 +3472,18 @@ files = [ [[package]] name = "setuptools" -version = "75.8.2" +version = "80.3.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.9" files = [ - {file = "setuptools-75.8.2-py3-none-any.whl", hash = "sha256:558e47c15f1811c1fa7adbd0096669bf76c1d3f433f58324df69f3f5ecac4e8f"}, - {file = "setuptools-75.8.2.tar.gz", hash = "sha256:4880473a969e5f23f2a2be3646b2dfd84af9028716d398e46192f84bc36900d2"}, + {file = "setuptools-80.3.1-py3-none-any.whl", hash = "sha256:ea8e00d7992054c4c592aeb892f6ad51fe1b4d90cc6947cc45c45717c40ec537"}, + {file = "setuptools-80.3.1.tar.gz", hash = "sha256:31e2c58dbb67c99c289f51c16d899afedae292b978f8051efaf6262d8212f927"}, ] [package.extras] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.8.0)"] -core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +core = ["importlib_metadata (>=6)", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] @@ -3543,13 +3525,13 @@ files = [ [[package]] name = "soupsieve" -version = "2.6" +version = "2.7" description = "A modern CSS selector implementation for Beautiful Soup." optional = false python-versions = ">=3.8" files = [ - {file = "soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9"}, - {file = "soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb"}, + {file = "soupsieve-2.7-py3-none-any.whl", hash = "sha256:6e60cc5c1ffaf1cebcc12e8188320b72071e922c2e897f737cadce79ad5d30c4"}, + {file = "soupsieve-2.7.tar.gz", hash = "sha256:ad282f9b6926286d2ead4750552c8a6142bc4c783fd66b0293547c8fe6ae126a"}, ] [[package]] @@ -3583,13 +3565,13 @@ full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7 [[package]] name = "termcolor" -version = "2.5.0" +version = "3.1.0" description = "ANSI color formatting for output in terminal" optional = false python-versions = ">=3.9" files = [ - {file = "termcolor-2.5.0-py3-none-any.whl", hash = "sha256:37b17b5fc1e604945c2642c872a3764b5d547a48009871aea3edd3afa180afb8"}, - {file = "termcolor-2.5.0.tar.gz", hash = "sha256:998d8d27da6d48442e8e1f016119076b690d962507531df4890fcd2db2ef8a6f"}, + {file = "termcolor-3.1.0-py3-none-any.whl", hash = "sha256:591dd26b5c2ce03b9e43f391264626557873ce1d379019786f99b0c2bee140aa"}, + {file = "termcolor-3.1.0.tar.gz", hash = "sha256:6a6dd7fbee581909eeec6a756cff1d7f7c376063b14e4a298dc4980309e55970"}, ] [package.extras] @@ -3735,24 +3717,38 @@ pyotp = "*" [[package]] name = "typing-extensions" -version = "4.12.2" +version = "4.13.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, + {file = "typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c"}, + {file = "typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef"}, +] + +[[package]] +name = "typing-inspection" +version = "0.4.0" +description = "Runtime typing introspection tools" +optional = false +python-versions = ">=3.9" +files = [ + {file = "typing_inspection-0.4.0-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f"}, + {file = "typing_inspection-0.4.0.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122"}, ] +[package.dependencies] +typing-extensions = ">=4.12.0" + [[package]] name = "urllib3" -version = "2.3.0" +version = "2.4.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.9" files = [ - {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, - {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, + {file = "urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813"}, + {file = "urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466"}, ] [package.extras] @@ -3820,13 +3816,13 @@ files = [ [[package]] name = "virtualenv" -version = "20.29.2" +version = "20.31.1" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.8" files = [ - {file = "virtualenv-20.29.2-py3-none-any.whl", hash = "sha256:febddfc3d1ea571bdb1dc0f98d7b45d24def7428214d4fb73cc486c9568cce6a"}, - {file = "virtualenv-20.29.2.tar.gz", hash = "sha256:fdaabebf6d03b5ba83ae0a02cfe96f48a716f4fae556461d180825866f75b728"}, + {file = "virtualenv-20.31.1-py3-none-any.whl", hash = "sha256:f448cd2f1604c831afb9ea238021060be2c0edbcad8eb0a4e8b4e14ff11a5482"}, + {file = "virtualenv-20.31.1.tar.gz", hash = "sha256:65442939608aeebb9284cd30baca5865fcd9f12b58bb740a24b220030df46d26"}, ] [package.dependencies] @@ -3929,80 +3925,80 @@ six = "*" [[package]] name = "websockets" -version = "15.0" +version = "15.0.1" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" optional = false python-versions = ">=3.9" files = [ - {file = "websockets-15.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5e6ee18a53dd5743e6155b8ff7e8e477c25b29b440f87f65be8165275c87fef0"}, - {file = "websockets-15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ee06405ea2e67366a661ed313e14cf2a86e84142a3462852eb96348f7219cee3"}, - {file = "websockets-15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8711682a629bbcaf492f5e0af72d378e976ea1d127a2d47584fa1c2c080b436b"}, - {file = "websockets-15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94c4a9b01eede952442c088d415861b0cf2053cbd696b863f6d5022d4e4e2453"}, - {file = "websockets-15.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:45535fead66e873f411c1d3cf0d3e175e66f4dd83c4f59d707d5b3e4c56541c4"}, - {file = "websockets-15.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e389efe46ccb25a1f93d08c7a74e8123a2517f7b7458f043bd7529d1a63ffeb"}, - {file = "websockets-15.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:67a04754d121ea5ca39ddedc3f77071651fb5b0bc6b973c71c515415b44ed9c5"}, - {file = "websockets-15.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:bd66b4865c8b853b8cca7379afb692fc7f52cf898786537dfb5e5e2d64f0a47f"}, - {file = "websockets-15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a4cc73a6ae0a6751b76e69cece9d0311f054da9b22df6a12f2c53111735657c8"}, - {file = "websockets-15.0-cp310-cp310-win32.whl", hash = "sha256:89da58e4005e153b03fe8b8794330e3f6a9774ee9e1c3bd5bc52eb098c3b0c4f"}, - {file = "websockets-15.0-cp310-cp310-win_amd64.whl", hash = "sha256:4ff380aabd7a74a42a760ee76c68826a8f417ceb6ea415bd574a035a111fd133"}, - {file = "websockets-15.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:dd24c4d256558429aeeb8d6c24ebad4e982ac52c50bc3670ae8646c181263965"}, - {file = "websockets-15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f83eca8cbfd168e424dfa3b3b5c955d6c281e8fc09feb9d870886ff8d03683c7"}, - {file = "websockets-15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4095a1f2093002c2208becf6f9a178b336b7572512ee0a1179731acb7788e8ad"}, - {file = "websockets-15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb915101dfbf318486364ce85662bb7b020840f68138014972c08331458d41f3"}, - {file = "websockets-15.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:45d464622314973d78f364689d5dbb9144e559f93dca11b11af3f2480b5034e1"}, - {file = "websockets-15.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ace960769d60037ca9625b4c578a6f28a14301bd2a1ff13bb00e824ac9f73e55"}, - {file = "websockets-15.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c7cd4b1015d2f60dfe539ee6c95bc968d5d5fad92ab01bb5501a77393da4f596"}, - {file = "websockets-15.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4f7290295794b5dec470867c7baa4a14182b9732603fd0caf2a5bf1dc3ccabf3"}, - {file = "websockets-15.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3abd670ca7ce230d5a624fd3d55e055215d8d9b723adee0a348352f5d8d12ff4"}, - {file = "websockets-15.0-cp311-cp311-win32.whl", hash = "sha256:110a847085246ab8d4d119632145224d6b49e406c64f1bbeed45c6f05097b680"}, - {file = "websockets-15.0-cp311-cp311-win_amd64.whl", hash = "sha256:8d7bbbe2cd6ed80aceef2a14e9f1c1b61683194c216472ed5ff33b700e784e37"}, - {file = "websockets-15.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:cccc18077acd34c8072578394ec79563664b1c205f7a86a62e94fafc7b59001f"}, - {file = "websockets-15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d4c22992e24f12de340ca5f824121a5b3e1a37ad4360b4e1aaf15e9d1c42582d"}, - {file = "websockets-15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1206432cc6c644f6fc03374b264c5ff805d980311563202ed7fef91a38906276"}, - {file = "websockets-15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d3cc75ef3e17490042c47e0523aee1bcc4eacd2482796107fd59dd1100a44bc"}, - {file = "websockets-15.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b89504227a5311610e4be16071465885a0a3d6b0e82e305ef46d9b064ce5fb72"}, - {file = "websockets-15.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56e3efe356416bc67a8e093607315951d76910f03d2b3ad49c4ade9207bf710d"}, - {file = "websockets-15.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0f2205cdb444a42a7919690238fb5979a05439b9dbb73dd47c863d39640d85ab"}, - {file = "websockets-15.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:aea01f40995fa0945c020228ab919b8dfc93fc8a9f2d3d705ab5b793f32d9e99"}, - {file = "websockets-15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a9f8e33747b1332db11cf7fcf4a9512bef9748cb5eb4d3f7fbc8c30d75dc6ffc"}, - {file = "websockets-15.0-cp312-cp312-win32.whl", hash = "sha256:32e02a2d83f4954aa8c17e03fe8ec6962432c39aca4be7e8ee346b05a3476904"}, - {file = "websockets-15.0-cp312-cp312-win_amd64.whl", hash = "sha256:ffc02b159b65c05f2ed9ec176b715b66918a674bd4daed48a9a7a590dd4be1aa"}, - {file = "websockets-15.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:d2244d8ab24374bed366f9ff206e2619345f9cd7fe79aad5225f53faac28b6b1"}, - {file = "websockets-15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3a302241fbe825a3e4fe07666a2ab513edfdc6d43ce24b79691b45115273b5e7"}, - {file = "websockets-15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:10552fed076757a70ba2c18edcbc601c7637b30cdfe8c24b65171e824c7d6081"}, - {file = "websockets-15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c53f97032b87a406044a1c33d1e9290cc38b117a8062e8a8b285175d7e2f99c9"}, - {file = "websockets-15.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1caf951110ca757b8ad9c4974f5cac7b8413004d2f29707e4d03a65d54cedf2b"}, - {file = "websockets-15.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8bf1ab71f9f23b0a1d52ec1682a3907e0c208c12fef9c3e99d2b80166b17905f"}, - {file = "websockets-15.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bfcd3acc1a81f106abac6afd42327d2cf1e77ec905ae11dc1d9142a006a496b6"}, - {file = "websockets-15.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c8c5c8e1bac05ef3c23722e591ef4f688f528235e2480f157a9cfe0a19081375"}, - {file = "websockets-15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:86bfb52a9cfbcc09aba2b71388b0a20ea5c52b6517c0b2e316222435a8cdab72"}, - {file = "websockets-15.0-cp313-cp313-win32.whl", hash = "sha256:26ba70fed190708551c19a360f9d7eca8e8c0f615d19a574292b7229e0ae324c"}, - {file = "websockets-15.0-cp313-cp313-win_amd64.whl", hash = "sha256:ae721bcc8e69846af00b7a77a220614d9b2ec57d25017a6bbde3a99473e41ce8"}, - {file = "websockets-15.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c348abc5924caa02a62896300e32ea80a81521f91d6db2e853e6b1994017c9f6"}, - {file = "websockets-15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5294fcb410ed0a45d5d1cdedc4e51a60aab5b2b3193999028ea94afc2f554b05"}, - {file = "websockets-15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c24ba103ecf45861e2e1f933d40b2d93f5d52d8228870c3e7bf1299cd1cb8ff1"}, - {file = "websockets-15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc8821a03bcfb36e4e4705316f6b66af28450357af8a575dc8f4b09bf02a3dee"}, - {file = "websockets-15.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc5ae23ada6515f31604f700009e2df90b091b67d463a8401c1d8a37f76c1d7"}, - {file = "websockets-15.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ac67b542505186b3bbdaffbc303292e1ee9c8729e5d5df243c1f20f4bb9057e"}, - {file = "websockets-15.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c86dc2068f1c5ca2065aca34f257bbf4f78caf566eb230f692ad347da191f0a1"}, - {file = "websockets-15.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:30cff3ef329682b6182c01c568f551481774c476722020b8f7d0daacbed07a17"}, - {file = "websockets-15.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:98dcf978d4c6048965d1762abd534c9d53bae981a035bfe486690ba11f49bbbb"}, - {file = "websockets-15.0-cp39-cp39-win32.whl", hash = "sha256:37d66646f929ae7c22c79bc73ec4074d6db45e6384500ee3e0d476daf55482a9"}, - {file = "websockets-15.0-cp39-cp39-win_amd64.whl", hash = "sha256:24d5333a9b2343330f0f4eb88546e2c32a7f5c280f8dd7d3cc079beb0901781b"}, - {file = "websockets-15.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b499caef4bca9cbd0bd23cd3386f5113ee7378094a3cb613a2fa543260fe9506"}, - {file = "websockets-15.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:17f2854c6bd9ee008c4b270f7010fe2da6c16eac5724a175e75010aacd905b31"}, - {file = "websockets-15.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89f72524033abbfde880ad338fd3c2c16e31ae232323ebdfbc745cbb1b3dcc03"}, - {file = "websockets-15.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1657a9eecb29d7838e3b415458cc494e6d1b194f7ac73a34aa55c6fb6c72d1f3"}, - {file = "websockets-15.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e413352a921f5ad5d66f9e2869b977e88d5103fc528b6deb8423028a2befd842"}, - {file = "websockets-15.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:8561c48b0090993e3b2a54db480cab1d23eb2c5735067213bb90f402806339f5"}, - {file = "websockets-15.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:190bc6ef8690cd88232a038d1b15714c258f79653abad62f7048249b09438af3"}, - {file = "websockets-15.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:327adab7671f3726b0ba69be9e865bba23b37a605b585e65895c428f6e47e766"}, - {file = "websockets-15.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bd8ef197c87afe0a9009f7a28b5dc613bfc585d329f80b7af404e766aa9e8c7"}, - {file = "websockets-15.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:789c43bf4a10cd067c24c321238e800b8b2716c863ddb2294d2fed886fa5a689"}, - {file = "websockets-15.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7394c0b7d460569c9285fa089a429f58465db930012566c03046f9e3ab0ed181"}, - {file = "websockets-15.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2ea4f210422b912ebe58ef0ad33088bc8e5c5ff9655a8822500690abc3b1232d"}, - {file = "websockets-15.0-py3-none-any.whl", hash = "sha256:51ffd53c53c4442415b613497a34ba0aa7b99ac07f1e4a62db5dcd640ae6c3c3"}, - {file = "websockets-15.0.tar.gz", hash = "sha256:ca36151289a15b39d8d683fd8b7abbe26fc50be311066c5f8dcf3cb8cee107ab"}, + {file = "websockets-15.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d63efaa0cd96cf0c5fe4d581521d9fa87744540d4bc999ae6e08595a1014b45b"}, + {file = "websockets-15.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac60e3b188ec7574cb761b08d50fcedf9d77f1530352db4eef1707fe9dee7205"}, + {file = "websockets-15.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5756779642579d902eed757b21b0164cd6fe338506a8083eb58af5c372e39d9a"}, + {file = "websockets-15.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fdfe3e2a29e4db3659dbd5bbf04560cea53dd9610273917799f1cde46aa725e"}, + {file = "websockets-15.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c2529b320eb9e35af0fa3016c187dffb84a3ecc572bcee7c3ce302bfeba52bf"}, + {file = "websockets-15.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac1e5c9054fe23226fb11e05a6e630837f074174c4c2f0fe442996112a6de4fb"}, + {file = "websockets-15.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5df592cd503496351d6dc14f7cdad49f268d8e618f80dce0cd5a36b93c3fc08d"}, + {file = "websockets-15.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0a34631031a8f05657e8e90903e656959234f3a04552259458aac0b0f9ae6fd9"}, + {file = "websockets-15.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3d00075aa65772e7ce9e990cab3ff1de702aa09be3940d1dc88d5abf1ab8a09c"}, + {file = "websockets-15.0.1-cp310-cp310-win32.whl", hash = "sha256:1234d4ef35db82f5446dca8e35a7da7964d02c127b095e172e54397fb6a6c256"}, + {file = "websockets-15.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:39c1fec2c11dc8d89bba6b2bf1556af381611a173ac2b511cf7231622058af41"}, + {file = "websockets-15.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:823c248b690b2fd9303ba00c4f66cd5e2d8c3ba4aa968b2779be9532a4dad431"}, + {file = "websockets-15.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678999709e68425ae2593acf2e3ebcbcf2e69885a5ee78f9eb80e6e371f1bf57"}, + {file = "websockets-15.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d50fd1ee42388dcfb2b3676132c78116490976f1300da28eb629272d5d93e905"}, + {file = "websockets-15.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d99e5546bf73dbad5bf3547174cd6cb8ba7273062a23808ffea025ecb1cf8562"}, + {file = "websockets-15.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66dd88c918e3287efc22409d426c8f729688d89a0c587c88971a0faa2c2f3792"}, + {file = "websockets-15.0.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8dd8327c795b3e3f219760fa603dcae1dcc148172290a8ab15158cf85a953413"}, + {file = "websockets-15.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8fdc51055e6ff4adeb88d58a11042ec9a5eae317a0a53d12c062c8a8865909e8"}, + {file = "websockets-15.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:693f0192126df6c2327cce3baa7c06f2a117575e32ab2308f7f8216c29d9e2e3"}, + {file = "websockets-15.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:54479983bd5fb469c38f2f5c7e3a24f9a4e70594cd68cd1fa6b9340dadaff7cf"}, + {file = "websockets-15.0.1-cp311-cp311-win32.whl", hash = "sha256:16b6c1b3e57799b9d38427dda63edcbe4926352c47cf88588c0be4ace18dac85"}, + {file = "websockets-15.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:27ccee0071a0e75d22cb35849b1db43f2ecd3e161041ac1ee9d2352ddf72f065"}, + {file = "websockets-15.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3e90baa811a5d73f3ca0bcbf32064d663ed81318ab225ee4f427ad4e26e5aff3"}, + {file = "websockets-15.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:592f1a9fe869c778694f0aa806ba0374e97648ab57936f092fd9d87f8bc03665"}, + {file = "websockets-15.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0701bc3cfcb9164d04a14b149fd74be7347a530ad3bbf15ab2c678a2cd3dd9a2"}, + {file = "websockets-15.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8b56bdcdb4505c8078cb6c7157d9811a85790f2f2b3632c7d1462ab5783d215"}, + {file = "websockets-15.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0af68c55afbd5f07986df82831c7bff04846928ea8d1fd7f30052638788bc9b5"}, + {file = "websockets-15.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64dee438fed052b52e4f98f76c5790513235efaa1ef7f3f2192c392cd7c91b65"}, + {file = "websockets-15.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d5f6b181bb38171a8ad1d6aa58a67a6aa9d4b38d0f8c5f496b9e42561dfc62fe"}, + {file = "websockets-15.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5d54b09eba2bada6011aea5375542a157637b91029687eb4fdb2dab11059c1b4"}, + {file = "websockets-15.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3be571a8b5afed347da347bfcf27ba12b069d9d7f42cb8c7028b5e98bbb12597"}, + {file = "websockets-15.0.1-cp312-cp312-win32.whl", hash = "sha256:c338ffa0520bdb12fbc527265235639fb76e7bc7faafbb93f6ba80d9c06578a9"}, + {file = "websockets-15.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:fcd5cf9e305d7b8338754470cf69cf81f420459dbae8a3b40cee57417f4614a7"}, + {file = "websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931"}, + {file = "websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675"}, + {file = "websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151"}, + {file = "websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22"}, + {file = "websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f"}, + {file = "websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8"}, + {file = "websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375"}, + {file = "websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d"}, + {file = "websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4"}, + {file = "websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa"}, + {file = "websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561"}, + {file = "websockets-15.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5f4c04ead5aed67c8a1a20491d54cdfba5884507a48dd798ecaf13c74c4489f5"}, + {file = "websockets-15.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abdc0c6c8c648b4805c5eacd131910d2a7f6455dfd3becab248ef108e89ab16a"}, + {file = "websockets-15.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a625e06551975f4b7ea7102bc43895b90742746797e2e14b70ed61c43a90f09b"}, + {file = "websockets-15.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d591f8de75824cbb7acad4e05d2d710484f15f29d4a915092675ad3456f11770"}, + {file = "websockets-15.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47819cea040f31d670cc8d324bb6435c6f133b8c7a19ec3d61634e62f8d8f9eb"}, + {file = "websockets-15.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac017dd64572e5c3bd01939121e4d16cf30e5d7e110a119399cf3133b63ad054"}, + {file = "websockets-15.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4a9fac8e469d04ce6c25bb2610dc535235bd4aa14996b4e6dbebf5e007eba5ee"}, + {file = "websockets-15.0.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363c6f671b761efcb30608d24925a382497c12c506b51661883c3e22337265ed"}, + {file = "websockets-15.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2034693ad3097d5355bfdacfffcbd3ef5694f9718ab7f29c29689a9eae841880"}, + {file = "websockets-15.0.1-cp39-cp39-win32.whl", hash = "sha256:3b1ac0d3e594bf121308112697cf4b32be538fb1444468fb0a6ae4feebc83411"}, + {file = "websockets-15.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:b7643a03db5c95c799b89b31c036d5f27eeb4d259c798e878d6937d71832b1e4"}, + {file = "websockets-15.0.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0c9e74d766f2818bb95f84c25be4dea09841ac0f734d1966f415e4edfc4ef1c3"}, + {file = "websockets-15.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1009ee0c7739c08a0cd59de430d6de452a55e42d6b522de7aa15e6f67db0b8e1"}, + {file = "websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76d1f20b1c7a2fa82367e04982e708723ba0e7b8d43aa643d3dcd404d74f1475"}, + {file = "websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f29d80eb9a9263b8d109135351caf568cc3f80b9928bccde535c235de55c22d9"}, + {file = "websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b359ed09954d7c18bbc1680f380c7301f92c60bf924171629c5db97febb12f04"}, + {file = "websockets-15.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:cad21560da69f4ce7658ca2cb83138fb4cf695a2ba3e475e0559e05991aa8122"}, + {file = "websockets-15.0.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7f493881579c90fc262d9cdbaa05a6b54b3811c2f300766748db79f098db9940"}, + {file = "websockets-15.0.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:47b099e1f4fbc95b701b6e85768e1fcdaf1630f3cbe4765fa216596f12310e2e"}, + {file = "websockets-15.0.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67f2b6de947f8c757db2db9c71527933ad0019737ec374a8a6be9a956786aaf9"}, + {file = "websockets-15.0.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d08eb4c2b7d6c41da6ca0600c077e93f5adcfd979cd777d747e9ee624556da4b"}, + {file = "websockets-15.0.1-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b826973a4a2ae47ba357e4e82fa44a463b8f168e1ca775ac64521442b19e87f"}, + {file = "websockets-15.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:21c1fa28a6a7e3cbdc171c694398b6df4744613ce9b36b1a498e816787e28123"}, + {file = "websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f"}, + {file = "websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee"}, ] [[package]] @@ -4021,99 +4017,121 @@ watchdog = ["watchdog"] [[package]] name = "yarl" -version = "1.18.3" +version = "1.20.0" description = "Yet another URL library" optional = false python-versions = ">=3.9" files = [ - {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7df647e8edd71f000a5208fe6ff8c382a1de8edfbccdbbfe649d263de07d8c34"}, - {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c69697d3adff5aa4f874b19c0e4ed65180ceed6318ec856ebc423aa5850d84f7"}, - {file = "yarl-1.18.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:602d98f2c2d929f8e697ed274fbadc09902c4025c5a9963bf4e9edfc3ab6f7ed"}, - {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c654d5207c78e0bd6d749f6dae1dcbbfde3403ad3a4b11f3c5544d9906969dde"}, - {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5094d9206c64181d0f6e76ebd8fb2f8fe274950a63890ee9e0ebfd58bf9d787b"}, - {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35098b24e0327fc4ebdc8ffe336cee0a87a700c24ffed13161af80124b7dc8e5"}, - {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3236da9272872443f81fedc389bace88408f64f89f75d1bdb2256069a8730ccc"}, - {file = "yarl-1.18.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2c08cc9b16f4f4bc522771d96734c7901e7ebef70c6c5c35dd0f10845270bcd"}, - {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80316a8bd5109320d38eef8833ccf5f89608c9107d02d2a7f985f98ed6876990"}, - {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c1e1cc06da1491e6734f0ea1e6294ce00792193c463350626571c287c9a704db"}, - {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fea09ca13323376a2fdfb353a5fa2e59f90cd18d7ca4eaa1fd31f0a8b4f91e62"}, - {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e3b9fd71836999aad54084906f8663dffcd2a7fb5cdafd6c37713b2e72be1760"}, - {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:757e81cae69244257d125ff31663249b3013b5dc0a8520d73694aed497fb195b"}, - {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b1771de9944d875f1b98a745bc547e684b863abf8f8287da8466cf470ef52690"}, - {file = "yarl-1.18.3-cp310-cp310-win32.whl", hash = "sha256:8874027a53e3aea659a6d62751800cf6e63314c160fd607489ba5c2edd753cf6"}, - {file = "yarl-1.18.3-cp310-cp310-win_amd64.whl", hash = "sha256:93b2e109287f93db79210f86deb6b9bbb81ac32fc97236b16f7433db7fc437d8"}, - {file = "yarl-1.18.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8503ad47387b8ebd39cbbbdf0bf113e17330ffd339ba1144074da24c545f0069"}, - {file = "yarl-1.18.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:02ddb6756f8f4517a2d5e99d8b2f272488e18dd0bfbc802f31c16c6c20f22193"}, - {file = "yarl-1.18.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:67a283dd2882ac98cc6318384f565bffc751ab564605959df4752d42483ad889"}, - {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d980e0325b6eddc81331d3f4551e2a333999fb176fd153e075c6d1c2530aa8a8"}, - {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b643562c12680b01e17239be267bc306bbc6aac1f34f6444d1bded0c5ce438ca"}, - {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c017a3b6df3a1bd45b9fa49a0f54005e53fbcad16633870104b66fa1a30a29d8"}, - {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75674776d96d7b851b6498f17824ba17849d790a44d282929c42dbb77d4f17ae"}, - {file = "yarl-1.18.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ccaa3a4b521b780a7e771cc336a2dba389a0861592bbce09a476190bb0c8b4b3"}, - {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2d06d3005e668744e11ed80812e61efd77d70bb7f03e33c1598c301eea20efbb"}, - {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:9d41beda9dc97ca9ab0b9888cb71f7539124bc05df02c0cff6e5acc5a19dcc6e"}, - {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ba23302c0c61a9999784e73809427c9dbedd79f66a13d84ad1b1943802eaaf59"}, - {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6748dbf9bfa5ba1afcc7556b71cda0d7ce5f24768043a02a58846e4a443d808d"}, - {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0b0cad37311123211dc91eadcb322ef4d4a66008d3e1bdc404808992260e1a0e"}, - {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0fb2171a4486bb075316ee754c6d8382ea6eb8b399d4ec62fde2b591f879778a"}, - {file = "yarl-1.18.3-cp311-cp311-win32.whl", hash = "sha256:61b1a825a13bef4a5f10b1885245377d3cd0bf87cba068e1d9a88c2ae36880e1"}, - {file = "yarl-1.18.3-cp311-cp311-win_amd64.whl", hash = "sha256:b9d60031cf568c627d028239693fd718025719c02c9f55df0a53e587aab951b5"}, - {file = "yarl-1.18.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1dd4bdd05407ced96fed3d7f25dbbf88d2ffb045a0db60dbc247f5b3c5c25d50"}, - {file = "yarl-1.18.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7c33dd1931a95e5d9a772d0ac5e44cac8957eaf58e3c8da8c1414de7dd27c576"}, - {file = "yarl-1.18.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:25b411eddcfd56a2f0cd6a384e9f4f7aa3efee14b188de13048c25b5e91f1640"}, - {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:436c4fc0a4d66b2badc6c5fc5ef4e47bb10e4fd9bf0c79524ac719a01f3607c2"}, - {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e35ef8683211db69ffe129a25d5634319a677570ab6b2eba4afa860f54eeaf75"}, - {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84b2deecba4a3f1a398df819151eb72d29bfeb3b69abb145a00ddc8d30094512"}, - {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00e5a1fea0fd4f5bfa7440a47eff01d9822a65b4488f7cff83155a0f31a2ecba"}, - {file = "yarl-1.18.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0e883008013c0e4aef84dcfe2a0b172c4d23c2669412cf5b3371003941f72bb"}, - {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5a3f356548e34a70b0172d8890006c37be92995f62d95a07b4a42e90fba54272"}, - {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ccd17349166b1bee6e529b4add61727d3f55edb7babbe4069b5764c9587a8cc6"}, - {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b958ddd075ddba5b09bb0be8a6d9906d2ce933aee81100db289badbeb966f54e"}, - {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c7d79f7d9aabd6011004e33b22bc13056a3e3fb54794d138af57f5ee9d9032cb"}, - {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4891ed92157e5430874dad17b15eb1fda57627710756c27422200c52d8a4e393"}, - {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ce1af883b94304f493698b00d0f006d56aea98aeb49d75ec7d98cd4a777e9285"}, - {file = "yarl-1.18.3-cp312-cp312-win32.whl", hash = "sha256:f91c4803173928a25e1a55b943c81f55b8872f0018be83e3ad4938adffb77dd2"}, - {file = "yarl-1.18.3-cp312-cp312-win_amd64.whl", hash = "sha256:7e2ee16578af3b52ac2f334c3b1f92262f47e02cc6193c598502bd46f5cd1477"}, - {file = "yarl-1.18.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:90adb47ad432332d4f0bc28f83a5963f426ce9a1a8809f5e584e704b82685dcb"}, - {file = "yarl-1.18.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:913829534200eb0f789d45349e55203a091f45c37a2674678744ae52fae23efa"}, - {file = "yarl-1.18.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ef9f7768395923c3039055c14334ba4d926f3baf7b776c923c93d80195624782"}, - {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a19f62ff30117e706ebc9090b8ecc79aeb77d0b1f5ec10d2d27a12bc9f66d0"}, - {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e17c9361d46a4d5addf777c6dd5eab0715a7684c2f11b88c67ac37edfba6c482"}, - {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a74a13a4c857a84a845505fd2d68e54826a2cd01935a96efb1e9d86c728e186"}, - {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41f7ce59d6ee7741af71d82020346af364949314ed3d87553763a2df1829cc58"}, - {file = "yarl-1.18.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f52a265001d830bc425f82ca9eabda94a64a4d753b07d623a9f2863fde532b53"}, - {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:82123d0c954dc58db301f5021a01854a85bf1f3bb7d12ae0c01afc414a882ca2"}, - {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:2ec9bbba33b2d00999af4631a3397d1fd78290c48e2a3e52d8dd72db3a067ac8"}, - {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fbd6748e8ab9b41171bb95c6142faf068f5ef1511935a0aa07025438dd9a9bc1"}, - {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:877d209b6aebeb5b16c42cbb377f5f94d9e556626b1bfff66d7b0d115be88d0a"}, - {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b464c4ab4bfcb41e3bfd3f1c26600d038376c2de3297760dfe064d2cb7ea8e10"}, - {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8d39d351e7faf01483cc7ff7c0213c412e38e5a340238826be7e0e4da450fdc8"}, - {file = "yarl-1.18.3-cp313-cp313-win32.whl", hash = "sha256:61ee62ead9b68b9123ec24bc866cbef297dd266175d53296e2db5e7f797f902d"}, - {file = "yarl-1.18.3-cp313-cp313-win_amd64.whl", hash = "sha256:578e281c393af575879990861823ef19d66e2b1d0098414855dd367e234f5b3c"}, - {file = "yarl-1.18.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:61e5e68cb65ac8f547f6b5ef933f510134a6bf31bb178be428994b0cb46c2a04"}, - {file = "yarl-1.18.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fe57328fbc1bfd0bd0514470ac692630f3901c0ee39052ae47acd1d90a436719"}, - {file = "yarl-1.18.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a440a2a624683108a1b454705ecd7afc1c3438a08e890a1513d468671d90a04e"}, - {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09c7907c8548bcd6ab860e5f513e727c53b4a714f459b084f6580b49fa1b9cee"}, - {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b4f6450109834af88cb4cc5ecddfc5380ebb9c228695afc11915a0bf82116789"}, - {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9ca04806f3be0ac6d558fffc2fdf8fcef767e0489d2684a21912cc4ed0cd1b8"}, - {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77a6e85b90a7641d2e07184df5557132a337f136250caafc9ccaa4a2a998ca2c"}, - {file = "yarl-1.18.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6333c5a377c8e2f5fae35e7b8f145c617b02c939d04110c76f29ee3676b5f9a5"}, - {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0b3c92fa08759dbf12b3a59579a4096ba9af8dd344d9a813fc7f5070d86bbab1"}, - {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4ac515b860c36becb81bb84b667466885096b5fc85596948548b667da3bf9f24"}, - {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:045b8482ce9483ada4f3f23b3774f4e1bf4f23a2d5c912ed5170f68efb053318"}, - {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:a4bb030cf46a434ec0225bddbebd4b89e6471814ca851abb8696170adb163985"}, - {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:54d6921f07555713b9300bee9c50fb46e57e2e639027089b1d795ecd9f7fa910"}, - {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1d407181cfa6e70077df3377938c08012d18893f9f20e92f7d2f314a437c30b1"}, - {file = "yarl-1.18.3-cp39-cp39-win32.whl", hash = "sha256:ac36703a585e0929b032fbaab0707b75dc12703766d0b53486eabd5139ebadd5"}, - {file = "yarl-1.18.3-cp39-cp39-win_amd64.whl", hash = "sha256:ba87babd629f8af77f557b61e49e7c7cac36f22f871156b91e10a6e9d4f829e9"}, - {file = "yarl-1.18.3-py3-none-any.whl", hash = "sha256:b57f4f58099328dfb26c6a771d09fb20dbbae81d20cfb66141251ea063bd101b"}, - {file = "yarl-1.18.3.tar.gz", hash = "sha256:ac1801c45cbf77b6c99242eeff4fffb5e4e73a800b5c4ad4fc0be5def634d2e1"}, + {file = "yarl-1.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f1f6670b9ae3daedb325fa55fbe31c22c8228f6e0b513772c2e1c623caa6ab22"}, + {file = "yarl-1.20.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:85a231fa250dfa3308f3c7896cc007a47bc76e9e8e8595c20b7426cac4884c62"}, + {file = "yarl-1.20.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a06701b647c9939d7019acdfa7ebbfbb78ba6aa05985bb195ad716ea759a569"}, + {file = "yarl-1.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7595498d085becc8fb9203aa314b136ab0516c7abd97e7d74f7bb4eb95042abe"}, + {file = "yarl-1.20.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:af5607159085dcdb055d5678fc2d34949bd75ae6ea6b4381e784bbab1c3aa195"}, + {file = "yarl-1.20.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:95b50910e496567434cb77a577493c26bce0f31c8a305135f3bda6a2483b8e10"}, + {file = "yarl-1.20.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b594113a301ad537766b4e16a5a6750fcbb1497dcc1bc8a4daae889e6402a634"}, + {file = "yarl-1.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:083ce0393ea173cd37834eb84df15b6853b555d20c52703e21fbababa8c129d2"}, + {file = "yarl-1.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f1a350a652bbbe12f666109fbddfdf049b3ff43696d18c9ab1531fbba1c977a"}, + {file = "yarl-1.20.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:fb0caeac4a164aadce342f1597297ec0ce261ec4532bbc5a9ca8da5622f53867"}, + {file = "yarl-1.20.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d88cc43e923f324203f6ec14434fa33b85c06d18d59c167a0637164863b8e995"}, + {file = "yarl-1.20.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e52d6ed9ea8fd3abf4031325dc714aed5afcbfa19ee4a89898d663c9976eb487"}, + {file = "yarl-1.20.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ce360ae48a5e9961d0c730cf891d40698a82804e85f6e74658fb175207a77cb2"}, + {file = "yarl-1.20.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:06d06c9d5b5bc3eb56542ceeba6658d31f54cf401e8468512447834856fb0e61"}, + {file = "yarl-1.20.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c27d98f4e5c4060582f44e58309c1e55134880558f1add7a87c1bc36ecfade19"}, + {file = "yarl-1.20.0-cp310-cp310-win32.whl", hash = "sha256:f4d3fa9b9f013f7050326e165c3279e22850d02ae544ace285674cb6174b5d6d"}, + {file = "yarl-1.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:bc906b636239631d42eb8a07df8359905da02704a868983265603887ed68c076"}, + {file = "yarl-1.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fdb5204d17cb32b2de2d1e21c7461cabfacf17f3645e4b9039f210c5d3378bf3"}, + {file = "yarl-1.20.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:eaddd7804d8e77d67c28d154ae5fab203163bd0998769569861258e525039d2a"}, + {file = "yarl-1.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:634b7ba6b4a85cf67e9df7c13a7fb2e44fa37b5d34501038d174a63eaac25ee2"}, + {file = "yarl-1.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d409e321e4addf7d97ee84162538c7258e53792eb7c6defd0c33647d754172e"}, + {file = "yarl-1.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ea52f7328a36960ba3231c6677380fa67811b414798a6e071c7085c57b6d20a9"}, + {file = "yarl-1.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c8703517b924463994c344dcdf99a2d5ce9eca2b6882bb640aa555fb5efc706a"}, + {file = "yarl-1.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:077989b09ffd2f48fb2d8f6a86c5fef02f63ffe6b1dd4824c76de7bb01e4f2e2"}, + {file = "yarl-1.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0acfaf1da020253f3533526e8b7dd212838fdc4109959a2c53cafc6db611bff2"}, + {file = "yarl-1.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b4230ac0b97ec5eeb91d96b324d66060a43fd0d2a9b603e3327ed65f084e41f8"}, + {file = "yarl-1.20.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a6a1e6ae21cdd84011c24c78d7a126425148b24d437b5702328e4ba640a8902"}, + {file = "yarl-1.20.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:86de313371ec04dd2531f30bc41a5a1a96f25a02823558ee0f2af0beaa7ca791"}, + {file = "yarl-1.20.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dd59c9dd58ae16eaa0f48c3d0cbe6be8ab4dc7247c3ff7db678edecbaf59327f"}, + {file = "yarl-1.20.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:a0bc5e05f457b7c1994cc29e83b58f540b76234ba6b9648a4971ddc7f6aa52da"}, + {file = "yarl-1.20.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c9471ca18e6aeb0e03276b5e9b27b14a54c052d370a9c0c04a68cefbd1455eb4"}, + {file = "yarl-1.20.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:40ed574b4df723583a26c04b298b283ff171bcc387bc34c2683235e2487a65a5"}, + {file = "yarl-1.20.0-cp311-cp311-win32.whl", hash = "sha256:db243357c6c2bf3cd7e17080034ade668d54ce304d820c2a58514a4e51d0cfd6"}, + {file = "yarl-1.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:8c12cd754d9dbd14204c328915e23b0c361b88f3cffd124129955e60a4fbfcfb"}, + {file = "yarl-1.20.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e06b9f6cdd772f9b665e5ba8161968e11e403774114420737f7884b5bd7bdf6f"}, + {file = "yarl-1.20.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b9ae2fbe54d859b3ade40290f60fe40e7f969d83d482e84d2c31b9bff03e359e"}, + {file = "yarl-1.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6d12b8945250d80c67688602c891237994d203d42427cb14e36d1a732eda480e"}, + {file = "yarl-1.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:087e9731884621b162a3e06dc0d2d626e1542a617f65ba7cc7aeab279d55ad33"}, + {file = "yarl-1.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:69df35468b66c1a6e6556248e6443ef0ec5f11a7a4428cf1f6281f1879220f58"}, + {file = "yarl-1.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b2992fe29002fd0d4cbaea9428b09af9b8686a9024c840b8a2b8f4ea4abc16f"}, + {file = "yarl-1.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4c903e0b42aab48abfbac668b5a9d7b6938e721a6341751331bcd7553de2dcae"}, + {file = "yarl-1.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf099e2432131093cc611623e0b0bcc399b8cddd9a91eded8bfb50402ec35018"}, + {file = "yarl-1.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8a7f62f5dc70a6c763bec9ebf922be52aa22863d9496a9a30124d65b489ea672"}, + {file = "yarl-1.20.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:54ac15a8b60382b2bcefd9a289ee26dc0920cf59b05368c9b2b72450751c6eb8"}, + {file = "yarl-1.20.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:25b3bc0763a7aca16a0f1b5e8ef0f23829df11fb539a1b70476dcab28bd83da7"}, + {file = "yarl-1.20.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b2586e36dc070fc8fad6270f93242124df68b379c3a251af534030a4a33ef594"}, + {file = "yarl-1.20.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:866349da9d8c5290cfefb7fcc47721e94de3f315433613e01b435473be63daa6"}, + {file = "yarl-1.20.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:33bb660b390a0554d41f8ebec5cd4475502d84104b27e9b42f5321c5192bfcd1"}, + {file = "yarl-1.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:737e9f171e5a07031cbee5e9180f6ce21a6c599b9d4b2c24d35df20a52fabf4b"}, + {file = "yarl-1.20.0-cp312-cp312-win32.whl", hash = "sha256:839de4c574169b6598d47ad61534e6981979ca2c820ccb77bf70f4311dd2cc64"}, + {file = "yarl-1.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:3d7dbbe44b443b0c4aa0971cb07dcb2c2060e4a9bf8d1301140a33a93c98e18c"}, + {file = "yarl-1.20.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2137810a20b933b1b1b7e5cf06a64c3ed3b4747b0e5d79c9447c00db0e2f752f"}, + {file = "yarl-1.20.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:447c5eadd750db8389804030d15f43d30435ed47af1313303ed82a62388176d3"}, + {file = "yarl-1.20.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:42fbe577272c203528d402eec8bf4b2d14fd49ecfec92272334270b850e9cd7d"}, + {file = "yarl-1.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18e321617de4ab170226cd15006a565d0fa0d908f11f724a2c9142d6b2812ab0"}, + {file = "yarl-1.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4345f58719825bba29895011e8e3b545e6e00257abb984f9f27fe923afca2501"}, + {file = "yarl-1.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5d9b980d7234614bc4674468ab173ed77d678349c860c3af83b1fffb6a837ddc"}, + {file = "yarl-1.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af4baa8a445977831cbaa91a9a84cc09debb10bc8391f128da2f7bd070fc351d"}, + {file = "yarl-1.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:123393db7420e71d6ce40d24885a9e65eb1edefc7a5228db2d62bcab3386a5c0"}, + {file = "yarl-1.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ab47acc9332f3de1b39e9b702d9c916af7f02656b2a86a474d9db4e53ef8fd7a"}, + {file = "yarl-1.20.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4a34c52ed158f89876cba9c600b2c964dfc1ca52ba7b3ab6deb722d1d8be6df2"}, + {file = "yarl-1.20.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:04d8cfb12714158abf2618f792c77bc5c3d8c5f37353e79509608be4f18705c9"}, + {file = "yarl-1.20.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7dc63ad0d541c38b6ae2255aaa794434293964677d5c1ec5d0116b0e308031f5"}, + {file = "yarl-1.20.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d02b591a64e4e6ca18c5e3d925f11b559c763b950184a64cf47d74d7e41877"}, + {file = "yarl-1.20.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:95fc9876f917cac7f757df80a5dda9de59d423568460fe75d128c813b9af558e"}, + {file = "yarl-1.20.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bb769ae5760cd1c6a712135ee7915f9d43f11d9ef769cb3f75a23e398a92d384"}, + {file = "yarl-1.20.0-cp313-cp313-win32.whl", hash = "sha256:70e0c580a0292c7414a1cead1e076c9786f685c1fc4757573d2967689b370e62"}, + {file = "yarl-1.20.0-cp313-cp313-win_amd64.whl", hash = "sha256:4c43030e4b0af775a85be1fa0433119b1565673266a70bf87ef68a9d5ba3174c"}, + {file = "yarl-1.20.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b6c4c3d0d6a0ae9b281e492b1465c72de433b782e6b5001c8e7249e085b69051"}, + {file = "yarl-1.20.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8681700f4e4df891eafa4f69a439a6e7d480d64e52bf460918f58e443bd3da7d"}, + {file = "yarl-1.20.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:84aeb556cb06c00652dbf87c17838eb6d92cfd317799a8092cee0e570ee11229"}, + {file = "yarl-1.20.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f166eafa78810ddb383e930d62e623d288fb04ec566d1b4790099ae0f31485f1"}, + {file = "yarl-1.20.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5d3d6d14754aefc7a458261027a562f024d4f6b8a798adb472277f675857b1eb"}, + {file = "yarl-1.20.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2a8f64df8ed5d04c51260dbae3cc82e5649834eebea9eadfd829837b8093eb00"}, + {file = "yarl-1.20.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4d9949eaf05b4d30e93e4034a7790634bbb41b8be2d07edd26754f2e38e491de"}, + {file = "yarl-1.20.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c366b254082d21cc4f08f522ac201d0d83a8b8447ab562732931d31d80eb2a5"}, + {file = "yarl-1.20.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91bc450c80a2e9685b10e34e41aef3d44ddf99b3a498717938926d05ca493f6a"}, + {file = "yarl-1.20.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c2aa4387de4bc3a5fe158080757748d16567119bef215bec643716b4fbf53f9"}, + {file = "yarl-1.20.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:d2cbca6760a541189cf87ee54ff891e1d9ea6406079c66341008f7ef6ab61145"}, + {file = "yarl-1.20.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:798a5074e656f06b9fad1a162be5a32da45237ce19d07884d0b67a0aa9d5fdda"}, + {file = "yarl-1.20.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:f106e75c454288472dbe615accef8248c686958c2e7dd3b8d8ee2669770d020f"}, + {file = "yarl-1.20.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:3b60a86551669c23dc5445010534d2c5d8a4e012163218fc9114e857c0586fdd"}, + {file = "yarl-1.20.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:3e429857e341d5e8e15806118e0294f8073ba9c4580637e59ab7b238afca836f"}, + {file = "yarl-1.20.0-cp313-cp313t-win32.whl", hash = "sha256:65a4053580fe88a63e8e4056b427224cd01edfb5f951498bfefca4052f0ce0ac"}, + {file = "yarl-1.20.0-cp313-cp313t-win_amd64.whl", hash = "sha256:53b2da3a6ca0a541c1ae799c349788d480e5144cac47dba0266c7cb6c76151fe"}, + {file = "yarl-1.20.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:119bca25e63a7725b0c9d20ac67ca6d98fa40e5a894bd5d4686010ff73397914"}, + {file = "yarl-1.20.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:35d20fb919546995f1d8c9e41f485febd266f60e55383090010f272aca93edcc"}, + {file = "yarl-1.20.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:484e7a08f72683c0f160270566b4395ea5412b4359772b98659921411d32ad26"}, + {file = "yarl-1.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d8a3d54a090e0fff5837cd3cc305dd8a07d3435a088ddb1f65e33b322f66a94"}, + {file = "yarl-1.20.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:f0cf05ae2d3d87a8c9022f3885ac6dea2b751aefd66a4f200e408a61ae9b7f0d"}, + {file = "yarl-1.20.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a884b8974729e3899d9287df46f015ce53f7282d8d3340fa0ed57536b440621c"}, + {file = "yarl-1.20.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f8d8aa8dd89ffb9a831fedbcb27d00ffd9f4842107d52dc9d57e64cb34073d5c"}, + {file = "yarl-1.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b4e88d6c3c8672f45a30867817e4537df1bbc6f882a91581faf1f6d9f0f1b5a"}, + {file = "yarl-1.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bdb77efde644d6f1ad27be8a5d67c10b7f769804fff7a966ccb1da5a4de4b656"}, + {file = "yarl-1.20.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4ba5e59f14bfe8d261a654278a0f6364feef64a794bd456a8c9e823071e5061c"}, + {file = "yarl-1.20.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:d0bf955b96ea44ad914bc792c26a0edcd71b4668b93cbcd60f5b0aeaaed06c64"}, + {file = "yarl-1.20.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:27359776bc359ee6eaefe40cb19060238f31228799e43ebd3884e9c589e63b20"}, + {file = "yarl-1.20.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:04d9c7a1dc0a26efb33e1acb56c8849bd57a693b85f44774356c92d610369efa"}, + {file = "yarl-1.20.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:faa709b66ae0e24c8e5134033187a972d849d87ed0a12a0366bedcc6b5dc14a5"}, + {file = "yarl-1.20.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:44869ee8538208fe5d9342ed62c11cc6a7a1af1b3d0bb79bb795101b6e77f6e0"}, + {file = "yarl-1.20.0-cp39-cp39-win32.whl", hash = "sha256:b7fa0cb9fd27ffb1211cde944b41f5c67ab1c13a13ebafe470b1e206b8459da8"}, + {file = "yarl-1.20.0-cp39-cp39-win_amd64.whl", hash = "sha256:d4fad6e5189c847820288286732075f213eabf81be4d08d6cc309912e62be5b7"}, + {file = "yarl-1.20.0-py3-none-any.whl", hash = "sha256:5d0fe6af927a47a230f31e6004621fd0959eaa915fc62acfafa67ff7229a3124"}, + {file = "yarl-1.20.0.tar.gz", hash = "sha256:686d51e51ee5dfe62dec86e4866ee0e9ed66df700d55c828a615640adc885307"}, ] [package.dependencies] idna = ">=2.0" multidict = ">=4.0" -propcache = ">=0.2.0" +propcache = ">=0.2.1" [[package]] name = "zipp" diff --git a/tests/test_bridge_bridge.py b/tests/test_bridge_bridge.py new file mode 100644 index 00000000..97a453af --- /dev/null +++ b/tests/test_bridge_bridge.py @@ -0,0 +1,680 @@ +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2024 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ + +"""Tests for bridge.bridge module.""" + + +import os +import time +import typing as t +from functools import cache +from pathlib import Path + +import pytest +import requests +from deepdiff import DeepDiff + +from operate.bridge.providers.bridge_provider import ( + BridgeProvider, + BridgeRequestStatus, + MESSAGE_QUOTE_ZERO, +) +from operate.bridge.providers.lifi_bridge_provider import ( + LIFI_DEFAULT_ETA, + LiFiBridgeProvider, +) +from operate.bridge.providers.native_bridge_provider import ( + BridgeContractAdaptor, + NativeBridgeProvider, + OmnibridgeContractAdaptor, + OptimismContractAdaptor, +) +from operate.cli import OperateApp +from operate.constants import ZERO_ADDRESS +from operate.ledger.profiles import OLAS, USDC +from operate.operate_types import Chain, LedgerType + + +ROOT_PATH = Path(__file__).resolve().parent +OPERATE = ".operate_test" +RUNNING_IN_CI = ( + os.getenv("GITHUB_ACTIONS", "").lower() == "true" + or os.getenv("CI", "").lower() == "true" +) + +COINGECKO_PLATFORM_IDS = { + "ethereum": "ethereum", + "polygon": "polygon-pos", + "arbitrum": "arbitrum-one", + "optimistic": "optimistic-ethereum", + "binance": "binance-smart-chain", + "avalanche": "avalanche", + "fantom": "fantom", + "base": "base", + "mode": "mode", + "gnosis": "xdai", +} + +COINGECKO_NATIVE_IDS = { + "ethereum": "ethereum", + "polygon": "matic-network", + "arbitrum": "ethereum", + "optimistic": "ethereum", + "binance": "binancecoin", + "avalanche": "avalanche-2", + "fantom": "fantom", + "base": "ethereum", + "mode": "ethereum", + "gnosis": "xdai", +} + + +class TestBridgeManager: + """Tests for bridge.bridge.BridgeManager class.""" + + @staticmethod + @cache + def _get_token_price_usd(chain: str, token_address: str) -> t.Optional[float]: + print(f"Calling _get_token_price_usd {chain=} {token_address=}") + chain = chain.lower() + if token_address == ZERO_ADDRESS: + coingecko_id = COINGECKO_NATIVE_IDS.get(chain) + if not coingecko_id: + return None + url = "https://api.coingecko.com/api/v3/simple/price" + print(f"Fetching {url}") + params = {"ids": coingecko_id, "vs_currencies": "usd"} + r = requests.get(url, params=params, timeout=30) + if r.status_code != 200: + return None + data = r.json() + print(r.json()) + return data.get(coingecko_id, {}).get("usd") + + platform_id = COINGECKO_PLATFORM_IDS.get(chain) + if not platform_id: + return None + token_address = token_address.lower() + url = f"https://api.coingecko.com/api/v3/simple/token_price/{platform_id}" + params = {"contract_addresses": token_address, "vs_currencies": "usd"} + print(f"Fetching {url}") + r = requests.get(url, params=params, timeout=30) + if r.status_code != 200: + return None + data = r.json() + print(r.json()) + return data.get(token_address, {}).get("usd") + + def test_bundle_zero( + self, + tmp_path: Path, + password: str, + ) -> None: + """test_bundle""" + + operate = OperateApp( + home=tmp_path / OPERATE, + ) + operate.setup() + operate.create_user_account(password=password) + operate.password = password + operate.wallet_manager.create(ledger_type=LedgerType.ETHEREUM) + bridge_manager = operate.bridge_manager + + wallet_address = operate.wallet_manager.load(LedgerType.ETHEREUM).address + params = [ + { + "from": { + "chain": "gnosis", + "address": wallet_address, + "token": ZERO_ADDRESS, + }, + "to": { + "chain": "base", + "address": wallet_address, + "token": ZERO_ADDRESS, + "amount": 0, # 1_000_000_000_000_000, + }, + }, + { + "from": { + "chain": "gnosis", + "address": wallet_address, + "token": OLAS[Chain.GNOSIS], + }, + "to": { + "chain": "base", + "address": wallet_address, + "token": OLAS[Chain.BASE], + "amount": 0, # 1_000_000_000_000_000_000, + }, + }, + ] + + timestamp1 = time.time() + brr = bridge_manager.bridge_refill_requirements( + requests_params=params, force_update=False + ) + timestamp2 = time.time() + expected_brr = { + "id": brr["id"], + "balances": { + "gnosis": {wallet_address: {ZERO_ADDRESS: 0, OLAS[Chain.GNOSIS]: 0}} + }, + "bridge_refill_requirements": brr["bridge_refill_requirements"], + "bridge_request_status": [ + { + "eta": 0, + "message": MESSAGE_QUOTE_ZERO, + "status": BridgeRequestStatus.QUOTE_DONE.value, + }, + { + "eta": 0, + "message": MESSAGE_QUOTE_ZERO, + "status": BridgeRequestStatus.QUOTE_DONE.value, + }, + ], + "bridge_total_requirements": brr["bridge_total_requirements"], + "expiration_timestamp": brr["expiration_timestamp"], + "is_refill_required": False, + } + + assert ( + brr["balances"]["gnosis"][wallet_address][ZERO_ADDRESS] == 0 + ), "Wrong bridge refill requirements." + assert ( + brr["balances"]["gnosis"][wallet_address][OLAS[Chain.GNOSIS]] == 0 + ), "Wrong bridge refill requirements." + assert ( + brr["bridge_refill_requirements"]["gnosis"][wallet_address][ZERO_ADDRESS] + == 0 + ), "Wrong bridge refill requirements." + assert ( + brr["bridge_refill_requirements"]["gnosis"][wallet_address][ + OLAS[Chain.GNOSIS] + ] + == 0 + ), "Wrong bridge refill requirements." + assert not DeepDiff( + brr["bridge_refill_requirements"], brr["bridge_total_requirements"] + ), "Wrong bridge refill requirements." + assert ( + brr["expiration_timestamp"] >= timestamp1 + ), "Wrong bridge refill requirements." + assert ( + brr["expiration_timestamp"] + <= timestamp2 + bridge_manager.quote_validity_period + ), "Wrong bridge refill requirements." + + diff = DeepDiff(brr, expected_brr) + if diff: + print(diff) + + assert not diff, "Wrong bridge refill requirements." + + def test_bundle_error( + self, + tmp_path: Path, + password: str, + ) -> None: + """test_bundle""" + + operate = OperateApp( + home=tmp_path / OPERATE, + ) + operate.setup() + operate.create_user_account(password=password) + operate.password = password + operate.wallet_manager.create(ledger_type=LedgerType.ETHEREUM) + bridge_manager = operate.bridge_manager + + wallet_address = operate.wallet_manager.load(LedgerType.ETHEREUM).address + params = [ + { + "from": { + "chain": "gnosis", + "address": wallet_address, + "token": ZERO_ADDRESS, + }, + "to": { + "chain": "base", + "address": wallet_address, + "token": ZERO_ADDRESS, + "amount": 1, + }, + }, + { + "from": { + "chain": "gnosis", + "address": wallet_address, + "token": OLAS[Chain.GNOSIS], + }, + "to": { + "chain": "base", + "address": wallet_address, + "token": OLAS[Chain.BASE], + "amount": 0, # 1_000_000_000_000_000_000, + }, + }, + ] + + timestamp1 = time.time() + brr = bridge_manager.bridge_refill_requirements( + requests_params=params, force_update=False + ) + timestamp2 = time.time() + expected_brr = { + "id": brr["id"], + "balances": { + "gnosis": {wallet_address: {ZERO_ADDRESS: 0, OLAS[Chain.GNOSIS]: 0}} + }, + "bridge_refill_requirements": brr["bridge_refill_requirements"], + "bridge_request_status": [ + { + "eta": None, + "message": brr["bridge_request_status"][0]["message"], + "status": BridgeRequestStatus.QUOTE_FAILED.value, + }, + { + "eta": 0, + "message": MESSAGE_QUOTE_ZERO, + "status": BridgeRequestStatus.QUOTE_DONE.value, + }, + ], + "bridge_total_requirements": brr["bridge_total_requirements"], + "expiration_timestamp": brr["expiration_timestamp"], + "is_refill_required": False, + } + + assert ( + brr["balances"]["gnosis"][wallet_address][ZERO_ADDRESS] == 0 + ), "Wrong bridge refill requirements." + assert ( + brr["balances"]["gnosis"][wallet_address][OLAS[Chain.GNOSIS]] == 0 + ), "Wrong bridge refill requirements." + assert ( + brr["bridge_refill_requirements"]["gnosis"][wallet_address][ZERO_ADDRESS] + == 0 + ), "Wrong bridge refill requirements." + assert ( + brr["bridge_refill_requirements"]["gnosis"][wallet_address][ + OLAS[Chain.GNOSIS] + ] + == 0 + ), "Wrong bridge refill requirements." + assert not DeepDiff( + brr["bridge_refill_requirements"], brr["bridge_total_requirements"] + ), "Wrong bridge refill requirements." + assert ( + brr["expiration_timestamp"] >= timestamp1 + ), "Wrong bridge refill requirements." + assert ( + brr["expiration_timestamp"] + <= timestamp2 + bridge_manager.quote_validity_period + ), "Wrong bridge refill requirements." + + diff = DeepDiff(brr, expected_brr) + if diff: + print(diff) + + assert not diff, "Wrong bridge refill requirements." + + @pytest.mark.skipif(RUNNING_IN_CI, reason="Skip test on CI.") + def test_bundle_quote( + self, + tmp_path: Path, + password: str, + ) -> None: + """test_bundle""" + + operate = OperateApp( + home=tmp_path / OPERATE, + ) + operate.setup() + operate.create_user_account(password=password) + operate.password = password + operate.wallet_manager.create(ledger_type=LedgerType.ETHEREUM) + bridge_manager = operate.bridge_manager + + wallet_address = operate.wallet_manager.load(LedgerType.ETHEREUM).address + params = [ + { + "from": { + "chain": "ethereum", + "address": wallet_address, + "token": ZERO_ADDRESS, + }, + "to": { + "chain": "base", + "address": wallet_address, + "token": ZERO_ADDRESS, + "amount": 1_000_000_000_000_000, + }, + }, + { + "from": { + "chain": "ethereum", + "address": wallet_address, + "token": OLAS[Chain.ETHEREUM], + }, + "to": { + "chain": "base", + "address": wallet_address, + "token": OLAS[Chain.BASE], + "amount": 1_000_000_000_000_000_000, + }, + }, + ] + + bundle = bridge_manager.data.last_requested_bundle + assert bundle is None, "Unexpected bundle." + timestamp1 = time.time() + brr = bridge_manager.bridge_refill_requirements( + requests_params=params, force_update=False + ) + timestamp2 = time.time() + + bundle = bridge_manager.data.last_requested_bundle + assert bundle is not None, "Unexpected bundle." + + request = bundle.bridge_requests[0] + bridge = bridge_manager._get_bridge_provider(request) + assert bridge._get_approve_tx(request) is None, "Wrong number of transactions." + assert ( + bridge._get_bridge_tx(request) is not None + ), "Wrong number of transactions." + + request = bundle.bridge_requests[1] + bridge = bridge_manager._get_bridge_provider(request) + assert ( + bridge._get_approve_tx(request) is not None + ), "Wrong number of transactions." + assert ( + bridge._get_approve_tx(request) is not None + ), "Wrong number of transactions." + + expected_brr = { + "id": brr["id"], + "balances": { + "ethereum": {wallet_address: {ZERO_ADDRESS: 0, OLAS[Chain.ETHEREUM]: 0}} + }, + "bridge_refill_requirements": brr["bridge_refill_requirements"], + "bridge_request_status": [ + { + "eta": LIFI_DEFAULT_ETA, + "message": None, + "status": BridgeRequestStatus.QUOTE_DONE.value, + }, + { + "eta": LIFI_DEFAULT_ETA, + "message": None, + "status": BridgeRequestStatus.QUOTE_DONE.value, + }, + ], + "bridge_total_requirements": brr["bridge_total_requirements"], + "expiration_timestamp": brr["expiration_timestamp"], + "is_refill_required": True, + } + + assert ( + brr["balances"]["ethereum"][wallet_address][ZERO_ADDRESS] == 0 + ), "Wrong bridge refill requirements." + assert ( + brr["balances"]["ethereum"][wallet_address][OLAS[Chain.ETHEREUM]] == 0 + ), "Wrong bridge refill requirements." + assert ( + brr["bridge_refill_requirements"]["ethereum"][wallet_address][ZERO_ADDRESS] + > 0 + ), "Wrong bridge refill requirements." + assert ( + brr["bridge_refill_requirements"]["ethereum"][wallet_address][ + OLAS[Chain.ETHEREUM] + ] + > 0 + ), "Wrong bridge refill requirements." + assert not DeepDiff( + brr["bridge_refill_requirements"], brr["bridge_total_requirements"] + ), "Wrong bridge refill requirements." + assert ( + brr["expiration_timestamp"] >= timestamp1 + ), "Wrong bridge refill requirements." + assert ( + brr["expiration_timestamp"] + <= timestamp2 + bridge_manager.quote_validity_period + ), "Wrong bridge refill requirements." + + diff = DeepDiff(brr, expected_brr) + if diff: + print(diff) + + assert not diff, "Wrong bridge refill requirements." + + @pytest.mark.parametrize( + "to_chain_enum", [Chain.BASE, Chain.MODE, Chain.OPTIMISTIC] + ) + def test_correct_providers_bridge_native( + self, + tmp_path: Path, + password: str, + to_chain_enum: Chain, + ) -> None: + """test_correct_providers_bridge_native""" + self._main_test_correct_providers( + tmp_path=tmp_path, + password=password, + from_chain=Chain.ETHEREUM.value, + from_token=ZERO_ADDRESS, + to_chain=to_chain_enum.value, + to_token=ZERO_ADDRESS, + expected_provider_cls=NativeBridgeProvider, + expected_contract_adaptor_cls=OptimismContractAdaptor, + ) + + @pytest.mark.parametrize("to_chain_enum", [Chain.GNOSIS]) + def test_correct_providers_swap_native( + self, + tmp_path: Path, + password: str, + to_chain_enum: Chain, + ) -> None: + """test_correct_providers_swap_native""" + self._main_test_correct_providers( + tmp_path=tmp_path, + password=password, + from_chain=Chain.ETHEREUM.value, + from_token=ZERO_ADDRESS, + to_chain=to_chain_enum.value, + to_token=ZERO_ADDRESS, + expected_provider_cls=LiFiBridgeProvider, + expected_contract_adaptor_cls=None, + ) + + @pytest.mark.parametrize( + "to_chain_enum", [Chain.BASE, Chain.MODE, Chain.OPTIMISTIC, Chain.GNOSIS] + ) + @pytest.mark.parametrize("token_dict", [USDC, OLAS]) + def test_correct_providers_bridge_token( + self, + tmp_path: Path, + password: str, + to_chain_enum: Chain, + token_dict: t.Dict, + ) -> None: + """test_correct_providers_bridge_token""" + expected_provider_cls: type[BridgeProvider] = NativeBridgeProvider + expected_contract_adaptor_cls: type[BridgeContractAdaptor] + if to_chain_enum == Chain.GNOSIS: + expected_contract_adaptor_cls = OmnibridgeContractAdaptor + else: + expected_contract_adaptor_cls = OptimismContractAdaptor + + if to_chain_enum == Chain.BASE and token_dict == USDC: + expected_provider_cls = LiFiBridgeProvider + expected_contract_adaptor_cls = None # type: ignore + + if to_chain_enum == Chain.OPTIMISTIC and token_dict == USDC: + expected_provider_cls = LiFiBridgeProvider + expected_contract_adaptor_cls = None # type: ignore + + self._main_test_correct_providers( + tmp_path=tmp_path, + password=password, + from_chain=Chain.ETHEREUM.value, + from_token=token_dict[Chain.ETHEREUM], + to_chain=to_chain_enum.value, + to_token=token_dict[to_chain_enum], + expected_provider_cls=expected_provider_cls, + expected_contract_adaptor_cls=expected_contract_adaptor_cls, + ) + + @pytest.mark.skipif(RUNNING_IN_CI, reason="Skip test on CI.") + @pytest.mark.parametrize( + "to_chain_enum", [Chain.BASE, Chain.MODE, Chain.OPTIMISTIC, Chain.GNOSIS] + ) + @pytest.mark.parametrize("token_dict", [USDC, OLAS]) + def test_correct_providers_swap_token( + self, + tmp_path: Path, + password: str, + to_chain_enum: Chain, + token_dict: t.Dict, + ) -> None: + """test_correct_providers_swap_token""" + self._main_test_correct_providers( + tmp_path=tmp_path, + password=password, + from_chain=Chain.ETHEREUM.value, + from_token=ZERO_ADDRESS, + to_chain=to_chain_enum.value, + to_token=token_dict[to_chain_enum], + expected_provider_cls=LiFiBridgeProvider, + expected_contract_adaptor_cls=None, + ) + + def _main_test_correct_providers( + self, + tmp_path: Path, + password: str, + from_chain: str, + from_token: str, + to_chain: str, + to_token: str, + expected_provider_cls: t.Type[BridgeProvider], + expected_contract_adaptor_cls: t.Optional[t.Type[BridgeContractAdaptor]], + check_price: bool = True, + margin: float = 0.15, + ) -> None: + """_main_test_correct_providers""" + operate = OperateApp( + home=tmp_path / OPERATE, + ) + operate.setup() + operate.create_user_account(password=password) + operate.password = password + operate.wallet_manager.create(ledger_type=LedgerType.ETHEREUM) + bridge_manager = operate.bridge_manager + + wallet_address = operate.wallet_manager.load(LedgerType.ETHEREUM).address + + amount_unit = 100 + if to_token in USDC.values(): + to_decimals = 6 + else: + to_decimals = 18 + + if from_token in USDC.values(): + from_decimals = 6 + else: + from_decimals = 18 + + params = [ + { + "from": { + "chain": from_chain, + "address": wallet_address, + "token": from_token, + }, + "to": { + "chain": to_chain, + "address": wallet_address, + "token": to_token, + "amount": amount_unit * (10**to_decimals), + }, + }, + ] + + bundle = bridge_manager.data.last_requested_bundle + assert bundle is None, "Wrong bundle." + refill_requirements = bridge_manager.bridge_refill_requirements( + requests_params=params, force_update=False + ) + + for request_status in refill_requirements["bridge_request_status"]: + assert ( + request_status["status"] == BridgeRequestStatus.QUOTE_DONE + ), f"Wrong bundle for params\n{params}" + + bundle = bridge_manager.data.last_requested_bundle + assert bundle is not None, "Wrong bundle." + assert len(bundle.bridge_requests) == 1, "Wrong bundle." + bridge_request = bundle.bridge_requests[0] + bridge = bridge_manager._get_bridge_provider(bridge_request) + + assert isinstance( + bridge, expected_provider_cls + ), f"Expected provider {expected_provider_cls}, got {type(bridge)}" + + if isinstance(bridge, NativeBridgeProvider): + assert expected_contract_adaptor_cls is not None, "Wrong contract adaptor." + assert isinstance( + bridge.bridge_contract_adaptor, expected_contract_adaptor_cls + ), f"Expected adaptor {expected_contract_adaptor_cls}, got {type(bridge.bridge_contract_adaptor)}" + + if check_price: + to_price_usd = self._get_token_price_usd(to_chain, to_token) + from_price_usd = self._get_token_price_usd(from_chain, from_token) + print(f"{to_price_usd=}") + print(f"{from_price_usd=}") + + if to_price_usd is None or from_price_usd is None: + pytest.skip("Token price could not be retrieved; skipping price check.") + return + + refill_amount = refill_requirements["bridge_total_requirements"][ + from_chain + ][wallet_address][from_token] + + print(f"{refill_amount=}") + + quoted_from_cost_usd = ( + refill_amount * from_price_usd / (10**from_decimals) + ) + expected_to_cost_usd = amount_unit * to_price_usd + print(f"Expected cost on {to_chain}: {expected_to_cost_usd}") + print(f"Quoted cost on {from_chain}: {quoted_from_cost_usd}") + + overpaid_usd = max(quoted_from_cost_usd - expected_to_cost_usd, 0) + overpaid_percent = (overpaid_usd / expected_to_cost_usd) * 100 + print( + f"Overpaid {overpaid_usd:.2f} USD ({overpaid_percent:.2f}% < {margin*100:.2f}%)" + ) + + assert quoted_from_cost_usd <= expected_to_cost_usd * ( + 1.0 + margin + ), f"Quoted cost exceeds {margin*100:.2f}% margin" diff --git a/tests/test_bridge_providers.py b/tests/test_bridge_providers.py new file mode 100644 index 00000000..ffb81fcf --- /dev/null +++ b/tests/test_bridge_providers.py @@ -0,0 +1,1141 @@ +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------------ +# +# Copyright 2024 Valory AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ------------------------------------------------------------------------------ + +"""Tests for bridge.providers.* module.""" + + +import os +import time +import typing as t +from pathlib import Path + +import pytest +from deepdiff import DeepDiff +from web3 import Web3 + +from operate.bridge.bridge import ( # MESSAGE_EXECUTION_SKIPPED,; MESSAGE_QUOTE_ZERO, + BridgeRequest, + LiFiBridgeProvider, + NATIVE_BRIDGE_CONFIGS, +) +from operate.bridge.providers.bridge_provider import ( + BridgeProvider, + BridgeRequestStatus, + ExecutionData, + MESSAGE_EXECUTION_FAILED, + MESSAGE_EXECUTION_FAILED_QUOTE_FAILED, + MESSAGE_EXECUTION_SKIPPED, + MESSAGE_QUOTE_ZERO, + QuoteData, +) +from operate.bridge.providers.lifi_bridge_provider import LIFI_DEFAULT_ETA +from operate.bridge.providers.native_bridge_provider import ( + BridgeContractAdaptor, + NativeBridgeProvider, + OmnibridgeContractAdaptor, + OptimismContractAdaptor, +) +from operate.cli import OperateApp +from operate.constants import ZERO_ADDRESS +from operate.ledger import DEFAULT_RPCS +from operate.ledger.profiles import OLAS +from operate.operate_types import Chain, LedgerType + + +ROOT_PATH = Path(__file__).resolve().parent +OPERATE = ".operate_test" +RUNNING_IN_CI = ( + os.getenv("GITHUB_ACTIONS", "").lower() == "true" + or os.getenv("CI", "").lower() == "true" +) + + +class TestLiFiBridge: + """Tests for bridge.providers.LiFiBridgeProvider class.""" + + def test_bridge_zero( + self, + tmp_path: Path, + password: str, + ) -> None: + """test_bridge_zero""" + operate = OperateApp( + home=tmp_path / OPERATE, + ) + operate.setup() + operate.create_user_account(password=password) + operate.password = password + operate.wallet_manager.create(ledger_type=LedgerType.ETHEREUM) + + wallet_address = operate.wallet_manager.load(LedgerType.ETHEREUM).address + params = { + "from": { + "chain": "gnosis", + "address": wallet_address, + "token": OLAS[Chain.GNOSIS], + }, + "to": { + "chain": "base", + "address": wallet_address, + "token": OLAS[Chain.BASE], + "amount": 0, + }, + } + + bridge = LiFiBridgeProvider( + provider_id="LiFiBridgeProvider", wallet_manager=operate.wallet_manager + ) + bridge_request = BridgeRequest( + params=params, + id="test-id", + bridge_provider_id=bridge.provider_id, + quote_data=None, + execution_data=None, + status=BridgeRequestStatus.CREATED, + ) + + assert not bridge_request.quote_data, "Unexpected quote data." + + with pytest.raises(RuntimeError): + bridge.execute(bridge_request) + + status1 = bridge_request.status + bridge._update_execution_status(bridge_request) + status2 = bridge_request.status + assert status1 == BridgeRequestStatus.CREATED, "Wrong status." + assert status2 == BridgeRequestStatus.CREATED, "Wrong status." + + for _ in range(2): + timestamp = int(time.time()) + bridge.quote(bridge_request=bridge_request) + qd = bridge_request.quote_data + assert qd is not None, "Missing quote data." + assert qd.bridge_eta == 0, "Wrong quote data." + assert qd.elapsed_time == 0, "Wrong quote data." + assert qd.message == MESSAGE_QUOTE_ZERO, "Wrong quote data." + assert qd.provider_data is None, "Wrong quote data." + assert timestamp <= qd.timestamp, "Wrong quote data." + assert qd.timestamp <= int(time.time()), "Wrong quote data." + assert ( + bridge_request.status == BridgeRequestStatus.QUOTE_DONE + ), "Wrong status." + + sj = bridge.status_json(bridge_request) + expected_sj = { + "eta": 0, + "message": MESSAGE_QUOTE_ZERO, + "status": BridgeRequestStatus.QUOTE_DONE.value, + } + diff = DeepDiff(sj, expected_sj) + if diff: + print(diff) + + assert not diff, "Wrong status." + assert bridge_request.quote_data is not None, "Missing quote data." + + br = bridge.bridge_requirements(bridge_request) + expected_br = { + "gnosis": {wallet_address: {ZERO_ADDRESS: 0, OLAS[Chain.GNOSIS]: 0}} + } + diff = DeepDiff(br, expected_br) + if diff: + print(diff) + + assert not diff, "Wrong bridge requirements." + + qd = bridge_request.quote_data + assert qd is not None, "Missing quote data." + assert qd.bridge_eta == 0, "Wrong quote data." + assert qd.elapsed_time == 0, "Wrong quote data." + assert qd.message == MESSAGE_QUOTE_ZERO, "Wrong quote data." + assert qd.provider_data is None, "Wrong quote data." + assert qd.timestamp <= int(time.time()), "Wrong quote data." + assert bridge_request.status == BridgeRequestStatus.QUOTE_DONE, "Wrong status." + + status1 = bridge_request.status + bridge._update_execution_status(bridge_request) + status2 = bridge_request.status + assert status1 == BridgeRequestStatus.QUOTE_DONE, "Wrong status." + assert status2 == BridgeRequestStatus.QUOTE_DONE, "Wrong status." + + timestamp = int(time.time()) + bridge.execute(bridge_request=bridge_request) + ed = bridge_request.execution_data + assert ed is not None, "Missing execution data." + assert ed.elapsed_time == 0, "Wrong execution data." + assert ed.message is not None, "Wrong execution data." + assert MESSAGE_EXECUTION_SKIPPED in ed.message, "Wrong execution data." + assert timestamp <= ed.timestamp, "Wrong quote data." + assert ed.timestamp <= int(time.time()), "Wrong quote data." + assert ed.from_tx_hash is None, "Wrong execution data." + assert ( + bridge_request.status == BridgeRequestStatus.EXECUTION_DONE + ), "Wrong status." + + bridge._update_execution_status(bridge_request) + assert ( + bridge_request.status == BridgeRequestStatus.EXECUTION_DONE + ), "Wrong status." + + sj = bridge.status_json(bridge_request) + assert MESSAGE_EXECUTION_SKIPPED in sj["message"], "Wrong execution data." + expected_sj = { + "eta": 0, + "explorer_link": sj["explorer_link"], + "tx_hash": None, # type: ignore + "message": sj["message"], + "status": BridgeRequestStatus.EXECUTION_DONE.value, + } + diff = DeepDiff(sj, expected_sj) + if diff: + print(diff) + + assert not diff, "Wrong status." + + def test_bridge_error( + self, + tmp_path: Path, + password: str, + ) -> None: + """test_bridge_error""" + operate = OperateApp( + home=tmp_path / OPERATE, + ) + operate.setup() + operate.create_user_account(password=password) + operate.password = password + operate.wallet_manager.create(ledger_type=LedgerType.ETHEREUM) + + wallet_address = operate.wallet_manager.load(LedgerType.ETHEREUM).address + params = { + "from": { + "chain": "gnosis", + "address": wallet_address, + "token": OLAS[Chain.GNOSIS], + }, + "to": { + "chain": "base", + "address": wallet_address, + "token": OLAS[Chain.BASE], + "amount": 1, # This will cause a quote error + }, + } + + bridge = LiFiBridgeProvider( + provider_id="LiFiBridgeProvider", wallet_manager=operate.wallet_manager + ) + bridge_request = BridgeRequest( + params=params, + id="test-id", + bridge_provider_id=bridge.provider_id, + quote_data=None, + execution_data=None, + status=BridgeRequestStatus.CREATED, + ) + + assert not bridge_request.quote_data, "Unexpected quote data." + + with pytest.raises(RuntimeError): + bridge.execute(bridge_request) + + status1 = bridge_request.status + bridge._update_execution_status(bridge_request) + status2 = bridge_request.status + assert status1 == BridgeRequestStatus.CREATED, "Wrong status." + assert status2 == BridgeRequestStatus.CREATED, "Wrong status." + + for _ in range(2): + timestamp = int(time.time()) + bridge.quote(bridge_request=bridge_request) + qd = bridge_request.quote_data + assert qd is not None, "Missing quote data." + assert qd.bridge_eta is None, "Wrong quote data." + assert qd.elapsed_time > 0, "Wrong quote data." + assert qd.message is not None, "Wrong quote data." + assert qd.provider_data is not None, "Wrong quote data." + assert qd.provider_data.get("response") is not None, "Wrong quote data." + assert qd.provider_data.get("attempts", 0) > 0, "Wrong quote data." + assert timestamp <= qd.timestamp, "Wrong quote data." + assert qd.timestamp <= int(time.time()), "Wrong quote data." + assert ( + bridge_request.status == BridgeRequestStatus.QUOTE_FAILED + ), "Wrong status." + + assert bridge_request.quote_data is not None, "Wrong quote data." + sj = bridge.status_json(bridge_request) + expected_sj = { + "eta": None, + "message": bridge_request.quote_data.message, + "status": BridgeRequestStatus.QUOTE_FAILED.value, + } + diff = DeepDiff(sj, expected_sj) + if diff: + print(diff) + + assert not diff, "Wrong status." + + br = bridge.bridge_requirements(bridge_request) + expected_br = { + "gnosis": {wallet_address: {ZERO_ADDRESS: 0, OLAS[Chain.GNOSIS]: 0}} + } + diff = DeepDiff(br, expected_br) + if diff: + print(diff) + + assert not diff, "Wrong bridge requirements." + + qd = bridge_request.quote_data + assert qd is not None, "Missing quote data." + assert qd.bridge_eta is None, "Wrong quote data." + assert qd.elapsed_time > 0, "Wrong quote data." + assert qd.message is not None, "Wrong quote data." + assert qd.provider_data is not None, "Wrong quote data." + assert qd.provider_data.get("response") is not None, "Wrong quote data." + assert qd.provider_data.get("attempts", 0) > 0, "Wrong quote data." + assert qd.timestamp <= int(time.time()), "Wrong quote data." + assert ( + bridge_request.status == BridgeRequestStatus.QUOTE_FAILED + ), "Wrong status." + + status1 = bridge_request.status + bridge._update_execution_status(bridge_request) + status2 = bridge_request.status + assert status1 == BridgeRequestStatus.QUOTE_FAILED, "Wrong status." + assert status2 == BridgeRequestStatus.QUOTE_FAILED, "Wrong status." + + timestamp = int(time.time()) + bridge.execute(bridge_request=bridge_request) + ed = bridge_request.execution_data + assert ed is not None, "Missing execution data." + assert ed.elapsed_time == 0, "Wrong execution data." + assert ed.message is not None, "Wrong execution data." + assert ( + MESSAGE_EXECUTION_FAILED_QUOTE_FAILED in ed.message + ), "Wrong execution data." + assert timestamp <= ed.timestamp, "Wrong quote data." + assert ed.timestamp <= int(time.time()), "Wrong quote data." + assert ed.from_tx_hash is None, "Wrong execution data." + assert ( + bridge_request.status == BridgeRequestStatus.EXECUTION_FAILED + ), "Wrong status." + + bridge._update_execution_status(bridge_request) + assert ( + bridge_request.status == BridgeRequestStatus.EXECUTION_FAILED + ), "Wrong status." + + sj = bridge.status_json(bridge_request) + assert ( + MESSAGE_EXECUTION_FAILED_QUOTE_FAILED in sj["message"] + ), "Wrong execution data." + expected_sj = { + "eta": None, + "explorer_link": None, + "tx_hash": None, + "message": sj["message"], + "status": BridgeRequestStatus.EXECUTION_FAILED.value, + } + diff = DeepDiff(sj, expected_sj) + if diff: + print(diff) + + assert not diff, "Wrong status." + + @pytest.mark.skipif(RUNNING_IN_CI, reason="Skip test on CI.") + def test_bridge_quote( + self, + tmp_path: Path, + password: str, + ) -> None: + """test_bridge_quote""" + operate = OperateApp( + home=tmp_path / OPERATE, + ) + operate.setup() + operate.create_user_account(password=password) + operate.password = password + operate.wallet_manager.create(ledger_type=LedgerType.ETHEREUM) + + wallet_address = operate.wallet_manager.load(LedgerType.ETHEREUM).address + params = { + "from": { + "chain": Chain.ETHEREUM.value, + "address": wallet_address, + "token": ZERO_ADDRESS, + }, + "to": { + "chain": "base", + "address": wallet_address, + "token": OLAS[Chain.BASE], + "amount": 1_000_000_000_000_000_000, + }, + } + + bridge = LiFiBridgeProvider( + provider_id="LiFiBridgeProvider", wallet_manager=operate.wallet_manager + ) + bridge_request = BridgeRequest( + params=params, + id="test-id", + bridge_provider_id=bridge.provider_id, + quote_data=None, + execution_data=None, + status=BridgeRequestStatus.CREATED, + ) + + assert not bridge_request.quote_data, "Unexpected quote data." + + with pytest.raises(RuntimeError): + bridge.execute(bridge_request) + + status1 = bridge_request.status + bridge._update_execution_status(bridge_request) + status2 = bridge_request.status + assert status1 == BridgeRequestStatus.CREATED, "Wrong status." + assert status2 == BridgeRequestStatus.CREATED, "Wrong status." + + for _ in range(2): + timestamp = int(time.time()) + bridge.quote(bridge_request=bridge_request) + qd = bridge_request.quote_data + assert qd is not None, "Missing quote data." + assert qd.bridge_eta == LIFI_DEFAULT_ETA, "Wrong quote data." + assert qd.elapsed_time > 0, "Wrong quote data." + assert qd.message is None, "Wrong quote data." + assert qd.provider_data is not None, "Wrong quote data." + assert qd.provider_data.get("response") is not None, "Wrong quote data." + assert qd.provider_data.get("attempts", 0) > 0, "Wrong quote data." + assert timestamp <= qd.timestamp, "Wrong quote data." + assert qd.timestamp <= int(time.time()), "Wrong quote data." + assert ( + bridge_request.status == BridgeRequestStatus.QUOTE_DONE + ), "Wrong status." + + assert bridge_request.quote_data is not None, "Wrong quote data." + sj = bridge.status_json(bridge_request) + expected_sj = { + "eta": LIFI_DEFAULT_ETA, + "message": bridge_request.quote_data.message, + "status": BridgeRequestStatus.QUOTE_DONE.value, + } + diff = DeepDiff(sj, expected_sj) + if diff: + print(diff) + + assert not diff, "Wrong status." + assert ( + bridge_request.quote_data.provider_data is not None + ), "Missing quote data." + + br = bridge.bridge_requirements(bridge_request) + expected_br = { + "ethereum": { + wallet_address: { + ZERO_ADDRESS: br["ethereum"][wallet_address][ZERO_ADDRESS], + } + } + } + diff = DeepDiff(br, expected_br) + if diff: + print(diff) + + assert not diff, "Wrong bridge requirements." + + qd = bridge_request.quote_data + assert qd is not None, "Missing quote data." + assert qd.bridge_eta == LIFI_DEFAULT_ETA, "Wrong quote data." + assert qd.elapsed_time > 0, "Wrong quote data." + assert qd.message is None, "Wrong quote data." + assert qd.provider_data is not None, "Wrong quote data." + assert qd.provider_data.get("response") is not None, "Wrong quote data." + assert qd.provider_data.get("attempts", 0) > 0, "Wrong quote data." + assert qd.timestamp <= int(time.time()), "Wrong quote data." + assert bridge_request.status == BridgeRequestStatus.QUOTE_DONE, "Wrong status." + + status1 = bridge_request.status + bridge._update_execution_status(bridge_request) + status2 = bridge_request.status + assert status1 == BridgeRequestStatus.QUOTE_DONE, "Wrong status." + assert status2 == BridgeRequestStatus.QUOTE_DONE, "Wrong status." + + +class TestNativeBridge: + """Tests for bridge.providers.NativeBridgeProvider class.""" + + def test_bridge_zero( + self, + tmp_path: Path, + password: str, + ) -> None: + """test_bridge_zero""" + operate = OperateApp( + home=tmp_path / OPERATE, + ) + operate.setup() + operate.create_user_account(password=password) + operate.password = password + operate.wallet_manager.create(ledger_type=LedgerType.ETHEREUM) + + wallet_address = operate.wallet_manager.load(LedgerType.ETHEREUM).address + params = { + "from": { + "chain": Chain.ETHEREUM.value, + "address": wallet_address, + "token": OLAS[Chain.ETHEREUM], + }, + "to": { + "chain": Chain.BASE.value, + "address": wallet_address, + "token": OLAS[Chain.BASE], + "amount": "0", + }, + } + + bridge_key = "native-ethereum-to-base" + bridge = NativeBridgeProvider( + provider_id="NativeBridgeProvider", + bridge_contract_adaptor=OptimismContractAdaptor( + from_chain=NATIVE_BRIDGE_CONFIGS[bridge_key]["from_chain"], + from_bridge=NATIVE_BRIDGE_CONFIGS[bridge_key]["from_bridge"], + to_chain=NATIVE_BRIDGE_CONFIGS[bridge_key]["to_chain"], + to_bridge=NATIVE_BRIDGE_CONFIGS[bridge_key]["to_bridge"], + bridge_eta=NATIVE_BRIDGE_CONFIGS[bridge_key]["bridge_eta"], + ), + wallet_manager=operate.wallet_manager, + ) + + # Create + bridge_request = bridge.create_request(params) + expected_request = BridgeRequest( + params={ + "from": { + "chain": Chain.ETHEREUM.value, + "address": wallet_address, + "token": OLAS[Chain.ETHEREUM], + }, + "to": { + "chain": Chain.BASE.value, + "address": wallet_address, + "token": OLAS[Chain.BASE], + "amount": 0, + }, + }, + bridge_provider_id=bridge.provider_id, + id=bridge_request.id, + status=BridgeRequestStatus.CREATED, + quote_data=None, + execution_data=None, + ) + + assert bridge_request == expected_request, "Wrong bridge request." + + with pytest.raises(RuntimeError): + bridge.execute(bridge_request) + + assert bridge_request == expected_request, "Wrong bridge request." + + bridge._update_execution_status(bridge_request) + + assert bridge_request == expected_request, "Wrong bridge request." + + # Quote + expected_quote_data = QuoteData( + bridge_eta=0, + elapsed_time=0, + message=MESSAGE_QUOTE_ZERO, + provider_data=None, + timestamp=int(time.time()), + ) + expected_request.quote_data = expected_quote_data + expected_request.status = BridgeRequestStatus.QUOTE_DONE + + for _ in range(2): + bridge.quote(bridge_request=bridge_request) + assert bridge_request.quote_data is not None, "Wrong bridge request." + expected_quote_data.timestamp = bridge_request.quote_data.timestamp + assert bridge_request == expected_request, "Wrong bridge request." + sj = bridge.status_json(bridge_request) + expected_sj = { + "eta": 0, + "message": MESSAGE_QUOTE_ZERO, + "status": BridgeRequestStatus.QUOTE_DONE.value, + } + diff = DeepDiff(sj, expected_sj) + if diff: + print(diff) + + assert not diff, "Wrong status." + assert bridge_request == expected_request, "Wrong bridge request." + + # Get requirements + br = bridge.bridge_requirements(bridge_request) + expected_br = { + "ethereum": {wallet_address: {ZERO_ADDRESS: 0, OLAS[Chain.ETHEREUM]: 0}} + } + diff = DeepDiff(br, expected_br) + if diff: + print(diff) + + assert not diff, "Wrong bridge requirements." + assert bridge_request == expected_request, "Wrong bridge request." + + # Execute + expected_execution_data = ExecutionData( + elapsed_time=0, + message=f"{MESSAGE_EXECUTION_SKIPPED} (bridge_request.status=)", + timestamp=0, + from_tx_hash=None, + to_tx_hash=None, + provider_data=None, + ) + expected_request.execution_data = expected_execution_data + expected_request.status = BridgeRequestStatus.EXECUTION_DONE + + bridge.execute(bridge_request=bridge_request) + assert bridge_request.execution_data is not None, "Wrong bridge request." + expected_execution_data.timestamp = bridge_request.execution_data.timestamp + + assert bridge_request == expected_request, "Wrong bridge request." + sj = bridge.status_json(bridge_request) + assert MESSAGE_EXECUTION_SKIPPED in sj["message"], "Wrong execution data." + expected_sj = { + "eta": 0, + "explorer_link": None, + "tx_hash": None, # type: ignore + "message": sj["message"], + "status": BridgeRequestStatus.EXECUTION_DONE.value, + } + diff = DeepDiff(sj, expected_sj) + if diff: + print(diff) + + assert not diff, "Wrong status." + assert bridge_request == expected_request, "Wrong bridge request." + + def test_bridge_execute_error( + self, + tmp_path: Path, + password: str, + ) -> None: + """test_bridge_execute_error""" + + DEFAULT_RPCS[Chain.ETHEREUM] = "https://rpc-gate.autonolas.tech/ethereum-rpc/" + DEFAULT_RPCS[Chain.BASE] = "https://rpc-gate.autonolas.tech/base-rpc/" + + operate = OperateApp( + home=tmp_path / OPERATE, + ) + operate.setup() + operate.create_user_account(password=password) + operate.password = password + operate.wallet_manager.create(ledger_type=LedgerType.ETHEREUM) + + wallet_address = operate.wallet_manager.load(LedgerType.ETHEREUM).address + params = { + "from": { + "chain": Chain.ETHEREUM.value, + "address": wallet_address, + "token": OLAS[Chain.ETHEREUM], + }, + "to": { + "chain": Chain.BASE.value, + "address": wallet_address, + "token": OLAS[Chain.BASE], + "amount": "1000000000000000000", + }, + } + + bridge_key = "native-ethereum-to-base" + bridge = NativeBridgeProvider( + provider_id="NativeBridgeProvider", + bridge_contract_adaptor=OptimismContractAdaptor( + from_chain=NATIVE_BRIDGE_CONFIGS[bridge_key]["from_chain"], + from_bridge=NATIVE_BRIDGE_CONFIGS[bridge_key]["from_bridge"], + to_chain=NATIVE_BRIDGE_CONFIGS[bridge_key]["to_chain"], + to_bridge=NATIVE_BRIDGE_CONFIGS[bridge_key]["to_bridge"], + bridge_eta=NATIVE_BRIDGE_CONFIGS[bridge_key]["bridge_eta"], + ), + wallet_manager=operate.wallet_manager, + ) + + # Create + bridge_request = bridge.create_request(params) + expected_request = BridgeRequest( + params={ + "from": { + "chain": Chain.ETHEREUM.value, + "address": wallet_address, + "token": OLAS[Chain.ETHEREUM], + }, + "to": { + "chain": Chain.BASE.value, + "address": wallet_address, + "token": OLAS[Chain.BASE], + "amount": 1000000000000000000, + }, + }, + id=bridge_request.id, + bridge_provider_id=bridge.provider_id, + status=BridgeRequestStatus.CREATED, + quote_data=None, + execution_data=None, + ) + + assert bridge_request == expected_request, "Wrong bridge request." + + with pytest.raises(RuntimeError): + bridge.execute(bridge_request) + + assert bridge_request == expected_request, "Wrong bridge request." + + bridge._update_execution_status(bridge_request) + + assert bridge_request == expected_request, "Wrong bridge request." + + # Quote + expected_quote_data = QuoteData( + bridge_eta=bridge.bridge_contract_adaptor.bridge_eta, + elapsed_time=0, + message=None, + provider_data=None, + timestamp=int(time.time()), + ) + expected_request.quote_data = expected_quote_data + expected_request.status = BridgeRequestStatus.QUOTE_DONE + + for _ in range(2): + bridge.quote(bridge_request=bridge_request) + assert bridge_request.quote_data is not None, "Wrong bridge request." + expected_quote_data.timestamp = bridge_request.quote_data.timestamp + assert bridge_request == expected_request, "Wrong bridge request." + sj = bridge.status_json(bridge_request) + expected_sj = { + "eta": bridge.bridge_contract_adaptor.bridge_eta, + "message": None, + "status": BridgeRequestStatus.QUOTE_DONE.value, + } + diff = DeepDiff(sj, expected_sj) + if diff: + print(diff) + + assert not diff, "Wrong status." + assert bridge_request == expected_request, "Wrong bridge request." + + # Get requirements + br = bridge.bridge_requirements(bridge_request) + assert ( + br["ethereum"][wallet_address][ZERO_ADDRESS] > 0 + ), "Wrong bridge requirements." + expected_br = { + "ethereum": { + wallet_address: { + ZERO_ADDRESS: br["ethereum"][wallet_address][ZERO_ADDRESS], + OLAS[Chain.ETHEREUM]: 1000000000000000000, + } + } + } + diff = DeepDiff(br, expected_br) + if diff: + print(diff) + + assert not diff, "Wrong bridge requirements." + assert bridge_request == expected_request, "Wrong bridge request." + + # Execute + expected_execution_data = ExecutionData( + elapsed_time=0, + message=None, + timestamp=0, + from_tx_hash=None, + to_tx_hash=None, + provider_data=None, + ) + expected_request.execution_data = expected_execution_data + expected_request.status = BridgeRequestStatus.EXECUTION_FAILED + + bridge.execute(bridge_request=bridge_request) + assert bridge_request.execution_data is not None, "Wrong bridge request." + expected_execution_data.message = bridge_request.execution_data.message + expected_execution_data.elapsed_time = ( + bridge_request.execution_data.elapsed_time + ) + expected_execution_data.timestamp = bridge_request.execution_data.timestamp + + assert bridge_request == expected_request, "Wrong bridge request." + sj = bridge.status_json(bridge_request) + assert MESSAGE_EXECUTION_FAILED in sj["message"], "Wrong execution data." + expected_sj = { + "eta": bridge.bridge_contract_adaptor.bridge_eta, + "explorer_link": sj["explorer_link"], + "tx_hash": None, # type: ignore + "message": sj["message"], + "status": BridgeRequestStatus.EXECUTION_FAILED.value, + } + diff = DeepDiff(sj, expected_sj) + if diff: + print(diff) + + assert not diff, "Wrong status." + assert bridge_request == expected_request, "Wrong bridge request." + + @pytest.mark.parametrize("rpc", ["https://rpc-gate.autonolas.tech/base-rpc/"]) + @pytest.mark.parametrize( + ("timestamp", "expected_block"), + [ + (1706789346, 9999999), + (1706789347, 9999999), # timestamp block 10000000 + (1706789348, 10000000), + (1706789349, 10000000), # timestamp block 10000001 + (1706789350, 10000001), + (0, 0), + (1686789346, 0), + (1686789347, 0), # timestamp block 0 + (1686789348, 0), + (1686789349, 0), # timestamp block 1 + (1686789350, 1), + ], + ) + def test_find_block_before_timestamp( + self, + rpc: str, + timestamp: int, + expected_block: int, + ) -> None: + """test_find_block_before_timestamp""" + w3 = Web3(Web3.HTTPProvider(rpc)) + block = NativeBridgeProvider._find_block_before_timestamp(w3, timestamp) + assert block == expected_block, f"Expected block {expected_block}, got {block}." + + +class TestBridgeProvider: + """Tests for bridge.providers.BridgeProvider class.""" + + @pytest.mark.parametrize( + ( + "bridge_provider_class", + "contract_adaptor_class", + "params", + "request_id", + "from_tx_hash", + "expected_status", + "expected_to_tx_hash", + "expected_elapsed_time", + ), + [ + # NativeBridgeProvider (Omnibridge) - EXECUTION_DONE tests + ( + NativeBridgeProvider, + OmnibridgeContractAdaptor, + { + "from": { + "chain": "ethereum", + "address": "0x308508F09F81A6d28679db6da73359c72f8e22C5", + "token": "0x0001A500A6B18995B03f44bb040A5fFc28E45CB0", + }, + "to": { + "chain": "gnosis", + "address": "0x308508F09F81A6d28679db6da73359c72f8e22C5", + "token": "0xcE11e14225575945b8E6Dc0D4F2dD4C570f79d9f", + "amount": 1000000000000000000, + }, + }, + "b-b5648bc4-15c0-4792-9970-cc692851ce50", + "0x8b7646a46e06b3fd4f61f592f6da0f66b5f29a71b13cfce4ce8a8dd2095b7827", + BridgeRequestStatus.EXECUTION_DONE, + "0xc8905a2193d86a58bb92f2bbe3640ef340aacfe4273efc50ad80115f3ed20206", + 2195, + ), + # LiFiBridgeProvider - EXECUTION_DONE tests + ( + LiFiBridgeProvider, + None, + { + "from": { + "chain": "gnosis", + "address": "0xE95866Fa91ce81109aA900550133654A4795C20e", + "token": "0x0000000000000000000000000000000000000000", + }, + "to": { + "chain": "base", + "address": "0xE95866Fa91ce81109aA900550133654A4795C20e", + "token": "0x0000000000000000000000000000000000000000", + "amount": 10000000000000, + }, + }, + "b-184035d4-18b4-42e1-8983-d30f7daff1b9", + "0x333f5a51163576c9d90599bffa6b038dbec45f4f6f761b87e29ab59235403861", + BridgeRequestStatus.EXECUTION_DONE, + "0x6cd9176f1da953e4464adb8bdc81fbe4133ebcd1bb6aeac49946a38ff025e623", + 374, + ), + # NativeBridgeProvider (Optimism bridge) - EXECUTION_DONE tests + ( + NativeBridgeProvider, + OptimismContractAdaptor, + { + "from": { + "chain": "ethereum", + "address": "0x308508F09F81A6d28679db6da73359c72f8e22C5", + "token": "0x0000000000000000000000000000000000000000", + }, + "to": { + "chain": "base", + "address": "0x308508F09F81A6d28679db6da73359c72f8e22C5", + "token": "0x0000000000000000000000000000000000000000", + "amount": 300000000000000, + }, + }, + "b-76a298b9-b243-4cfb-b48a-f59183ae0e85", + "0xf649cdce0075a950ed031cc32775990facdcefc8d2bfff695a8023895dd47ebd", + BridgeRequestStatus.EXECUTION_DONE, + "0xc97722c1310b94043fb37219285cb4f80ce4189f158033b84c935ec54166eb19", + 178, + ), + ( + NativeBridgeProvider, + OptimismContractAdaptor, + { + "from": { + "chain": "ethereum", + "address": "0x308508F09F81A6d28679db6da73359c72f8e22C5", + "token": "0x0001A500A6B18995B03f44bb040A5fFc28E45CB0", + }, + "to": { + "chain": "base", + "address": "0x308508F09F81A6d28679db6da73359c72f8e22C5", + "token": "0x54330d28ca3357F294334BDC454a032e7f353416", + "amount": 100000000000000000, + }, + }, + "b-7221ece2-e15e-4aec-bac2-7fd4c4d4851a", + "0xa1139bb4ba963d7979417f49fed03b365c1f1bfc31d0100257caed888a491c4c", + BridgeRequestStatus.EXECUTION_DONE, + "0x9b8f8998b1cd8f256914751606f772bee9ebbf459b3a1c8ca177838597464739", + 184, + ), + ( + NativeBridgeProvider, + OptimismContractAdaptor, + { + "from": { + "chain": "ethereum", + "address": "0xC0a12402089ce761E6496892AF4754350639bf94", + "token": "0x0000000000000000000000000000000000000000", + }, + "to": { + "chain": "base", + "address": "0xC0a12402089ce761E6496892AF4754350639bf94", + "token": "0x0000000000000000000000000000000000000000", + "amount": 30750000000000000, + }, + }, + "b-7ca71220-4336-414f-985e-bdfe11707c71", + "0xcf2b263ab1149bc6691537d09f3ed97e1ac4a8411a49ca9d81219c32f98228ba", + BridgeRequestStatus.EXECUTION_DONE, + "0x5718e6f0da2e0b1a02bcb53db239cef49a731f9f52cccf193f7d0abe62e971d4", + 198, + ), + ( + NativeBridgeProvider, + OptimismContractAdaptor, + { + "from": { + "chain": "ethereum", + "address": "0xC0a12402089ce761E6496892AF4754350639bf94", + "token": "0x0001A500A6B18995B03f44bb040A5fFc28E45CB0", + }, + "to": { + "chain": "base", + "address": "0xC0a12402089ce761E6496892AF4754350639bf94", + "token": "0x54330d28ca3357F294334BDC454a032e7f353416", + "amount": 100000000000000000000, + }, + }, + "b-fef67eea-d55c-45f0-8b5b-e7987c843ced", + "0x4a755c455f029a645f5bfe3fcd999c24acbde49991cb54f5b9b8fcf286ad2ac0", + BridgeRequestStatus.EXECUTION_DONE, + "0xf4ccb5f6547c188e638ac3d84f80158e3d7462211e15bc3657f8585b0bbffb68", + 186, + ), + # NativeBridgeProvider (Optimism bridge) - EXECUTION_FAILED tests + ( + NativeBridgeProvider, + OptimismContractAdaptor, + { + "from": { + "chain": "ethereum", + "address": "0x308508F09F81A6d28679db6da73359c72f8e22C5", + "token": "0x0000000000000000000000000000000000000000", + }, + "to": { + "chain": "base", + "address": "0x308508F09F81A6d28679db6da73359c72f8e22C5", + "token": "0x0000000000000000000000000000000000000000", + "amount": 42, # Wrong amount + }, + }, + "b-76a298b9-b243-4cfb-b48a-f59183ae0e85", + "0xf649cdce0075a950ed031cc32775990facdcefc8d2bfff695a8023895dd47ebd", + BridgeRequestStatus.EXECUTION_FAILED, + None, + 0, + ), + ( + NativeBridgeProvider, + OptimismContractAdaptor, + { + "from": { + "chain": "ethereum", + "address": "0x308508F09F81A6d28679db6da73359c72f8e22C5", + "token": "0x0001A500A6B18995B03f44bb040A5fFc28E45CB0", + }, + "to": { + "chain": "base", + "address": "0x308508F09F81A6d28679db6da73359c72f8e22C5", + "token": "0x54330d28ca3357F294334BDC454a032e7f353416", + "amount": 100000000000000000, + }, + }, + "b-42", # Wrong id + "0xa1139bb4ba963d7979417f49fed03b365c1f1bfc31d0100257caed888a491c4c", + BridgeRequestStatus.EXECUTION_FAILED, + None, + 0, + ), + ( + NativeBridgeProvider, + OptimismContractAdaptor, + { + "from": { + "chain": "ethereum", + "address": "0xC0a12402089ce761E6496892AF4754350639bf94", + "token": "0x0000000000000000000000000000000000000000", + }, + "to": { + "chain": "base", + "address": "0x54330d28ca3357F294334BDC454a032e7f353416", # Wrong address + "token": "0x0000000000000000000000000000000000000000", + "amount": 30750000000000000, + }, + }, + "b-7ca71220-4336-414f-985e-bdfe11707c71", + "0xcf2b263ab1149bc6691537d09f3ed97e1ac4a8411a49ca9d81219c32f98228ba", + BridgeRequestStatus.EXECUTION_FAILED, + None, + 0, + ), + ( + NativeBridgeProvider, + OptimismContractAdaptor, + { + "from": { + "chain": "ethereum", + "address": "0xC0a12402089ce761E6496892AF4754350639bf94", + "token": "0x0001A500A6B18995B03f44bb040A5fFc28E45CB0", + }, + "to": { + "chain": "base", + "address": "0xC0a12402089ce761E6496892AF4754350639bf94", + "token": "0x54330d28ca3357F294334BDC454a032e7f353416", + "amount": 100000000000000000000, + }, + }, + "b-fef67eea-d55c-45f0-8b5b-e7987c843ced", + "0x7cefa52970f4e1b12a07b9795b8f03de2bbc2ee7c42cba5913d923316e96b3c5", # Wrong from_tx_hash + BridgeRequestStatus.EXECUTION_FAILED, + None, + 0, + ), + ], + ) + def test_update_execution_status( + self, + tmp_path: Path, + password: str, + bridge_provider_class: t.Type[BridgeProvider], + contract_adaptor_class: t.Optional[t.Type[BridgeContractAdaptor]], + params: dict, + request_id: str, + from_tx_hash: str, + expected_status: BridgeRequestStatus, + expected_to_tx_hash: str, + expected_elapsed_time: int, + ) -> None: + """test_update_execution_status""" + + DEFAULT_RPCS[Chain.ETHEREUM] = "https://rpc-gate.autonolas.tech/ethereum-rpc/" + DEFAULT_RPCS[Chain.BASE] = "https://rpc-gate.autonolas.tech/base-rpc/" + + operate = OperateApp(home=tmp_path / OPERATE) + operate.setup() + operate.create_user_account(password=password) + operate.password = password + operate.wallet_manager.create(ledger_type=LedgerType.ETHEREUM) + + if contract_adaptor_class is not None: + from_chain = params["from"]["chain"] + to_chain = params["to"]["chain"] + provider_id = f"native-{from_chain}-to-{to_chain}" + bridge: BridgeProvider = NativeBridgeProvider( + provider_id=provider_id, + bridge_contract_adaptor=contract_adaptor_class( + from_chain=NATIVE_BRIDGE_CONFIGS[provider_id]["from_chain"], + from_bridge=NATIVE_BRIDGE_CONFIGS[provider_id]["from_bridge"], + to_chain=NATIVE_BRIDGE_CONFIGS[provider_id]["to_chain"], + to_bridge=NATIVE_BRIDGE_CONFIGS[provider_id]["to_bridge"], + bridge_eta=NATIVE_BRIDGE_CONFIGS[provider_id]["bridge_eta"], + ), + wallet_manager=operate.wallet_manager, + ) + else: + bridge = bridge_provider_class( + provider_id="", wallet_manager=operate.wallet_manager + ) + + quote_data = QuoteData( + bridge_eta=0, + elapsed_time=0, + message=None, + provider_data=None, + timestamp=0, + ) + + execution_data = ExecutionData( + elapsed_time=0, + message=None, + timestamp=0, + from_tx_hash=from_tx_hash, + to_tx_hash=None, + provider_data=None, + ) + + bridge_request = BridgeRequest( + params=params, + bridge_provider_id=bridge.provider_id, + id=request_id, + status=BridgeRequestStatus.EXECUTION_PENDING, + quote_data=quote_data, + execution_data=execution_data, + ) + + bridge.status_json(bridge_request) + + assert bridge_request.status == expected_status, "Wrong execution status." + assert execution_data.to_tx_hash == expected_to_tx_hash, "Wrong to_tx_hash." + assert execution_data.elapsed_time == expected_elapsed_time, "Wrong timestamp." diff --git a/tox.ini b/tox.ini index 7c18c03e..2d4f929a 100644 --- a/tox.ini +++ b/tox.ini @@ -3,6 +3,8 @@ envlist = isort skip_missing_interpreters = true isolated_build = True +[testenv] +passenv = * [testenv:bandit] skipsdist = True @@ -240,6 +242,12 @@ ignore_missing_imports = True [mypy-argon2.*] ignore_missing_imports = True +[mypy-eth_abi.*] +ignore_missing_imports = True + +[mypy-eth_typing.*] +ignore_missing_imports = true + [testenv:unit-tests] deps = pytest==7.2.1