wayfinder-paths 0.1.22__py3-none-any.whl → 0.1.24__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.
Potentially problematic release.
This version of wayfinder-paths might be problematic. Click here for more details.
- wayfinder_paths/__init__.py +0 -4
- wayfinder_paths/adapters/balance_adapter/README.md +0 -1
- wayfinder_paths/adapters/balance_adapter/adapter.py +313 -167
- wayfinder_paths/adapters/balance_adapter/manifest.yaml +8 -0
- wayfinder_paths/adapters/balance_adapter/test_adapter.py +41 -124
- wayfinder_paths/adapters/boros_adapter/__init__.py +17 -0
- wayfinder_paths/adapters/boros_adapter/adapter.py +1574 -0
- wayfinder_paths/adapters/boros_adapter/client.py +476 -0
- wayfinder_paths/adapters/boros_adapter/manifest.yaml +10 -0
- wayfinder_paths/adapters/boros_adapter/parsers.py +88 -0
- wayfinder_paths/adapters/boros_adapter/test_adapter.py +460 -0
- wayfinder_paths/adapters/boros_adapter/test_golden.py +156 -0
- wayfinder_paths/adapters/boros_adapter/types.py +70 -0
- wayfinder_paths/adapters/boros_adapter/utils.py +85 -0
- wayfinder_paths/adapters/brap_adapter/README.md +22 -75
- wayfinder_paths/adapters/brap_adapter/adapter.py +187 -576
- wayfinder_paths/adapters/brap_adapter/examples.json +21 -140
- wayfinder_paths/adapters/brap_adapter/manifest.yaml +9 -0
- wayfinder_paths/adapters/brap_adapter/test_adapter.py +6 -234
- wayfinder_paths/adapters/hyperlend_adapter/adapter.py +180 -92
- wayfinder_paths/adapters/hyperlend_adapter/manifest.yaml +9 -0
- wayfinder_paths/adapters/hyperlend_adapter/test_adapter.py +82 -14
- wayfinder_paths/adapters/hyperliquid_adapter/__init__.py +2 -9
- wayfinder_paths/adapters/hyperliquid_adapter/adapter.py +586 -61
- wayfinder_paths/adapters/hyperliquid_adapter/executor.py +47 -68
- wayfinder_paths/adapters/hyperliquid_adapter/manifest.yaml +14 -0
- wayfinder_paths/adapters/hyperliquid_adapter/paired_filler.py +2 -3
- wayfinder_paths/adapters/hyperliquid_adapter/test_adapter.py +17 -21
- wayfinder_paths/adapters/hyperliquid_adapter/test_adapter_live.py +3 -6
- wayfinder_paths/adapters/hyperliquid_adapter/test_executor.py +4 -8
- wayfinder_paths/adapters/hyperliquid_adapter/test_utils.py +2 -2
- wayfinder_paths/adapters/ledger_adapter/README.md +4 -1
- wayfinder_paths/adapters/ledger_adapter/adapter.py +3 -3
- wayfinder_paths/adapters/ledger_adapter/manifest.yaml +7 -0
- wayfinder_paths/adapters/ledger_adapter/test_adapter.py +1 -2
- wayfinder_paths/adapters/moonwell_adapter/adapter.py +649 -547
- wayfinder_paths/adapters/moonwell_adapter/manifest.yaml +14 -0
- wayfinder_paths/adapters/moonwell_adapter/test_adapter.py +160 -239
- wayfinder_paths/adapters/multicall_adapter/__init__.py +7 -0
- wayfinder_paths/adapters/multicall_adapter/adapter.py +166 -0
- wayfinder_paths/adapters/multicall_adapter/manifest.yaml +5 -0
- wayfinder_paths/adapters/multicall_adapter/test_adapter.py +97 -0
- wayfinder_paths/adapters/pendle_adapter/README.md +102 -0
- wayfinder_paths/adapters/pendle_adapter/__init__.py +7 -0
- wayfinder_paths/adapters/pendle_adapter/adapter.py +1992 -0
- wayfinder_paths/adapters/pendle_adapter/examples.json +11 -0
- wayfinder_paths/adapters/pendle_adapter/manifest.yaml +21 -0
- wayfinder_paths/adapters/pendle_adapter/test_adapter.py +666 -0
- wayfinder_paths/adapters/pool_adapter/manifest.yaml +6 -0
- wayfinder_paths/adapters/token_adapter/adapter.py +14 -0
- wayfinder_paths/adapters/token_adapter/examples.json +0 -4
- wayfinder_paths/adapters/token_adapter/manifest.yaml +7 -0
- wayfinder_paths/conftest.py +24 -17
- wayfinder_paths/core/__init__.py +0 -3
- wayfinder_paths/core/adapters/BaseAdapter.py +0 -25
- wayfinder_paths/core/adapters/models.py +17 -7
- wayfinder_paths/core/clients/BRAPClient.py +4 -1
- wayfinder_paths/core/clients/ClientManager.py +0 -7
- wayfinder_paths/core/clients/LedgerClient.py +196 -172
- wayfinder_paths/core/clients/TokenClient.py +47 -1
- wayfinder_paths/core/clients/WayfinderClient.py +1 -3
- wayfinder_paths/core/clients/__init__.py +0 -5
- wayfinder_paths/core/clients/protocols.py +21 -35
- wayfinder_paths/core/clients/test_ledger_client.py +448 -0
- wayfinder_paths/core/config.py +10 -162
- wayfinder_paths/core/constants/__init__.py +73 -2
- wayfinder_paths/core/constants/base.py +8 -17
- wayfinder_paths/core/constants/chains.py +36 -0
- wayfinder_paths/core/constants/contracts.py +52 -0
- wayfinder_paths/core/constants/erc20_abi.py +0 -1
- wayfinder_paths/core/constants/hyperlend_abi.py +0 -4
- wayfinder_paths/core/constants/hyperliquid.py +16 -0
- wayfinder_paths/core/constants/moonwell_abi.py +0 -15
- wayfinder_paths/core/constants/tokens.py +9 -0
- wayfinder_paths/core/engine/manifest.py +66 -0
- wayfinder_paths/core/strategies/Strategy.py +0 -71
- wayfinder_paths/core/strategies/__init__.py +10 -1
- wayfinder_paths/core/strategies/opa_loop.py +167 -0
- wayfinder_paths/core/utils/evm_helpers.py +5 -15
- wayfinder_paths/core/utils/test_transaction.py +289 -0
- wayfinder_paths/core/utils/tokens.py +28 -0
- wayfinder_paths/core/utils/transaction.py +57 -8
- wayfinder_paths/core/utils/web3.py +8 -3
- wayfinder_paths/mcp/__init__.py +5 -0
- wayfinder_paths/mcp/preview.py +185 -0
- wayfinder_paths/mcp/scripting.py +84 -0
- wayfinder_paths/mcp/server.py +52 -0
- wayfinder_paths/mcp/state/profile_store.py +195 -0
- wayfinder_paths/mcp/state/store.py +89 -0
- wayfinder_paths/mcp/test_scripting.py +267 -0
- wayfinder_paths/mcp/tools/__init__.py +0 -0
- wayfinder_paths/mcp/tools/balances.py +290 -0
- wayfinder_paths/mcp/tools/discovery.py +158 -0
- wayfinder_paths/mcp/tools/execute.py +770 -0
- wayfinder_paths/mcp/tools/hyperliquid.py +931 -0
- wayfinder_paths/mcp/tools/quotes.py +288 -0
- wayfinder_paths/mcp/tools/run_script.py +286 -0
- wayfinder_paths/mcp/tools/strategies.py +188 -0
- wayfinder_paths/mcp/tools/tokens.py +46 -0
- wayfinder_paths/mcp/tools/wallets.py +354 -0
- wayfinder_paths/mcp/utils.py +129 -0
- wayfinder_paths/policies/enso.py +1 -2
- wayfinder_paths/policies/hyper_evm.py +6 -3
- wayfinder_paths/policies/hyperlend.py +1 -2
- wayfinder_paths/policies/hyperliquid.py +1 -1
- wayfinder_paths/policies/lifi.py +18 -0
- wayfinder_paths/policies/moonwell.py +12 -7
- wayfinder_paths/policies/prjx.py +1 -3
- wayfinder_paths/policies/util.py +8 -2
- wayfinder_paths/run_strategy.py +97 -300
- wayfinder_paths/strategies/basis_trading_strategy/constants.py +3 -1
- wayfinder_paths/strategies/basis_trading_strategy/strategy.py +47 -133
- wayfinder_paths/strategies/basis_trading_strategy/test_strategy.py +24 -53
- wayfinder_paths/strategies/boros_hype_strategy/__init__.py +3 -0
- wayfinder_paths/strategies/boros_hype_strategy/boros_ops_mixin.py +450 -0
- wayfinder_paths/strategies/boros_hype_strategy/constants.py +255 -0
- wayfinder_paths/strategies/boros_hype_strategy/examples.json +37 -0
- wayfinder_paths/strategies/boros_hype_strategy/hyperevm_ops_mixin.py +114 -0
- wayfinder_paths/strategies/boros_hype_strategy/hyperliquid_ops_mixin.py +642 -0
- wayfinder_paths/strategies/boros_hype_strategy/manifest.yaml +36 -0
- wayfinder_paths/strategies/boros_hype_strategy/planner.py +460 -0
- wayfinder_paths/strategies/boros_hype_strategy/risk_ops_mixin.py +886 -0
- wayfinder_paths/strategies/boros_hype_strategy/snapshot_mixin.py +494 -0
- wayfinder_paths/strategies/boros_hype_strategy/strategy.py +1194 -0
- wayfinder_paths/strategies/boros_hype_strategy/test_planner_golden.py +374 -0
- wayfinder_paths/{templates/strategy → strategies/boros_hype_strategy}/test_strategy.py +99 -63
- wayfinder_paths/strategies/boros_hype_strategy/types.py +365 -0
- wayfinder_paths/strategies/boros_hype_strategy/withdraw_mixin.py +997 -0
- wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py +15 -23
- wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py +27 -62
- wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/strategy.py +84 -58
- wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/test_strategy.py +5 -15
- wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py +69 -164
- wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py +43 -76
- wayfinder_paths/tests/test_mcp_quote_swap.py +165 -0
- wayfinder_paths/tests/test_test_coverage.py +1 -4
- wayfinder_paths-0.1.24.dist-info/METADATA +378 -0
- wayfinder_paths-0.1.24.dist-info/RECORD +185 -0
- {wayfinder_paths-0.1.22.dist-info → wayfinder_paths-0.1.24.dist-info}/WHEEL +1 -1
- wayfinder_paths/core/clients/WalletClient.py +0 -41
- wayfinder_paths/core/engine/StrategyJob.py +0 -110
- wayfinder_paths/core/services/test_local_evm_txn.py +0 -145
- wayfinder_paths/scripts/create_strategy.py +0 -139
- wayfinder_paths/scripts/make_wallets.py +0 -142
- wayfinder_paths/templates/adapter/README.md +0 -150
- wayfinder_paths/templates/adapter/adapter.py +0 -16
- wayfinder_paths/templates/adapter/examples.json +0 -8
- wayfinder_paths/templates/adapter/test_adapter.py +0 -30
- wayfinder_paths/templates/strategy/README.md +0 -186
- wayfinder_paths/templates/strategy/examples.json +0 -11
- wayfinder_paths/templates/strategy/strategy.py +0 -35
- wayfinder_paths/tests/test_smoke_manifest.py +0 -63
- wayfinder_paths-0.1.22.dist-info/METADATA +0 -355
- wayfinder_paths-0.1.22.dist-info/RECORD +0 -129
- /wayfinder_paths/{scripts → mcp/state}/__init__.py +0 -0
- {wayfinder_paths-0.1.22.dist-info → wayfinder_paths-0.1.24.dist-info}/LICENSE +0 -0
|
@@ -1,17 +1,88 @@
|
|
|
1
|
-
from .base import (
|
|
2
|
-
|
|
1
|
+
from wayfinder_paths.core.constants.base import (
|
|
2
|
+
ADAPTER_BALANCE,
|
|
3
|
+
ADAPTER_BRAP,
|
|
4
|
+
ADAPTER_HYPERLEND,
|
|
5
|
+
ADAPTER_HYPERLIQUID,
|
|
6
|
+
ADAPTER_LEDGER,
|
|
7
|
+
ADAPTER_MOONWELL,
|
|
8
|
+
ADAPTER_POOL,
|
|
9
|
+
ADAPTER_TOKEN,
|
|
10
|
+
DEFAULT_HTTP_TIMEOUT,
|
|
3
11
|
DEFAULT_NATIVE_GAS_UNITS,
|
|
12
|
+
DEFAULT_PAGINATION_LIMIT,
|
|
4
13
|
DEFAULT_SLIPPAGE,
|
|
5
14
|
GAS_BUFFER_MULTIPLIER,
|
|
15
|
+
MANTISSA,
|
|
16
|
+
MAX_UINT256,
|
|
6
17
|
ONE_GWEI,
|
|
18
|
+
SECONDS_PER_YEAR,
|
|
19
|
+
SUGGESTED_GAS_PRICE_MULTIPLIER,
|
|
20
|
+
SUGGESTED_PRIORITY_FEE_MULTIPLIER,
|
|
21
|
+
)
|
|
22
|
+
from wayfinder_paths.core.constants.chains import (
|
|
23
|
+
CHAIN_CODE_TO_ID,
|
|
24
|
+
CHAIN_ID_ARBITRUM,
|
|
25
|
+
CHAIN_ID_AVALANCHE,
|
|
26
|
+
CHAIN_ID_BASE,
|
|
27
|
+
CHAIN_ID_BSC,
|
|
28
|
+
CHAIN_ID_ETHEREUM,
|
|
29
|
+
CHAIN_ID_HYPEREVM,
|
|
30
|
+
CHAIN_ID_POLYGON,
|
|
31
|
+
POA_MIDDLEWARE_CHAIN_IDS,
|
|
32
|
+
PRE_EIP_1559_CHAIN_IDS,
|
|
33
|
+
SUPPORTED_CHAINS,
|
|
34
|
+
)
|
|
35
|
+
from wayfinder_paths.core.constants.contracts import (
|
|
36
|
+
NATIVE_TOKEN_SENTINEL,
|
|
7
37
|
ZERO_ADDRESS,
|
|
8
38
|
)
|
|
9
39
|
|
|
40
|
+
from .hyperliquid import (
|
|
41
|
+
ARBITRUM_USDC_ADDRESS,
|
|
42
|
+
ARBITRUM_USDC_TOKEN_ID,
|
|
43
|
+
DEFAULT_HYPERLIQUID_BUILDER_FEE,
|
|
44
|
+
DEFAULT_HYPERLIQUID_BUILDER_FEE_TENTHS_BP,
|
|
45
|
+
HYPE_FEE_WALLET,
|
|
46
|
+
HYPERLIQUID_BRIDGE_ADDRESS,
|
|
47
|
+
)
|
|
48
|
+
|
|
10
49
|
__all__ = [
|
|
50
|
+
"NATIVE_TOKEN_SENTINEL",
|
|
11
51
|
"ZERO_ADDRESS",
|
|
12
52
|
"CHAIN_CODE_TO_ID",
|
|
13
53
|
"DEFAULT_NATIVE_GAS_UNITS",
|
|
14
54
|
"GAS_BUFFER_MULTIPLIER",
|
|
15
55
|
"ONE_GWEI",
|
|
56
|
+
"SUGGESTED_PRIORITY_FEE_MULTIPLIER",
|
|
57
|
+
"SUGGESTED_GAS_PRICE_MULTIPLIER",
|
|
16
58
|
"DEFAULT_SLIPPAGE",
|
|
59
|
+
"DEFAULT_HTTP_TIMEOUT",
|
|
60
|
+
"DEFAULT_PAGINATION_LIMIT",
|
|
61
|
+
"MANTISSA",
|
|
62
|
+
"SECONDS_PER_YEAR",
|
|
63
|
+
"MAX_UINT256",
|
|
64
|
+
"ADAPTER_BALANCE",
|
|
65
|
+
"ADAPTER_BRAP",
|
|
66
|
+
"ADAPTER_MOONWELL",
|
|
67
|
+
"ADAPTER_HYPERLIQUID",
|
|
68
|
+
"ADAPTER_POOL",
|
|
69
|
+
"ADAPTER_TOKEN",
|
|
70
|
+
"ADAPTER_LEDGER",
|
|
71
|
+
"ADAPTER_HYPERLEND",
|
|
72
|
+
"CHAIN_ID_ETHEREUM",
|
|
73
|
+
"CHAIN_ID_BASE",
|
|
74
|
+
"CHAIN_ID_ARBITRUM",
|
|
75
|
+
"CHAIN_ID_BSC",
|
|
76
|
+
"CHAIN_ID_POLYGON",
|
|
77
|
+
"CHAIN_ID_AVALANCHE",
|
|
78
|
+
"CHAIN_ID_HYPEREVM",
|
|
79
|
+
"SUPPORTED_CHAINS",
|
|
80
|
+
"POA_MIDDLEWARE_CHAIN_IDS",
|
|
81
|
+
"PRE_EIP_1559_CHAIN_IDS",
|
|
82
|
+
"HYPERLIQUID_BRIDGE_ADDRESS",
|
|
83
|
+
"ARBITRUM_USDC_ADDRESS",
|
|
84
|
+
"ARBITRUM_USDC_TOKEN_ID",
|
|
85
|
+
"HYPE_FEE_WALLET",
|
|
86
|
+
"DEFAULT_HYPERLIQUID_BUILDER_FEE_TENTHS_BP",
|
|
87
|
+
"DEFAULT_HYPERLIQUID_BUILDER_FEE",
|
|
17
88
|
]
|
|
@@ -1,21 +1,9 @@
|
|
|
1
|
-
ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"
|
|
2
|
-
|
|
3
|
-
# Chain code to EVM chain id mapping
|
|
4
|
-
CHAIN_CODE_TO_ID = {
|
|
5
|
-
"base": 8453,
|
|
6
|
-
"arbitrum": 42161,
|
|
7
|
-
"arbitrum-one": 42161,
|
|
8
|
-
"ethereum": 1,
|
|
9
|
-
"mainnet": 1,
|
|
10
|
-
"hyperevm": 999,
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
# Gas/defaults
|
|
14
1
|
DEFAULT_NATIVE_GAS_UNITS = 21000
|
|
15
|
-
# Fallback gas limit used only when RPC gas estimation fails for non-revert reasons.
|
|
16
|
-
# Must be high enough for typical DeFi interactions (lending, swaps, etc.).
|
|
17
2
|
GAS_BUFFER_MULTIPLIER = 1.1
|
|
18
3
|
ONE_GWEI = 1_000_000_000
|
|
4
|
+
SUGGESTED_PRIORITY_FEE_MULTIPLIER = 1.5
|
|
5
|
+
SUGGESTED_GAS_PRICE_MULTIPLIER = 1.5
|
|
6
|
+
|
|
19
7
|
DEFAULT_SLIPPAGE = 0.005
|
|
20
8
|
|
|
21
9
|
# Timeout constants (seconds)
|
|
@@ -23,8 +11,8 @@ DEFAULT_SLIPPAGE = 0.005
|
|
|
23
11
|
# even if the transaction is eventually mined. A longer timeout reduces false negatives that
|
|
24
12
|
# can lead to unsafe retry behavior (nonce gaps, duplicate swaps, etc.).
|
|
25
13
|
DEFAULT_HTTP_TIMEOUT = 30.0 # HTTP client timeout
|
|
14
|
+
DEFAULT_TRANSACTION_TIMEOUT = 180 # Transaction receipt timeout (seconds)
|
|
26
15
|
|
|
27
|
-
# Adapter type identifiers
|
|
28
16
|
ADAPTER_BALANCE = "BALANCE"
|
|
29
17
|
ADAPTER_BRAP = "BRAP"
|
|
30
18
|
ADAPTER_MOONWELL = "MOONWELL"
|
|
@@ -34,5 +22,8 @@ ADAPTER_TOKEN = "TOKEN"
|
|
|
34
22
|
ADAPTER_LEDGER = "LEDGER"
|
|
35
23
|
ADAPTER_HYPERLEND = "HYPERLEND"
|
|
36
24
|
|
|
37
|
-
# Pagination defaults
|
|
38
25
|
DEFAULT_PAGINATION_LIMIT = 50
|
|
26
|
+
|
|
27
|
+
MANTISSA = 10**18
|
|
28
|
+
SECONDS_PER_YEAR = 365 * 24 * 60 * 60
|
|
29
|
+
MAX_UINT256 = 2**256 - 1
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
CHAIN_ID_ETHEREUM = 1
|
|
2
|
+
CHAIN_ID_BASE = 8453
|
|
3
|
+
CHAIN_ID_ARBITRUM = 42161
|
|
4
|
+
CHAIN_ID_BSC = 56
|
|
5
|
+
CHAIN_ID_POLYGON = 137
|
|
6
|
+
CHAIN_ID_AVALANCHE = 43114
|
|
7
|
+
CHAIN_ID_HYPEREVM = 999
|
|
8
|
+
|
|
9
|
+
CHAIN_CODE_TO_ID = {
|
|
10
|
+
"base": CHAIN_ID_BASE,
|
|
11
|
+
"arbitrum": CHAIN_ID_ARBITRUM,
|
|
12
|
+
"arbitrum-one": CHAIN_ID_ARBITRUM,
|
|
13
|
+
"ethereum": CHAIN_ID_ETHEREUM,
|
|
14
|
+
"mainnet": CHAIN_ID_ETHEREUM,
|
|
15
|
+
"hyperevm": CHAIN_ID_HYPEREVM,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
SUPPORTED_CHAINS = [
|
|
19
|
+
CHAIN_ID_ETHEREUM,
|
|
20
|
+
CHAIN_ID_BASE,
|
|
21
|
+
CHAIN_ID_BSC,
|
|
22
|
+
CHAIN_ID_ARBITRUM,
|
|
23
|
+
CHAIN_ID_POLYGON,
|
|
24
|
+
CHAIN_ID_HYPEREVM,
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
POA_MIDDLEWARE_CHAIN_IDS: set[int] = {
|
|
28
|
+
CHAIN_ID_BSC,
|
|
29
|
+
CHAIN_ID_POLYGON,
|
|
30
|
+
CHAIN_ID_AVALANCHE,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
PRE_EIP_1559_CHAIN_IDS: set[int] = {
|
|
34
|
+
CHAIN_ID_BSC,
|
|
35
|
+
CHAIN_ID_ARBITRUM,
|
|
36
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from eth_utils import to_checksum_address
|
|
2
|
+
|
|
3
|
+
ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"
|
|
4
|
+
NATIVE_TOKEN_SENTINEL = to_checksum_address(
|
|
5
|
+
"0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
BASE_WETH = to_checksum_address("0x4200000000000000000000000000000000000006")
|
|
9
|
+
BASE_USDC = to_checksum_address("0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913")
|
|
10
|
+
BASE_WSTETH = to_checksum_address("0xc1CBa3fCea344f92D9239c08C0568f6F2F0ee452")
|
|
11
|
+
|
|
12
|
+
MOONWELL_M_USDC = to_checksum_address("0xEdc817A28E8B93B03976FBd4a3dDBc9f7D176c22")
|
|
13
|
+
MOONWELL_M_WETH = to_checksum_address("0x628ff693426583D9a7FB391E54366292F509D457")
|
|
14
|
+
MOONWELL_M_WSTETH = to_checksum_address("0x627Fe393Bc6EdDA28e99AE648fD6fF362514304b")
|
|
15
|
+
MOONWELL_COMPTROLLER = to_checksum_address("0xfBb21d0380beE3312B33c4353c8936a0F13EF26C")
|
|
16
|
+
MOONWELL_REWARD_DISTRIBUTOR = to_checksum_address(
|
|
17
|
+
"0xe9005b078701e2A0948D2EaC43010D35870Ad9d2"
|
|
18
|
+
)
|
|
19
|
+
MOONWELL_WELL_TOKEN = to_checksum_address("0xA88594D404727625A9437C3f886C7643872296AE")
|
|
20
|
+
|
|
21
|
+
ENSO_ROUTER = to_checksum_address("0xF75584eF6673aD213a685a1B58Cc0330B8eA22Cf")
|
|
22
|
+
|
|
23
|
+
HYPEREVM_WHYPE = to_checksum_address("0x5555555555555555555555555555555555555555")
|
|
24
|
+
HYPERCORE_SENTINEL_ADDRESS = to_checksum_address(
|
|
25
|
+
"0x2222222222222222222222222222222222222222"
|
|
26
|
+
)
|
|
27
|
+
HYPERCORE_SENTINEL_VALUE = 100_000_000_000
|
|
28
|
+
|
|
29
|
+
HYPERLEND_POOL = to_checksum_address("0x00A89d7a5A02160f20150EbEA7a2b5E4879A1A8b")
|
|
30
|
+
HYPERLEND_WRAPPED_TOKEN_GATEWAY = to_checksum_address(
|
|
31
|
+
"0x49558c794ea2aC8974C9F27886DDfAa951E99171"
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
PRJX_ROUTER = to_checksum_address("0x1EbDFC75FfE3ba3de61E7138a3E8706aC841Af9B")
|
|
35
|
+
PRJX_NPM = to_checksum_address("0xeaD19AE861c29bBb2101E834922B2FEee69B9091")
|
|
36
|
+
|
|
37
|
+
ARBITRUM_USDC = to_checksum_address("0xaf88d065e77c8cC2239327C5EDb3A432268e5831")
|
|
38
|
+
|
|
39
|
+
HYPERLIQUID_BRIDGE = to_checksum_address("0x2Df1c51E09aECF9cacB7bc98cB1742757f163dF7")
|
|
40
|
+
|
|
41
|
+
BOROS_ROUTER = to_checksum_address("0x8080808080dab95efed788a9214e400ba552def6")
|
|
42
|
+
BOROS_MARKET_HUB = to_checksum_address("0x1080808080f145b14228443212e62447c112adad")
|
|
43
|
+
|
|
44
|
+
USDT_ETHEREUM = to_checksum_address("0xdAC17F958D2ee523a2206206994597C13D831ec7")
|
|
45
|
+
USDT_POLYGON = to_checksum_address("0xc2132D05D31c914a87C6611C10748AEb04B58e8F")
|
|
46
|
+
USDT_BSC = to_checksum_address("0x55d398326f99059fF775485246999027B3197955")
|
|
47
|
+
|
|
48
|
+
TOKENS_REQUIRING_APPROVAL_RESET: set[tuple[int, str]] = {
|
|
49
|
+
(1, USDT_ETHEREUM),
|
|
50
|
+
(137, USDT_POLYGON),
|
|
51
|
+
(56, USDT_BSC),
|
|
52
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# Minimal Pool ABI for supply and deposit operations
|
|
2
1
|
POOL_ABI = [
|
|
3
2
|
{
|
|
4
3
|
"name": "supply",
|
|
@@ -37,7 +36,6 @@ POOL_ABI = [
|
|
|
37
36
|
},
|
|
38
37
|
]
|
|
39
38
|
|
|
40
|
-
# Protocol Data Provider ABI for reserve token addresses and user data
|
|
41
39
|
PROTOCOL_DATA_PROVIDER_ABI = [
|
|
42
40
|
{
|
|
43
41
|
"type": "function",
|
|
@@ -71,7 +69,6 @@ PROTOCOL_DATA_PROVIDER_ABI = [
|
|
|
71
69
|
},
|
|
72
70
|
]
|
|
73
71
|
|
|
74
|
-
# Wrapped Token Gateway ABI for native token operations
|
|
75
72
|
WRAPPED_TOKEN_GATEWAY_ABI = [
|
|
76
73
|
{
|
|
77
74
|
"type": "function",
|
|
@@ -126,7 +123,6 @@ WRAPPED_TOKEN_GATEWAY_ABI = [
|
|
|
126
123
|
},
|
|
127
124
|
]
|
|
128
125
|
|
|
129
|
-
# WETH ABI for native token wrapping
|
|
130
126
|
WETH_ABI = [
|
|
131
127
|
{
|
|
132
128
|
"inputs": [],
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
HYPERLIQUID_BRIDGE_ADDRESS: str = "0x2Df1c51E09aECF9cacB7bc98cB1742757f163dF7"
|
|
6
|
+
ARBITRUM_USDC_ADDRESS: str = "0xaf88d065e77c8cC2239327C5EDb3A432268e5831"
|
|
7
|
+
ARBITRUM_USDC_TOKEN_ID: str = "usd-coin-arbitrum"
|
|
8
|
+
HYPE_FEE_WALLET: str = "0xaA1D89f333857eD78F8434CC4f896A9293EFE65c"
|
|
9
|
+
|
|
10
|
+
# Tenths of a basis point: 30 -> 0.030% (3 bps)
|
|
11
|
+
DEFAULT_HYPERLIQUID_BUILDER_FEE_TENTHS_BP: int = 30
|
|
12
|
+
|
|
13
|
+
DEFAULT_HYPERLIQUID_BUILDER_FEE: dict[str, Any] = {
|
|
14
|
+
"b": HYPE_FEE_WALLET,
|
|
15
|
+
"f": DEFAULT_HYPERLIQUID_BUILDER_FEE_TENTHS_BP,
|
|
16
|
+
}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
# mToken (CErc20Delegator) ABI - for lending, borrowing, and position management
|
|
2
1
|
MTOKEN_ABI = [
|
|
3
|
-
# Lend (supply) tokens by minting mTokens
|
|
4
2
|
{
|
|
5
3
|
"name": "mint",
|
|
6
4
|
"type": "function",
|
|
@@ -8,7 +6,6 @@ MTOKEN_ABI = [
|
|
|
8
6
|
"inputs": [{"name": "mintAmount", "type": "uint256"}],
|
|
9
7
|
"outputs": [{"name": "", "type": "uint256"}],
|
|
10
8
|
},
|
|
11
|
-
# Withdraw (redeem) underlying by burning mTokens
|
|
12
9
|
{
|
|
13
10
|
"name": "redeem",
|
|
14
11
|
"type": "function",
|
|
@@ -16,7 +13,6 @@ MTOKEN_ABI = [
|
|
|
16
13
|
"inputs": [{"name": "redeemTokens", "type": "uint256"}],
|
|
17
14
|
"outputs": [{"name": "", "type": "uint256"}],
|
|
18
15
|
},
|
|
19
|
-
# Withdraw exact underlying amount
|
|
20
16
|
{
|
|
21
17
|
"name": "redeemUnderlying",
|
|
22
18
|
"type": "function",
|
|
@@ -24,7 +20,6 @@ MTOKEN_ABI = [
|
|
|
24
20
|
"inputs": [{"name": "redeemAmount", "type": "uint256"}],
|
|
25
21
|
"outputs": [{"name": "", "type": "uint256"}],
|
|
26
22
|
},
|
|
27
|
-
# Borrow underlying tokens
|
|
28
23
|
{
|
|
29
24
|
"name": "borrow",
|
|
30
25
|
"type": "function",
|
|
@@ -32,7 +27,6 @@ MTOKEN_ABI = [
|
|
|
32
27
|
"inputs": [{"name": "borrowAmount", "type": "uint256"}],
|
|
33
28
|
"outputs": [{"name": "", "type": "uint256"}],
|
|
34
29
|
},
|
|
35
|
-
# Repay borrowed tokens
|
|
36
30
|
{
|
|
37
31
|
"name": "repayBorrow",
|
|
38
32
|
"type": "function",
|
|
@@ -124,7 +118,6 @@ MTOKEN_ABI = [
|
|
|
124
118
|
"inputs": [],
|
|
125
119
|
"outputs": [{"name": "", "type": "uint256"}],
|
|
126
120
|
},
|
|
127
|
-
# Accrue interest
|
|
128
121
|
{
|
|
129
122
|
"name": "accrueInterest",
|
|
130
123
|
"type": "function",
|
|
@@ -141,9 +134,7 @@ MTOKEN_ABI = [
|
|
|
141
134
|
},
|
|
142
135
|
]
|
|
143
136
|
|
|
144
|
-
# Comptroller ABI - for collateral management and account liquidity
|
|
145
137
|
COMPTROLLER_ABI = [
|
|
146
|
-
# Enable a market as collateral
|
|
147
138
|
{
|
|
148
139
|
"name": "enterMarkets",
|
|
149
140
|
"type": "function",
|
|
@@ -151,7 +142,6 @@ COMPTROLLER_ABI = [
|
|
|
151
142
|
"inputs": [{"name": "mTokens", "type": "address[]"}],
|
|
152
143
|
"outputs": [{"name": "", "type": "uint256[]"}],
|
|
153
144
|
},
|
|
154
|
-
# Disable a market as collateral
|
|
155
145
|
{
|
|
156
146
|
"name": "exitMarket",
|
|
157
147
|
"type": "function",
|
|
@@ -234,7 +224,6 @@ COMPTROLLER_ABI = [
|
|
|
234
224
|
"inputs": [],
|
|
235
225
|
"outputs": [{"name": "", "type": "uint256"}],
|
|
236
226
|
},
|
|
237
|
-
# Claim rewards for a user (called on comptroller in some versions)
|
|
238
227
|
{
|
|
239
228
|
"name": "claimReward",
|
|
240
229
|
"type": "function",
|
|
@@ -244,9 +233,7 @@ COMPTROLLER_ABI = [
|
|
|
244
233
|
},
|
|
245
234
|
]
|
|
246
235
|
|
|
247
|
-
# Reward Distributor ABI - for claiming WELL rewards
|
|
248
236
|
REWARD_DISTRIBUTOR_ABI = [
|
|
249
|
-
# Claim rewards for all markets
|
|
250
237
|
{
|
|
251
238
|
"name": "claimReward",
|
|
252
239
|
"type": "function",
|
|
@@ -254,7 +241,6 @@ REWARD_DISTRIBUTOR_ABI = [
|
|
|
254
241
|
"inputs": [],
|
|
255
242
|
"outputs": [],
|
|
256
243
|
},
|
|
257
|
-
# Claim rewards for specific holder and markets
|
|
258
244
|
{
|
|
259
245
|
"name": "claimReward",
|
|
260
246
|
"type": "function",
|
|
@@ -350,7 +336,6 @@ REWARD_DISTRIBUTOR_ABI = [
|
|
|
350
336
|
},
|
|
351
337
|
]
|
|
352
338
|
|
|
353
|
-
# WETH ABI for wrapping/unwrapping ETH
|
|
354
339
|
WETH_ABI = [
|
|
355
340
|
{
|
|
356
341
|
"name": "deposit",
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
TOKEN_ID_USDC_BASE = "usd-coin-base"
|
|
2
|
+
TOKEN_ID_WETH_BASE = "l2-standard-bridged-weth-base-base"
|
|
3
|
+
TOKEN_ID_WSTETH_BASE = "superbridge-bridged-wsteth-base-base"
|
|
4
|
+
TOKEN_ID_ETH_BASE = "ethereum-base"
|
|
5
|
+
TOKEN_ID_WELL_BASE = "moonwell-artemis-base"
|
|
6
|
+
|
|
7
|
+
TOKEN_ID_STETH = "staked-ether-ethereum"
|
|
8
|
+
|
|
9
|
+
TOKEN_ID_USDC_ARBITRUM = "usd-coin-arbitrum"
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
import yaml
|
|
4
|
+
from pydantic import BaseModel, Field, validator
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class AdapterRequirement(BaseModel):
|
|
8
|
+
name: str = Field(
|
|
9
|
+
..., description="Adapter symbolic name (e.g., BALANCE, HYPERLIQUID)"
|
|
10
|
+
)
|
|
11
|
+
capabilities: list[str] = Field(default_factory=list)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class StrategyManifest(BaseModel):
|
|
15
|
+
schema_version: str = Field(default="0.1")
|
|
16
|
+
entrypoint: str = Field(
|
|
17
|
+
...,
|
|
18
|
+
description="Python path to class, e.g. strategies.funding_rate_strategy.FundingRateStrategy",
|
|
19
|
+
)
|
|
20
|
+
name: str | None = Field(
|
|
21
|
+
default=None,
|
|
22
|
+
description="Unique name identifier for this strategy instance. Used to look up dedicated wallet in wallets.json by label.",
|
|
23
|
+
)
|
|
24
|
+
permissions: dict[str, Any] = Field(default_factory=dict)
|
|
25
|
+
adapters: list[AdapterRequirement] = Field(default_factory=list)
|
|
26
|
+
|
|
27
|
+
@validator("entrypoint")
|
|
28
|
+
def validate_entrypoint(cls, v: str) -> str:
|
|
29
|
+
if "." not in v:
|
|
30
|
+
raise ValueError(
|
|
31
|
+
"entrypoint must be a full import path to a Strategy class"
|
|
32
|
+
)
|
|
33
|
+
return v
|
|
34
|
+
|
|
35
|
+
@validator("permissions")
|
|
36
|
+
def validate_permissions(cls, v: dict) -> dict:
|
|
37
|
+
if "policy" not in v:
|
|
38
|
+
raise ValueError("permissions.policy is required")
|
|
39
|
+
if not v["policy"]:
|
|
40
|
+
raise ValueError("permissions.policy cannot be empty")
|
|
41
|
+
return v
|
|
42
|
+
|
|
43
|
+
@validator("adapters")
|
|
44
|
+
def validate_adapters(cls, v: list) -> list:
|
|
45
|
+
if not v:
|
|
46
|
+
raise ValueError("adapters cannot be empty")
|
|
47
|
+
return v
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def load_strategy_manifest(path: str) -> StrategyManifest:
|
|
51
|
+
with open(path) as f:
|
|
52
|
+
data = yaml.safe_load(f)
|
|
53
|
+
return StrategyManifest(**data)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def load_manifest(path: str) -> StrategyManifest:
|
|
57
|
+
"""Legacy function for backward compatibility."""
|
|
58
|
+
return load_strategy_manifest(path)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def validate_manifest(manifest: StrategyManifest) -> None:
|
|
62
|
+
# Simple v0.1 rules: require at least one adapter and permissions.policy
|
|
63
|
+
if not manifest.adapters:
|
|
64
|
+
raise ValueError("Manifest must declare at least one adapter")
|
|
65
|
+
if "policy" not in manifest.permissions:
|
|
66
|
+
raise ValueError("Manifest.permissions must include 'policy'")
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import traceback
|
|
4
3
|
from abc import ABC, abstractmethod
|
|
5
4
|
from collections.abc import Awaitable, Callable
|
|
6
5
|
from typing import Any, TypedDict
|
|
@@ -56,7 +55,6 @@ class Strategy(ABC):
|
|
|
56
55
|
strategy_wallet_signing_callback: Callable[[dict], Awaitable[str]]
|
|
57
56
|
| None = None,
|
|
58
57
|
):
|
|
59
|
-
self.adapters = {}
|
|
60
58
|
self.ledger_adapter = None
|
|
61
59
|
self.logger = logger.bind(strategy=self.__class__.__name__)
|
|
62
60
|
self.config = config
|
|
@@ -66,12 +64,6 @@ class Strategy(ABC):
|
|
|
66
64
|
async def setup(self) -> None:
|
|
67
65
|
pass
|
|
68
66
|
|
|
69
|
-
async def log(self, msg: str) -> None:
|
|
70
|
-
self.logger.info(msg)
|
|
71
|
-
|
|
72
|
-
async def quote(self) -> None:
|
|
73
|
-
pass
|
|
74
|
-
|
|
75
67
|
def _get_strategy_wallet_address(self) -> str:
|
|
76
68
|
strategy_wallet = self.config.get("strategy_wallet")
|
|
77
69
|
if not strategy_wallet or not isinstance(strategy_wallet, dict):
|
|
@@ -95,16 +87,6 @@ class Strategy(ABC):
|
|
|
95
87
|
pass
|
|
96
88
|
|
|
97
89
|
async def withdraw(self, **kwargs) -> StatusTuple:
|
|
98
|
-
if hasattr(self, "ledger_adapter") and self.ledger_adapter:
|
|
99
|
-
while self.ledger_adapter.positions.operations:
|
|
100
|
-
node = self.ledger_adapter.positions.operations[-1]
|
|
101
|
-
adapter = self.adapters.get(node.adapter)
|
|
102
|
-
if adapter and hasattr(adapter, "unwind_op"):
|
|
103
|
-
await adapter.unwind_op(node)
|
|
104
|
-
self.ledger_adapter.positions.operations.pop()
|
|
105
|
-
|
|
106
|
-
await self.ledger_adapter.save()
|
|
107
|
-
|
|
108
90
|
return (True, "Withdrawal complete")
|
|
109
91
|
|
|
110
92
|
@abstractmethod
|
|
@@ -132,59 +114,6 @@ class Strategy(ABC):
|
|
|
132
114
|
|
|
133
115
|
return status
|
|
134
116
|
|
|
135
|
-
def register_adapters(self, adapters: list[Any]) -> None:
|
|
136
|
-
self.adapters = {}
|
|
137
|
-
for adapter in adapters:
|
|
138
|
-
if hasattr(adapter, "adapter_type"):
|
|
139
|
-
self.adapters[adapter.adapter_type] = adapter
|
|
140
|
-
elif hasattr(adapter, "__class__"):
|
|
141
|
-
self.adapters[adapter.__class__.__name__] = adapter
|
|
142
|
-
|
|
143
|
-
def unwind_on_error(
|
|
144
|
-
self, func: Callable[..., Awaitable[StatusTuple]]
|
|
145
|
-
) -> Callable[..., Awaitable[StatusTuple]]:
|
|
146
|
-
async def wrapper(*args: Any, **kwargs: Any) -> StatusTuple:
|
|
147
|
-
try:
|
|
148
|
-
return await func(*args, **kwargs)
|
|
149
|
-
except Exception:
|
|
150
|
-
trace = traceback.format_exc()
|
|
151
|
-
try:
|
|
152
|
-
await self.withdraw()
|
|
153
|
-
return (
|
|
154
|
-
False,
|
|
155
|
-
f"Strategy failed during operation and was unwound. Failure: {trace}",
|
|
156
|
-
)
|
|
157
|
-
except Exception:
|
|
158
|
-
trace2 = traceback.format_exc()
|
|
159
|
-
return (
|
|
160
|
-
False,
|
|
161
|
-
f"Strategy failed and unwinding also failed. Operation error: {trace}. Unwind error: {trace2}",
|
|
162
|
-
)
|
|
163
|
-
finally:
|
|
164
|
-
if hasattr(self, "ledger_adapter") and self.ledger_adapter:
|
|
165
|
-
await self.ledger_adapter.save()
|
|
166
|
-
|
|
167
|
-
return wrapper
|
|
168
|
-
|
|
169
|
-
@classmethod
|
|
170
|
-
def get_metadata(cls) -> dict[str, Any]:
|
|
171
|
-
return {
|
|
172
|
-
"name": getattr(cls, "name", None),
|
|
173
|
-
"description": getattr(cls, "description", None),
|
|
174
|
-
"summary": getattr(cls, "summary", None),
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
async def health_check(self) -> dict[str, Any]:
|
|
178
|
-
health = {"status": "healthy", "strategy": self.name, "adapters": {}}
|
|
179
|
-
|
|
180
|
-
for name, adapter in self.adapters.items():
|
|
181
|
-
if hasattr(adapter, "health_check"):
|
|
182
|
-
health["adapters"][name] = await adapter.health_check()
|
|
183
|
-
else:
|
|
184
|
-
health["adapters"][name] = {"status": "unknown"}
|
|
185
|
-
|
|
186
|
-
return health
|
|
187
|
-
|
|
188
117
|
async def partial_liquidate(
|
|
189
118
|
self, usd_value: float
|
|
190
119
|
) -> tuple[bool, LiquidationResult]:
|
|
@@ -1,3 +1,12 @@
|
|
|
1
1
|
from .base import StatusDict, StatusTuple, Strategy
|
|
2
|
+
from .opa_loop import OPAConfig, OPALoopMixin, Plan, PlanStep
|
|
2
3
|
|
|
3
|
-
__all__ = [
|
|
4
|
+
__all__ = [
|
|
5
|
+
"Strategy",
|
|
6
|
+
"StatusDict",
|
|
7
|
+
"StatusTuple",
|
|
8
|
+
"OPALoopMixin",
|
|
9
|
+
"OPAConfig",
|
|
10
|
+
"Plan",
|
|
11
|
+
"PlanStep",
|
|
12
|
+
]
|