iwa 0.0.62__py3-none-any.whl → 0.0.65__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- iwa/core/services/transfer/__init__.py +2 -2
- iwa/plugins/olas/models.py +5 -22
- iwa/plugins/olas/service_manager/drain.py +41 -12
- iwa/plugins/olas/service_manager/lifecycle.py +3 -3
- iwa/plugins/olas/tests/test_olas_models.py +5 -5
- iwa/plugins/olas/tests/test_olas_view_actions.py +1 -1
- iwa/plugins/olas/tests/test_service_manager_rewards.py +6 -1
- iwa/plugins/olas/tests/test_service_staking.py +1 -0
- iwa/web/routers/state.py +8 -0
- iwa/web/static/app.js +15 -1
- iwa/web/static/index.html +1 -1
- iwa/web/tests/test_web_olas.py +1 -1
- {iwa-0.0.62.dist-info → iwa-0.0.65.dist-info}/METADATA +1 -1
- {iwa-0.0.62.dist-info → iwa-0.0.65.dist-info}/RECORD +22 -21
- tests/test_chainlist_enrichment.py +233 -0
- tests/test_contract_cache.py +253 -0
- tests/test_drain_coverage.py +265 -3
- tests/test_staking_simple.py +478 -6
- {iwa-0.0.62.dist-info → iwa-0.0.65.dist-info}/WHEEL +0 -0
- {iwa-0.0.62.dist-info → iwa-0.0.65.dist-info}/entry_points.txt +0 -0
- {iwa-0.0.62.dist-info → iwa-0.0.65.dist-info}/licenses/LICENSE +0 -0
- {iwa-0.0.62.dist-info → iwa-0.0.65.dist-info}/top_level.txt +0 -0
|
@@ -136,8 +136,8 @@ class TransferService(
|
|
|
136
136
|
|
|
137
137
|
amount_eth = float(chain_interface.web3.from_wei(amount_wei, "ether"))
|
|
138
138
|
logger.info(
|
|
139
|
-
f"Sending {amount_eth:.4f} {
|
|
140
|
-
f"from {from_address_or_tag} to {to_address_or_tag}"
|
|
139
|
+
f"Sending {amount_eth:.4f} {token_symbol} "
|
|
140
|
+
f"from {from_tag or from_address_or_tag} to {to_tag or to_address_or_tag}"
|
|
141
141
|
)
|
|
142
142
|
|
|
143
143
|
if is_safe:
|
iwa/plugins/olas/models.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from typing import Dict, List, Optional
|
|
4
4
|
|
|
5
|
-
from pydantic import BaseModel, Field
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
6
6
|
|
|
7
7
|
from iwa.core.models import EthereumAddress
|
|
8
8
|
|
|
@@ -15,37 +15,20 @@ class Service(BaseModel):
|
|
|
15
15
|
service_id: int # Unique per chain
|
|
16
16
|
agent_ids: List[int] = Field(default_factory=list) # List of agent type IDs
|
|
17
17
|
|
|
18
|
-
#
|
|
18
|
+
# Owner fields:
|
|
19
|
+
# - service_owner_eoa_address: EOA that owns the service (or signs for the multisig)
|
|
20
|
+
# - service_owner_multisig_address: Safe multisig owner (optional, if service is owned by a Safe)
|
|
19
21
|
service_owner_eoa_address: Optional[EthereumAddress] = None
|
|
20
22
|
service_owner_multisig_address: Optional[EthereumAddress] = None
|
|
21
23
|
|
|
22
|
-
# Deprecated fields (kept for migration, removed from physical model via aliasing/validation)
|
|
23
|
-
# Actually, we keep it optional but not used, or use migration logic.
|
|
24
|
-
# Let's remove it from fields and rely on before validator to map it to eoa.
|
|
25
|
-
|
|
26
24
|
agent_address: Optional[EthereumAddress] = None
|
|
27
25
|
multisig_address: Optional[EthereumAddress] = None
|
|
28
26
|
staking_contract_address: Optional[EthereumAddress] = None
|
|
29
27
|
token_address: Optional[EthereumAddress] = None
|
|
30
28
|
|
|
31
|
-
@root_validator(pre=True)
|
|
32
|
-
def migrate_owner_fields(cls, values): # noqa: N805
|
|
33
|
-
"""Migrate legacy service_owner_address to service_owner_eoa_address."""
|
|
34
|
-
# Check for legacy 'service_owner_address'
|
|
35
|
-
if "service_owner_address" in values and values["service_owner_address"]:
|
|
36
|
-
legacy_addr = values["service_owner_address"]
|
|
37
|
-
|
|
38
|
-
# If service_owner_eoa_address is missing, use legacy
|
|
39
|
-
if "service_owner_eoa_address" not in values or not values["service_owner_eoa_address"]:
|
|
40
|
-
values["service_owner_eoa_address"] = legacy_addr
|
|
41
|
-
|
|
42
|
-
# Remove legacy field from values so it doesn't cause extra field errors if we removed it from model
|
|
43
|
-
# Or if strict.
|
|
44
|
-
return values
|
|
45
|
-
|
|
46
29
|
@property
|
|
47
30
|
def service_owner_address(self) -> Optional[EthereumAddress]:
|
|
48
|
-
"""
|
|
31
|
+
"""Returns effective owner address (Safe multisig if present, else EOA)."""
|
|
49
32
|
return self.service_owner_multisig_address or self.service_owner_eoa_address
|
|
50
33
|
|
|
51
34
|
@property
|
|
@@ -12,7 +12,9 @@ from iwa.plugins.olas.contracts.staking import StakingContract, StakingState
|
|
|
12
12
|
class DrainManagerMixin:
|
|
13
13
|
"""Mixin for draining and service token management."""
|
|
14
14
|
|
|
15
|
-
def claim_rewards(
|
|
15
|
+
def claim_rewards( # noqa: C901
|
|
16
|
+
self, staking_contract: Optional[StakingContract] = None
|
|
17
|
+
) -> Tuple[bool, int]:
|
|
16
18
|
"""Claim staking rewards for the active service.
|
|
17
19
|
|
|
18
20
|
The claimed OLAS tokens will be sent to the service's multisig (Safe).
|
|
@@ -51,13 +53,19 @@ class DrainManagerMixin:
|
|
|
51
53
|
logger.info("Service not staked, skipping claim")
|
|
52
54
|
return False, 0
|
|
53
55
|
|
|
54
|
-
# Check
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
# Check claimable rewards using calculate_staking_reward for accurate value
|
|
57
|
+
# (get_accrued_rewards returns stored value which may be outdated)
|
|
58
|
+
try:
|
|
59
|
+
claimable_rewards = staking_contract.calculate_staking_reward(service_id)
|
|
60
|
+
except Exception:
|
|
61
|
+
# Fallback to stored value if calculation fails
|
|
62
|
+
claimable_rewards = staking_contract.get_accrued_rewards(service_id)
|
|
63
|
+
|
|
64
|
+
if claimable_rewards == 0:
|
|
65
|
+
logger.info("No rewards to claim")
|
|
58
66
|
return False, 0
|
|
59
67
|
|
|
60
|
-
logger.info(f"Claiming {
|
|
68
|
+
logger.info(f"Claiming ~{claimable_rewards / 1e18:.4f} OLAS rewards for service {service_id}")
|
|
61
69
|
|
|
62
70
|
# Use service owner which holds the reward rights (not necessarily master)
|
|
63
71
|
owner_address = self.service.service_owner_address or self.wallet.master_account.address
|
|
@@ -72,6 +80,13 @@ class DrainManagerMixin:
|
|
|
72
80
|
logger.error("Failed to prepare claim transaction")
|
|
73
81
|
return False, 0
|
|
74
82
|
|
|
83
|
+
# Simulate transaction to catch revert before sending
|
|
84
|
+
try:
|
|
85
|
+
staking_contract.chain_interface.web3.eth.call(claim_tx)
|
|
86
|
+
except Exception as e:
|
|
87
|
+
logger.warning(f"Claim would revert, skipping: {e}")
|
|
88
|
+
return False, 0
|
|
89
|
+
|
|
75
90
|
success, receipt = self.wallet.sign_and_send_transaction(
|
|
76
91
|
claim_tx,
|
|
77
92
|
signer_address_or_tag=owner_address,
|
|
@@ -83,11 +98,19 @@ class DrainManagerMixin:
|
|
|
83
98
|
return False, 0
|
|
84
99
|
|
|
85
100
|
events = staking_contract.extract_events(receipt)
|
|
86
|
-
if "RewardClaimed" not in [event["name"] for event in events]:
|
|
87
|
-
logger.warning("RewardClaimed event not found, but transaction succeeded")
|
|
88
101
|
|
|
89
|
-
|
|
90
|
-
|
|
102
|
+
# Extract actual claimed amount from RewardClaimed event
|
|
103
|
+
claimed_amount = claimable_rewards # Default to estimated
|
|
104
|
+
for event in events:
|
|
105
|
+
if event["name"] == "RewardClaimed":
|
|
106
|
+
# RewardClaimed event has 'amount' or 'reward' field
|
|
107
|
+
claimed_amount = event["args"].get("amount", event["args"].get("reward", claimed_amount))
|
|
108
|
+
break
|
|
109
|
+
else:
|
|
110
|
+
logger.warning("RewardClaimed event not found, using estimated amount")
|
|
111
|
+
|
|
112
|
+
logger.info(f"Successfully claimed {claimed_amount / 1e18:.4f} OLAS rewards")
|
|
113
|
+
return True, claimed_amount
|
|
91
114
|
|
|
92
115
|
def withdraw_rewards(self) -> Tuple[bool, float]:
|
|
93
116
|
"""Withdraw OLAS from the service Safe to the configured withdrawal address.
|
|
@@ -132,8 +155,14 @@ class DrainManagerMixin:
|
|
|
132
155
|
return False, 0
|
|
133
156
|
|
|
134
157
|
olas_amount = olas_balance / 1e18
|
|
135
|
-
withdrawal_tag =
|
|
136
|
-
|
|
158
|
+
withdrawal_tag = (
|
|
159
|
+
self.wallet.account_service.get_tag_by_address(withdrawal_address)
|
|
160
|
+
or withdrawal_address
|
|
161
|
+
)
|
|
162
|
+
multisig_tag = (
|
|
163
|
+
self.wallet.account_service.get_tag_by_address(multisig_address)
|
|
164
|
+
or multisig_address
|
|
165
|
+
)
|
|
137
166
|
|
|
138
167
|
logger.info(f"Withdrawing {olas_amount:.4f} OLAS from {multisig_tag} to {withdrawal_tag}")
|
|
139
168
|
|
|
@@ -183,7 +183,7 @@ class LifecycleManagerMixin:
|
|
|
183
183
|
service_name=service_name,
|
|
184
184
|
chain_name=chain_name,
|
|
185
185
|
agent_id_values=agent_id_values,
|
|
186
|
-
|
|
186
|
+
service_owner_eoa_address=service_owner_account.address,
|
|
187
187
|
token_address=token_address,
|
|
188
188
|
)
|
|
189
189
|
|
|
@@ -263,7 +263,7 @@ class LifecycleManagerMixin:
|
|
|
263
263
|
service_name: Optional[str],
|
|
264
264
|
chain_name: str,
|
|
265
265
|
agent_id_values: List[int],
|
|
266
|
-
|
|
266
|
+
service_owner_eoa_address: str,
|
|
267
267
|
token_address: Optional[str],
|
|
268
268
|
) -> None:
|
|
269
269
|
"""Create and save the new Service model."""
|
|
@@ -272,7 +272,7 @@ class LifecycleManagerMixin:
|
|
|
272
272
|
chain_name=chain_name,
|
|
273
273
|
service_id=service_id,
|
|
274
274
|
agent_ids=agent_id_values,
|
|
275
|
-
|
|
275
|
+
service_owner_eoa_address=service_owner_eoa_address,
|
|
276
276
|
token_address=token_address,
|
|
277
277
|
)
|
|
278
278
|
|
|
@@ -14,7 +14,7 @@ class TestOlasConfig:
|
|
|
14
14
|
chain_name="gnosis",
|
|
15
15
|
service_id=456,
|
|
16
16
|
agent_ids=[25],
|
|
17
|
-
|
|
17
|
+
service_owner_eoa_address="0x1234567890123456789012345678901234567890",
|
|
18
18
|
)
|
|
19
19
|
|
|
20
20
|
config.add_service(service)
|
|
@@ -30,7 +30,7 @@ class TestOlasConfig:
|
|
|
30
30
|
chain_name="gnosis",
|
|
31
31
|
service_id=789,
|
|
32
32
|
agent_ids=[25],
|
|
33
|
-
|
|
33
|
+
service_owner_eoa_address="0x1234567890123456789012345678901234567890",
|
|
34
34
|
)
|
|
35
35
|
config.services["gnosis:789"] = service
|
|
36
36
|
|
|
@@ -53,7 +53,7 @@ class TestOlasConfig:
|
|
|
53
53
|
chain_name="ethereum",
|
|
54
54
|
service_id=200,
|
|
55
55
|
agent_ids=[25],
|
|
56
|
-
|
|
56
|
+
service_owner_eoa_address="0x1234567890123456789012345678901234567890",
|
|
57
57
|
)
|
|
58
58
|
config.services["ethereum:200"] = service
|
|
59
59
|
|
|
@@ -116,7 +116,7 @@ class TestService:
|
|
|
116
116
|
chain_name="gnosis",
|
|
117
117
|
service_id=123,
|
|
118
118
|
agent_ids=[25],
|
|
119
|
-
|
|
119
|
+
service_owner_eoa_address="0x1234567890123456789012345678901234567890",
|
|
120
120
|
)
|
|
121
121
|
|
|
122
122
|
assert service.key == "gnosis:123"
|
|
@@ -133,7 +133,7 @@ class TestService:
|
|
|
133
133
|
chain_name="gnosis",
|
|
134
134
|
service_id=456,
|
|
135
135
|
agent_ids=[25],
|
|
136
|
-
|
|
136
|
+
service_owner_eoa_address="0x1234567890123456789012345678901234567890",
|
|
137
137
|
staking_contract_address=staking_addr,
|
|
138
138
|
token_address=token_addr,
|
|
139
139
|
)
|
|
@@ -35,7 +35,7 @@ def mock_olas_config():
|
|
|
35
35
|
chain_name="gnosis",
|
|
36
36
|
agent_address=VALID_ADDR_1,
|
|
37
37
|
multisig_address=VALID_ADDR_2,
|
|
38
|
-
|
|
38
|
+
service_owner_eoa_address=VALID_ADDR_3,
|
|
39
39
|
staking_contract_address=VALID_ADDR_1,
|
|
40
40
|
)
|
|
41
41
|
config = OlasConfig(services={"gnosis:1": service})
|
|
@@ -108,6 +108,7 @@ def test_claim_rewards_no_accrued_rewards(mock_wallet):
|
|
|
108
108
|
|
|
109
109
|
mock_staking = MagicMock()
|
|
110
110
|
mock_staking.get_staking_state.return_value = StakingState.STAKED
|
|
111
|
+
mock_staking.calculate_staking_reward.return_value = 0
|
|
111
112
|
mock_staking.get_accrued_rewards.return_value = 0
|
|
112
113
|
|
|
113
114
|
success, amount = manager.claim_rewards(staking_contract=mock_staking)
|
|
@@ -129,9 +130,12 @@ def test_claim_rewards_success(mock_wallet):
|
|
|
129
130
|
|
|
130
131
|
mock_staking = MagicMock()
|
|
131
132
|
mock_staking.get_staking_state.return_value = StakingState.STAKED
|
|
133
|
+
mock_staking.calculate_staking_reward.return_value = 10 * 10**18 # 10 OLAS
|
|
132
134
|
mock_staking.get_accrued_rewards.return_value = 10 * 10**18 # 10 OLAS
|
|
133
135
|
mock_staking.prepare_claim_tx.return_value = {"data": "0x"}
|
|
134
|
-
mock_staking.extract_events.return_value = [
|
|
136
|
+
mock_staking.extract_events.return_value = [
|
|
137
|
+
{"name": "RewardClaimed", "args": {"amount": 10 * 10**18}}
|
|
138
|
+
]
|
|
135
139
|
|
|
136
140
|
success, amount = manager.claim_rewards(staking_contract=mock_staking)
|
|
137
141
|
|
|
@@ -152,6 +156,7 @@ def test_claim_rewards_tx_fails(mock_wallet):
|
|
|
152
156
|
|
|
153
157
|
mock_staking = MagicMock()
|
|
154
158
|
mock_staking.get_staking_state.return_value = StakingState.STAKED
|
|
159
|
+
mock_staking.calculate_staking_reward.return_value = 10 * 10**18
|
|
155
160
|
mock_staking.get_accrued_rewards.return_value = 10 * 10**18
|
|
156
161
|
mock_staking.prepare_claim_tx.return_value = {"data": "0x"}
|
|
157
162
|
mock_wallet.sign_and_send_transaction.return_value = (False, {})
|
|
@@ -201,6 +201,7 @@ def test_sm_claim_rewards_tx_fails(mock_wallet):
|
|
|
201
201
|
mock_staking = MagicMock()
|
|
202
202
|
mock_staking.prepare_claim_tx.return_value = {"to": VALID_ADDR}
|
|
203
203
|
mock_staking.get_staking_state.return_value = StakingState.STAKED
|
|
204
|
+
mock_staking.calculate_staking_reward.return_value = 100
|
|
204
205
|
mock_staking.get_accrued_rewards.return_value = 100
|
|
205
206
|
|
|
206
207
|
def get_contract_side_effect(cls, *args, **kwargs):
|
iwa/web/routers/state.py
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from fastapi import APIRouter, Depends
|
|
4
4
|
|
|
5
5
|
from iwa.core.chain import ChainInterfaces
|
|
6
|
+
from iwa.core.models import Config
|
|
6
7
|
from iwa.web.dependencies import verify_auth
|
|
7
8
|
|
|
8
9
|
router = APIRouter(prefix="/api", tags=["state"])
|
|
@@ -25,12 +26,19 @@ def get_state(auth: bool = Depends(verify_auth)):
|
|
|
25
26
|
# Get token symbols from the interface (dict of symbol -> address)
|
|
26
27
|
tokens[name] = list(interface.tokens.keys())
|
|
27
28
|
|
|
29
|
+
# Get whitelist from config
|
|
30
|
+
config = Config()
|
|
31
|
+
whitelist = {}
|
|
32
|
+
if config.core and config.core.whitelist:
|
|
33
|
+
whitelist = {tag: str(addr) for tag, addr in config.core.whitelist.items()}
|
|
34
|
+
|
|
28
35
|
return {
|
|
29
36
|
"chains": chain_names,
|
|
30
37
|
"tokens": tokens,
|
|
31
38
|
"native_currencies": native_currencies,
|
|
32
39
|
"default_chain": "gnosis",
|
|
33
40
|
"testing": ChainInterfaces().gnosis.is_tenderly,
|
|
41
|
+
"whitelist": whitelist,
|
|
34
42
|
}
|
|
35
43
|
|
|
36
44
|
|
iwa/web/static/app.js
CHANGED
|
@@ -12,6 +12,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
|
12
12
|
olasServicesCache: {}, // { chain: [services] }
|
|
13
13
|
stakingContractsCache: null, // Cached staking contracts
|
|
14
14
|
olasPriceCache: null, // Cached OLAS price in EUR
|
|
15
|
+
whitelist: {}, // { tag: address } from config
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
// Real-time countdown updater for unstake availability
|
|
@@ -138,6 +139,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
|
138
139
|
state.chains = data.chains;
|
|
139
140
|
state.tokens = data.tokens;
|
|
140
141
|
state.nativeCurrencies = data.native_currencies || {};
|
|
142
|
+
state.whitelist = data.whitelist || {};
|
|
141
143
|
|
|
142
144
|
// Update status indicator for testing mode
|
|
143
145
|
const statusText = document.getElementById("status-text");
|
|
@@ -518,12 +520,24 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
|
518
520
|
)
|
|
519
521
|
.join("");
|
|
520
522
|
|
|
521
|
-
|
|
523
|
+
// Build To options: own accounts + whitelisted addresses
|
|
524
|
+
const accountOptions = state.accounts
|
|
522
525
|
.map(
|
|
523
526
|
(acc) =>
|
|
524
527
|
`<option value="${escapeHtml(acc.tag)}">${escapeHtml(acc.tag)}</option>`,
|
|
525
528
|
)
|
|
526
529
|
.join("");
|
|
530
|
+
const whitelistOptions = Object.entries(state.whitelist)
|
|
531
|
+
.map(
|
|
532
|
+
([tag, addr]) =>
|
|
533
|
+
`<option value="${escapeHtml(addr)}">${escapeHtml(tag)} (whitelist)</option>`,
|
|
534
|
+
)
|
|
535
|
+
.join("");
|
|
536
|
+
toSelect.innerHTML =
|
|
537
|
+
accountOptions +
|
|
538
|
+
(whitelistOptions
|
|
539
|
+
? `<optgroup label="Whitelist">${whitelistOptions}</optgroup>`
|
|
540
|
+
: "");
|
|
527
541
|
|
|
528
542
|
tokenSelect.innerHTML =
|
|
529
543
|
`<option value="native">${escapeHtml(nativeSymbol)}</option>` +
|
iwa/web/static/index.html
CHANGED
iwa/web/tests/test_web_olas.py
CHANGED
|
@@ -43,7 +43,7 @@ def mock_olas_config():
|
|
|
43
43
|
chain_name="gnosis",
|
|
44
44
|
agent_address="0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB",
|
|
45
45
|
multisig_address="0x40A2aCCbd92BCA938b02010E17A5b8929b49130D",
|
|
46
|
-
|
|
46
|
+
service_owner_eoa_address="0x1111111111111111111111111111111111111111",
|
|
47
47
|
staking_contract_address="0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB",
|
|
48
48
|
)
|
|
49
49
|
return OlasConfig(services={"gnosis:1": service})
|
|
@@ -43,7 +43,7 @@ iwa/core/services/plugin.py,sha256=GNNlbtELyHl7MNVChrypF76GYphxXduxDog4kx1MLi8,3
|
|
|
43
43
|
iwa/core/services/safe.py,sha256=vqvpk7aIqHljaG1zYYpmKdW4mi5OVuoyXcpReISPYM0,15744
|
|
44
44
|
iwa/core/services/safe_executor.py,sha256=TqpDgtvh8d5cedYAKBj7s1SW7EnomTT9MW_GnYWMxDE,17157
|
|
45
45
|
iwa/core/services/transaction.py,sha256=FrGRWn1xo5rbGIr2ToZ2kPzapr3zmWW38oycyB87TK8,19971
|
|
46
|
-
iwa/core/services/transfer/__init__.py,sha256=
|
|
46
|
+
iwa/core/services/transfer/__init__.py,sha256=7p22xtwrH0murXWTuTGNw0WRKBDqjJEnnVaUpWd8Vfo,5589
|
|
47
47
|
iwa/core/services/transfer/base.py,sha256=sohz-Ss2i-pGYGl4x9bD93cnYKcSvsXaXyvyRawvgQs,9043
|
|
48
48
|
iwa/core/services/transfer/erc20.py,sha256=e6RD1_QcI_-iJvP85kj7aw4p6NnCPjZcm-QSKi14RRA,10104
|
|
49
49
|
iwa/core/services/transfer/multisend.py,sha256=MuOTjzUQoYg1eSixXKhJGBmB1c0ymLelvk4puHm_VGE,15194
|
|
@@ -70,7 +70,7 @@ iwa/plugins/olas/constants.py,sha256=BbEDho_TAh10cCGsrlk2vP1OVrS_ZWBE_cAEITd_658
|
|
|
70
70
|
iwa/plugins/olas/events.py,sha256=HHjYu4pN3tuZATIh8vGWWzDb7z9wuqhsaTqI3_4H0-I,6086
|
|
71
71
|
iwa/plugins/olas/importer.py,sha256=5xTtlQe5hO5bUCOg1sRuFkN2UcohYdJEQwfMm2JckyI,42088
|
|
72
72
|
iwa/plugins/olas/mech_reference.py,sha256=CaSCpQnQL4F7wOG6Ox6Zdoy-uNEQ78YBwVLILQZKL8Q,5782
|
|
73
|
-
iwa/plugins/olas/models.py,sha256=
|
|
73
|
+
iwa/plugins/olas/models.py,sha256=VtDjSyc63Yxs3aManmALrcf7asehdQ5f-5Y6MtAdWIk,4056
|
|
74
74
|
iwa/plugins/olas/plugin.py,sha256=kz21CxIGQw3Is6HC2dvKvFRIm9m1FRKHO0YgUuDEplQ,15650
|
|
75
75
|
iwa/plugins/olas/contracts/activity_checker.py,sha256=OXh0SFPGfcpeD665ay-I19LqcIx38qEz8o62dw0A9zE,5361
|
|
76
76
|
iwa/plugins/olas/contracts/base.py,sha256=y73aQbDq6l4zUpz_eQAg4MsLkTAEqjjupXlcvxjfgCI,240
|
|
@@ -93,8 +93,8 @@ iwa/plugins/olas/scripts/test_full_mech_flow.py,sha256=Fqoq5bn7Z_3YyRrnuqNAZy9cw
|
|
|
93
93
|
iwa/plugins/olas/scripts/test_simple_lifecycle.py,sha256=8T50tOZx3afeECSfCNAb0rAHNtYOsBaeXlMwKXElCk8,2099
|
|
94
94
|
iwa/plugins/olas/service_manager/__init__.py,sha256=GXiThMEY3nPgHUl1i-DLrF4h96z9jPxxI8Jepo2E1PM,1926
|
|
95
95
|
iwa/plugins/olas/service_manager/base.py,sha256=EBPg0ymqgtAb7ZvVSfTt31QYgv_6gp4UAc6je00NLAg,5009
|
|
96
|
-
iwa/plugins/olas/service_manager/drain.py,sha256=
|
|
97
|
-
iwa/plugins/olas/service_manager/lifecycle.py,sha256=
|
|
96
|
+
iwa/plugins/olas/service_manager/drain.py,sha256=tJLqvMEPOymxukFuxt-AdgOB4bIIciKcXoxOPx9j-LM,13983
|
|
97
|
+
iwa/plugins/olas/service_manager/lifecycle.py,sha256=Jz2WTsBE_kGjFnsnpQlUBmMM2csOuqEfYdvj4cLrNuU,50586
|
|
98
98
|
iwa/plugins/olas/service_manager/mech.py,sha256=NVzVbEmyOe3wK92VEzCCOSuy3HDkEP1MSoVt7Av8Psk,27949
|
|
99
99
|
iwa/plugins/olas/service_manager/staking.py,sha256=kT9OOQ4fi3FrIJB2T2gsvmv7DBRD6pDxqcXXh2o6iwc,29600
|
|
100
100
|
iwa/plugins/olas/tests/conftest.py,sha256=4vM7EI00SrTGyeP0hNzsGSQHEj2-iznVgzlNh2_OGfo,739
|
|
@@ -104,9 +104,9 @@ iwa/plugins/olas/tests/test_mech_contracts.py,sha256=wvxuigPafF-ySIHVBdWVei3AO41
|
|
|
104
104
|
iwa/plugins/olas/tests/test_olas_archiving.py,sha256=rwyP-9eZ1cNvvV4h4bBOrs_8qV-du9yt-VNMuH_13nY,3443
|
|
105
105
|
iwa/plugins/olas/tests/test_olas_contracts.py,sha256=B8X-5l1KfYMoZOiM94_rcNzbILLl78rqt_jhyxzAOqE,10835
|
|
106
106
|
iwa/plugins/olas/tests/test_olas_integration.py,sha256=LGkdeso5lvi7_0GjlS9EFlSs6PEEn_b5aD2USmperDA,23086
|
|
107
|
-
iwa/plugins/olas/tests/test_olas_models.py,sha256=
|
|
107
|
+
iwa/plugins/olas/tests/test_olas_models.py,sha256=LCtU01v2LhPgSjzMBGlhRQ9nBb7sgcd7n7F1z-T-IuA,4977
|
|
108
108
|
iwa/plugins/olas/tests/test_olas_view.py,sha256=2SsQYayeV3rf_mAPVvt4vINcMysAXmICkkQe3MRn4K8,10662
|
|
109
|
-
iwa/plugins/olas/tests/test_olas_view_actions.py,sha256=
|
|
109
|
+
iwa/plugins/olas/tests/test_olas_view_actions.py,sha256=67al8ffNWMETI-foq-FjsXqpjdEruuH1sRCsGo_x9GE,5113
|
|
110
110
|
iwa/plugins/olas/tests/test_olas_view_modals.py,sha256=8j0PNFjKqFC5V1kBdVFWNLMvqGt49H6fLSYGxn02c8o,5562
|
|
111
111
|
iwa/plugins/olas/tests/test_plugin.py,sha256=RVgU-Cq6t_3mOh90xFAGwlJOV7ZIgp0VNaK5ZAxisAQ,2565
|
|
112
112
|
iwa/plugins/olas/tests/test_plugin_full.py,sha256=55EBa07JhJLVG3IMi6QKlR_ivWLYCdLQTySP66qbEXo,8584
|
|
@@ -115,9 +115,9 @@ iwa/plugins/olas/tests/test_service_manager.py,sha256=_mFRptssimITHhjvZA5jUPU2bI
|
|
|
115
115
|
iwa/plugins/olas/tests/test_service_manager_errors.py,sha256=-qpLmU4Uiqqtre59L2wXpO4WPMs4ej_K_gAL3naEvRg,8554
|
|
116
116
|
iwa/plugins/olas/tests/test_service_manager_flows.py,sha256=ZSmBJNa18d_MyAaLQRoPpfFYRwzmk9k-5AhSAGd7WeI,20737
|
|
117
117
|
iwa/plugins/olas/tests/test_service_manager_mech.py,sha256=qG6qu5IPRNypXUsblU2OEkuiuwDJ0TH8RXZbibmTFcQ,4937
|
|
118
|
-
iwa/plugins/olas/tests/test_service_manager_rewards.py,sha256=
|
|
118
|
+
iwa/plugins/olas/tests/test_service_manager_rewards.py,sha256=2YCrXBU5bEkPuhBoGBhjnO1nA2qwHxn5Ivrror18FHM,12248
|
|
119
119
|
iwa/plugins/olas/tests/test_service_manager_validation.py,sha256=ajlfH5uc4mAHf8A7GLE5cW7X8utM2vUilM0JdGDdlVg,5382
|
|
120
|
-
iwa/plugins/olas/tests/test_service_staking.py,sha256=
|
|
120
|
+
iwa/plugins/olas/tests/test_service_staking.py,sha256=78yyPoLo51N1aQyDxjzj7I0a263JHKHqekL-W3oQAsw,15914
|
|
121
121
|
iwa/plugins/olas/tests/test_staking_integration.py,sha256=QCBQf6P2ZmmsEGt2k8W2r53lG2aVRuoMJE-aFxVDLss,9701
|
|
122
122
|
iwa/plugins/olas/tests/test_staking_validation.py,sha256=uug64jFcXYJ3Nw_lNa3O4fnhNr5wAWHHIrchSbR2MVE,4020
|
|
123
123
|
iwa/plugins/olas/tui/__init__.py,sha256=5ZRsbC7J3z1xfkZRiwr4bLEklf78rNVjdswe2p7SlS8,28
|
|
@@ -150,7 +150,7 @@ iwa/web/dependencies.py,sha256=0_dAJlRh6gKrUDRPKUe92eshFsg572yx_H0lQgSqGDA,2103
|
|
|
150
150
|
iwa/web/models.py,sha256=MSD9WPy_Nz_amWgoo2KSDTn4ZLv_AV0o0amuNtSf-68,3035
|
|
151
151
|
iwa/web/server.py,sha256=4ZLVFEKoGs_NoCcXMeyYzDNdxUXazjwHQaX7CR1pwHE,5239
|
|
152
152
|
iwa/web/routers/accounts.py,sha256=VhCHrwzRWqZcSW-tTEqFWT5hFl-IYEWpqXeuN8xM3-4,3922
|
|
153
|
-
iwa/web/routers/state.py,sha256=
|
|
153
|
+
iwa/web/routers/state.py,sha256=wsBAOIWZeMWjMwLiiWVhuEXHAceI0IIq6CPpmh7SbIc,2469
|
|
154
154
|
iwa/web/routers/swap.py,sha256=8xycAytquR29ELxW3vx428W8s9bI_w_x2kpRhhJ0KXY,22630
|
|
155
155
|
iwa/web/routers/transactions.py,sha256=bRjfD7zcuX3orVIHzOMVsIkEtcE_pM_KCom4cdAKV6Q,5602
|
|
156
156
|
iwa/web/routers/olas/__init__.py,sha256=Jo6Dm1e8fHafCD800fbxsxeFz3tvuEEKXEf5-9tj5Qg,947
|
|
@@ -159,14 +159,14 @@ iwa/web/routers/olas/funding.py,sha256=f8fADNtbZEBFl-vuVKfas6os38Vot6K5tJBTenZmC
|
|
|
159
159
|
iwa/web/routers/olas/general.py,sha256=dPsBQppTGoQY1RztliUhseOHOZGeeCR10lhThD9kyXo,803
|
|
160
160
|
iwa/web/routers/olas/services.py,sha256=jDbxLUJBN48vs2-fXrIpxhPSM6quqYxggmMOkUVEIaI,18200
|
|
161
161
|
iwa/web/routers/olas/staking.py,sha256=jktJ2C1Q9X4aC0tWJByN3sHpEXY0EIvr3rr4N0MtXXc,14081
|
|
162
|
-
iwa/web/static/app.js,sha256=
|
|
163
|
-
iwa/web/static/index.html,sha256=
|
|
162
|
+
iwa/web/static/app.js,sha256=VCm9zPJERb9pX6zbFQ_7D47UnztGdibrkZ1dmwhsvdc,114949
|
|
163
|
+
iwa/web/static/index.html,sha256=pPwUcpqzv51P8FSKd-ml5K_xgmVGjigh3sFOPKsQpO8,28514
|
|
164
164
|
iwa/web/static/style.css,sha256=7i6T96pS7gXSLDZfyp_87gRlyB9rpsFWJEHJ-dRY1ug,24371
|
|
165
165
|
iwa/web/tests/test_web_endpoints.py,sha256=vA25YghHNB23sbmhD4ciesn_f_okSq0tjlkrSiKZ0rs,24007
|
|
166
|
-
iwa/web/tests/test_web_olas.py,sha256=
|
|
166
|
+
iwa/web/tests/test_web_olas.py,sha256=GunKEAzcbzL7FoUGMtEl8wqiqwYwA5lB9sOhfCNj0TA,16312
|
|
167
167
|
iwa/web/tests/test_web_swap.py,sha256=7A4gBJFL01kIXPtW1E1J17SCsVc_0DmUn-R8kKrnnVA,2974
|
|
168
168
|
iwa/web/tests/test_web_swap_coverage.py,sha256=zGNrzlhZ_vWDCvWmLcoUwFgqxnrp_ACbo49AtWBS_Kw,5584
|
|
169
|
-
iwa-0.0.
|
|
169
|
+
iwa-0.0.65.dist-info/licenses/LICENSE,sha256=eIubm_IlBHPYRQlLNZKbBNKhJUUP3JH0A2miZUhAVfI,1078
|
|
170
170
|
tests/legacy_cow.py,sha256=oOkZvIxL70ReEoD9oHQbOD5GpjIr6AGNHcOCgfPlerU,8389
|
|
171
171
|
tests/legacy_safe.py,sha256=AssM2g13E74dNGODu_H0Q0y412lgqsrYnEzI97nm_Ts,2972
|
|
172
172
|
tests/legacy_transaction_retry_logic.py,sha256=D9RqZ7DBu61Xr2djBAodU2p9UE939LL-DnQXswX5iQk,1497
|
|
@@ -178,11 +178,12 @@ tests/test_balance_service.py,sha256=wcuCOVszxPy8nPkldAVcEiygcOK3BuQt797fqAJvbp4
|
|
|
178
178
|
tests/test_chain.py,sha256=VZoidSojWyt1y4mQdZdoZsjuuDZjLC6neTC-2SF_Q7I,13957
|
|
179
179
|
tests/test_chain_interface.py,sha256=bgqGM8wJGZjc-BOX6i0K4sh06KCJl-6UAvrwl8x24lA,8324
|
|
180
180
|
tests/test_chain_interface_coverage.py,sha256=fvrVvw8-DMwdsSFKQHUhpbfutrVRxnnTc-tjB7Bb-jo,3327
|
|
181
|
-
tests/test_chainlist_enrichment.py,sha256=
|
|
181
|
+
tests/test_chainlist_enrichment.py,sha256=hxfYjI54hT2pBXeacmQkLJGEPyuaAwDtNL5sEVZURp8,22065
|
|
182
182
|
tests/test_cli.py,sha256=Pl4RC2xp1omiJUnL3Dza6pCmIoO29LJ0vGw33_ZpT5c,3980
|
|
183
183
|
tests/test_contract.py,sha256=tApHAxsfKGawYJWA9PhTNrOZUE0VVAq79ruIe3KxeWY,14412
|
|
184
|
+
tests/test_contract_cache.py,sha256=TYIYPwIm_pVsdDjXJj_9-yDah_RFYB3PBn_fyE-a_YU,8454
|
|
184
185
|
tests/test_db.py,sha256=dmbrupj0qlUeiiycZ2mzMFjf7HrDa6tcqMPY8zpiKIk,5710
|
|
185
|
-
tests/test_drain_coverage.py,sha256=
|
|
186
|
+
tests/test_drain_coverage.py,sha256=x-ANNt2YVJcuJApMe7VlzZE-1RRpSvGtDz5M_UXLc4I,18497
|
|
186
187
|
tests/test_erc20.py,sha256=kNEw1afpm5EbXRNXkjpkBNZIy7Af1nqGlztKH5IWAwU,3074
|
|
187
188
|
tests/test_gnosis_plugin.py,sha256=XMoHBCTrnVBq9bXYPzMUIrhr95caucMVRxooCjKrzjg,3454
|
|
188
189
|
tests/test_keys.py,sha256=Qk4n3QDZ2HjXYRvehdrSlvDS_q3NLRLMnCq45Eo1Q9o,17551
|
|
@@ -210,7 +211,7 @@ tests/test_service_manager_integration.py,sha256=I_BLUzEKrVTyg_8jqsUK0oFD3aQVPCR
|
|
|
210
211
|
tests/test_service_manager_structure.py,sha256=zK506ucCXCBHcjPYKrKEuK1bgq0xsbawyL8Y-wahXf8,868
|
|
211
212
|
tests/test_service_transaction.py,sha256=IeqYhmRD-pIXffBJrBQwfPx-qnfNEJs0iPM3eCb8MLo,7054
|
|
212
213
|
tests/test_staking_router.py,sha256=cnOtwWeQPu09kecVhlCf1WA4ONqs13OcQJhJCx2EOPY,3067
|
|
213
|
-
tests/test_staking_simple.py,sha256=
|
|
214
|
+
tests/test_staking_simple.py,sha256=LN1ehVpNlT2oGGNhj0B1DAmazoL5xRmSCHB5AUL8900,19643
|
|
214
215
|
tests/test_tables.py,sha256=1KQHgxuizoOrRxpubDdnzk9iaU5Lwyp3bcWP_hZD5uU,2686
|
|
215
216
|
tests/test_transaction_service.py,sha256=q2IQ6cJ6sZtzc_pVCM_dv0vW7LW2sONNrK5Pvrm63rU,12816
|
|
216
217
|
tests/test_transfer_multisend.py,sha256=PErjNqNwN66TMh4oVa307re64Ucccg1LkXqB0KlkmsI,6677
|
|
@@ -223,8 +224,8 @@ tests/test_utils.py,sha256=vkP49rYNI8BRzLpWR3WnKdDr8upeZjZcs7Rx0pjbQMo,1292
|
|
|
223
224
|
tests/test_workers.py,sha256=MInwdkFY5LdmFB3o1odIaSD7AQZb3263hNafO1De5PE,2793
|
|
224
225
|
tools/create_and_stake_service.py,sha256=1xwy_bJQI1j9yIQ968Oc9Db_F6mk1659LuuZntTASDE,3742
|
|
225
226
|
tools/verify_drain.py,sha256=PkMjblyOOAuQge88FwfEzRtCYeEtJxXhPBmtQYCoQ-8,6743
|
|
226
|
-
iwa-0.0.
|
|
227
|
-
iwa-0.0.
|
|
228
|
-
iwa-0.0.
|
|
229
|
-
iwa-0.0.
|
|
230
|
-
iwa-0.0.
|
|
227
|
+
iwa-0.0.65.dist-info/METADATA,sha256=E6lkx395V7EMKgNrvdvYWu4vQRbwFDv8Udj14n2UaR4,7337
|
|
228
|
+
iwa-0.0.65.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
229
|
+
iwa-0.0.65.dist-info/entry_points.txt,sha256=nwB6kscrfA7M00pYmL2j-sBH6eF6h2ga9IK1BZxdiyQ,241
|
|
230
|
+
iwa-0.0.65.dist-info/top_level.txt,sha256=kedS9cRUbm4JE2wYeabIXilhHjN8KCw0IGbqqqsw0Bs,16
|
|
231
|
+
iwa-0.0.65.dist-info/RECORD,,
|