hypnex-staking 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hypnex_staking-0.1.0/.gitignore +66 -0
- hypnex_staking-0.1.0/PKG-INFO +146 -0
- hypnex_staking-0.1.0/README.md +118 -0
- hypnex_staking-0.1.0/examples/01_check_position.py +30 -0
- hypnex_staking-0.1.0/examples/02_get_referrer_data.py +30 -0
- hypnex_staking-0.1.0/examples/03_quote_tier.py +37 -0
- hypnex_staking-0.1.0/examples/04_stake.py +67 -0
- hypnex_staking-0.1.0/examples/05_claim_referrer_rewards.py +43 -0
- hypnex_staking-0.1.0/examples/06_create_hypnex_subnet.py +155 -0
- hypnex_staking-0.1.0/examples/07_update_metadata.py +92 -0
- hypnex_staking-0.1.0/examples/08_bootstrap_deposit.py +111 -0
- hypnex_staking-0.1.0/examples/09_buy_mor.py +223 -0
- hypnex_staking-0.1.0/pyproject.toml +50 -0
- hypnex_staking-0.1.0/src/hypnex_staking/__init__.py +83 -0
- hypnex_staking-0.1.0/src/hypnex_staking/_abi.py +316 -0
- hypnex_staking-0.1.0/src/hypnex_staking/_constants.py +140 -0
- hypnex_staking-0.1.0/src/hypnex_staking/builders.py +480 -0
- hypnex_staking-0.1.0/src/hypnex_staking/staker.py +387 -0
- hypnex_staking-0.1.0/tests/test_read_only.py +84 -0
- hypnex_staking-0.1.0/uv.lock +2538 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# --- Python ---
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.egg-info/
|
|
6
|
+
build/
|
|
7
|
+
dist/
|
|
8
|
+
.eggs/
|
|
9
|
+
.pytest_cache/
|
|
10
|
+
.ruff_cache/
|
|
11
|
+
.tox/
|
|
12
|
+
.coverage
|
|
13
|
+
.coverage.*
|
|
14
|
+
htmlcov/
|
|
15
|
+
.venv/
|
|
16
|
+
venv/
|
|
17
|
+
env/
|
|
18
|
+
|
|
19
|
+
# --- Node / TypeScript ---
|
|
20
|
+
node_modules/
|
|
21
|
+
*.tsbuildinfo
|
|
22
|
+
.npm/
|
|
23
|
+
.yarn/
|
|
24
|
+
.pnpm-store/
|
|
25
|
+
.parcel-cache/
|
|
26
|
+
|
|
27
|
+
# --- Next.js (apps/stake) ---
|
|
28
|
+
.next/
|
|
29
|
+
out/
|
|
30
|
+
.vercel/
|
|
31
|
+
|
|
32
|
+
# --- Wrangler / Cloudflare ---
|
|
33
|
+
.wrangler/
|
|
34
|
+
|
|
35
|
+
# --- Foundry (registry-contracts) ---
|
|
36
|
+
forge-cache/
|
|
37
|
+
broadcast/
|
|
38
|
+
|
|
39
|
+
# --- Editor / OS ---
|
|
40
|
+
.idea/
|
|
41
|
+
.vscode/
|
|
42
|
+
.DS_Store
|
|
43
|
+
*.swp
|
|
44
|
+
*.swo
|
|
45
|
+
*~
|
|
46
|
+
|
|
47
|
+
# --- Local secrets — never commit ---
|
|
48
|
+
.env
|
|
49
|
+
.env.*
|
|
50
|
+
!.env.example
|
|
51
|
+
.env.local
|
|
52
|
+
.env.production
|
|
53
|
+
|
|
54
|
+
# --- Log + tmp ---
|
|
55
|
+
*.log
|
|
56
|
+
logs/
|
|
57
|
+
tmp/
|
|
58
|
+
|
|
59
|
+
# --- Build outputs in apps/bench ---
|
|
60
|
+
apps/bench/out/
|
|
61
|
+
|
|
62
|
+
# --- Generated bench data is committed (audit trail) but local runs aren't ---
|
|
63
|
+
python-bench/data/*.jsonl
|
|
64
|
+
|
|
65
|
+
# Claude Code session artifacts — never commit
|
|
66
|
+
.claude/
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: hypnex-staking
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: On-chain staking helpers for the Morpheus AI capital pool. Wraps DepositPool.stake() with referrer support (MRC 73 unlocked-MOR rewards).
|
|
5
|
+
Project-URL: Homepage, https://hypnex.xyz
|
|
6
|
+
Project-URL: Documentation, https://docs.hypnex.xyz/staking
|
|
7
|
+
Project-URL: Repository, https://github.com/hypnex-labs/hypnex
|
|
8
|
+
Project-URL: Issues, https://github.com/hypnex-labs/hypnex/issues
|
|
9
|
+
Author: Hypnex Labs
|
|
10
|
+
License: MIT
|
|
11
|
+
Keywords: aave,defi,ethereum,mor,morpheus,onchain,referral,staking,web3
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
21
|
+
Requires-Python: >=3.9
|
|
22
|
+
Requires-Dist: eth-account>=0.10.0
|
|
23
|
+
Requires-Dist: web3<8.0,>=6.15.0
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
26
|
+
Requires-Dist: ruff>=0.5; extra == 'dev'
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# hypnex-staking (Python)
|
|
30
|
+
|
|
31
|
+
On-chain helpers for the **Morpheus AI capital pool** on Ethereum mainnet. Wraps `DepositPool.stake()` and `claimReferrerTier()` so a Python developer can stake stETH/USDC/USDT/wBTC and capture **MRC 73 unlocked-MOR referral rewards**.
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install hypnex-staking
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Why this exists
|
|
38
|
+
|
|
39
|
+
Morpheus's `app.mor.org` UI requires AWS Cognito email signup. The capital pool's on-chain interface is wallet-native and supports referrer attribution, but no Python tooling exists for it. This package fills that gap.
|
|
40
|
+
|
|
41
|
+
The single most under-marketed mechanic: **referral MOR is unlocked, while own-stake MOR is delayed 90 days** (MRC 73 vs MRC 46). Refer once, earn liquid MOR for as long as the referee stays staked.
|
|
42
|
+
|
|
43
|
+
## Quickstart
|
|
44
|
+
|
|
45
|
+
### Read-only (no key needed)
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from hypnex_staking import Staker
|
|
49
|
+
|
|
50
|
+
s = Staker() # public RPC, no signer
|
|
51
|
+
|
|
52
|
+
# Inspect the live tier table
|
|
53
|
+
for tier in s.get_referrer_tiers("USDC"):
|
|
54
|
+
print(tier)
|
|
55
|
+
|
|
56
|
+
# Look up an existing position
|
|
57
|
+
print(s.get_position("0xSomeAddress...", "USDC"))
|
|
58
|
+
|
|
59
|
+
# Look up someone's referrer data
|
|
60
|
+
print(s.get_referrer_data("0xReferrer...", "USDC"))
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### With a signer (moves real funds)
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
import os
|
|
67
|
+
from hypnex_staking import Staker
|
|
68
|
+
|
|
69
|
+
s = Staker(
|
|
70
|
+
rpc_url=os.environ["ETH_RPC_URL"],
|
|
71
|
+
private_key=os.environ["PRIVATE_KEY"],
|
|
72
|
+
default_referrer="0xYourHypnexLabsAddress", # or set HYPNEX_REFERRER env
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
# Always dry-run first — returns calldata, doesn't broadcast
|
|
76
|
+
print(s.stake("USDC", amount=1000, claim_lock_end=0, dry_run=True))
|
|
77
|
+
|
|
78
|
+
# When ready, drop dry_run for the real tx
|
|
79
|
+
tx = s.stake("USDC", amount=1000, claim_lock_end=0)
|
|
80
|
+
print("submitted:", tx)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Claim accumulated MRC 73 unlocked-MOR
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
# Per MRC 73, this MOR has no 90-day lockup — claimable immediately.
|
|
87
|
+
tx = s.claim_referrer_rewards("USDC")
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Verified contracts (Ethereum mainnet)
|
|
91
|
+
|
|
92
|
+
| Contract | Address |
|
|
93
|
+
|---|---|
|
|
94
|
+
| USDC DepositPool | `0x6cCE082851Add4c535352f596662521B4De4750E` |
|
|
95
|
+
| USDT DepositPool | `0x3B51989212BEdaB926794D6bf8e9E991218cf116` |
|
|
96
|
+
| wBTC DepositPool | `0xdE283F8309Fd1AA46c95d299f6B8310716277A42` |
|
|
97
|
+
| wETH DepositPool | `0x9380d72aBbD6e0Cc45095A2Ef8c2CA87d77Cb384` |
|
|
98
|
+
| DistributorV2 | `0xDf1AC1AC255d91F5f4B1E3B4Aef57c5350F64C7A` |
|
|
99
|
+
| ChainLinkDataConsumer | `0xd182263d06FDC463c96190005D6359CC3d3Bbc5e` |
|
|
100
|
+
|
|
101
|
+
Sourced from `MorpheusAIs/SmartContracts` v7 deploy script — verified against the on-chain bytecode by `tests/test_read_only.py`.
|
|
102
|
+
|
|
103
|
+
## Public API
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
Staker(w3=..., rpc_url=..., account=..., private_key=..., default_referrer=...)
|
|
107
|
+
|
|
108
|
+
# read (no signer)
|
|
109
|
+
.get_pool_address(asset) -> str
|
|
110
|
+
.get_token_address(asset) -> str
|
|
111
|
+
.get_decimals(asset) -> int
|
|
112
|
+
.get_position(address, asset) -> Position
|
|
113
|
+
.get_referrer_data(referrer, asset) -> ReferrerData
|
|
114
|
+
.get_referrer_tiers(asset) -> list[ReferrerTier]
|
|
115
|
+
.quote_tier(asset, virtual_amount_staked) -> ReferrerTier | None
|
|
116
|
+
|
|
117
|
+
# write (signer required)
|
|
118
|
+
.approve(asset, amount, dry_run=False) -> str (tx hash)
|
|
119
|
+
.stake(asset, amount, claim_lock_end=0, referrer=None, auto_approve=True, dry_run=False) -> str
|
|
120
|
+
.claim_referrer_rewards(asset, receiver=None, layerzero_fee_wei=0, dry_run=False) -> str
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
`asset` is one of `"USDC" | "USDT" | "WBTC" | "WETH"`.
|
|
124
|
+
|
|
125
|
+
## Environment variables
|
|
126
|
+
|
|
127
|
+
- `ETH_RPC_URL` — Ethereum mainnet RPC (free public default works for reads)
|
|
128
|
+
- `PRIVATE_KEY` — for write methods only
|
|
129
|
+
- `HYPNEX_REFERRER` — default referrer address (override per-call with `referrer=`)
|
|
130
|
+
|
|
131
|
+
## Tests
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
pip install -e ".[dev]"
|
|
135
|
+
pytest # read-only mainnet smoke tests, no key needed
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
For write-method tests, run a local Anvil fork (`anvil --fork-url $ETH_RPC_URL`) and set `ETH_RPC_URL=http://localhost:8545` plus a funded test key. Test recipes are in `tests/test_anvil_fork.py` (unimplemented stub — community contributions welcome).
|
|
139
|
+
|
|
140
|
+
## Status & affiliation
|
|
141
|
+
|
|
142
|
+
**Hypnex is not affiliated with the Morpheus AI Foundation.** The contracts you sign into are Morpheus's; this is the unofficial Python toolkit for them. Audit your own transactions; the Code4rena audit ([report](https://code4rena.com/reports/2025-08-morpheus)) covers the contracts, not this client.
|
|
143
|
+
|
|
144
|
+
## License
|
|
145
|
+
|
|
146
|
+
MIT
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# hypnex-staking (Python)
|
|
2
|
+
|
|
3
|
+
On-chain helpers for the **Morpheus AI capital pool** on Ethereum mainnet. Wraps `DepositPool.stake()` and `claimReferrerTier()` so a Python developer can stake stETH/USDC/USDT/wBTC and capture **MRC 73 unlocked-MOR referral rewards**.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
pip install hypnex-staking
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Why this exists
|
|
10
|
+
|
|
11
|
+
Morpheus's `app.mor.org` UI requires AWS Cognito email signup. The capital pool's on-chain interface is wallet-native and supports referrer attribution, but no Python tooling exists for it. This package fills that gap.
|
|
12
|
+
|
|
13
|
+
The single most under-marketed mechanic: **referral MOR is unlocked, while own-stake MOR is delayed 90 days** (MRC 73 vs MRC 46). Refer once, earn liquid MOR for as long as the referee stays staked.
|
|
14
|
+
|
|
15
|
+
## Quickstart
|
|
16
|
+
|
|
17
|
+
### Read-only (no key needed)
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
from hypnex_staking import Staker
|
|
21
|
+
|
|
22
|
+
s = Staker() # public RPC, no signer
|
|
23
|
+
|
|
24
|
+
# Inspect the live tier table
|
|
25
|
+
for tier in s.get_referrer_tiers("USDC"):
|
|
26
|
+
print(tier)
|
|
27
|
+
|
|
28
|
+
# Look up an existing position
|
|
29
|
+
print(s.get_position("0xSomeAddress...", "USDC"))
|
|
30
|
+
|
|
31
|
+
# Look up someone's referrer data
|
|
32
|
+
print(s.get_referrer_data("0xReferrer...", "USDC"))
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### With a signer (moves real funds)
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
import os
|
|
39
|
+
from hypnex_staking import Staker
|
|
40
|
+
|
|
41
|
+
s = Staker(
|
|
42
|
+
rpc_url=os.environ["ETH_RPC_URL"],
|
|
43
|
+
private_key=os.environ["PRIVATE_KEY"],
|
|
44
|
+
default_referrer="0xYourHypnexLabsAddress", # or set HYPNEX_REFERRER env
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
# Always dry-run first — returns calldata, doesn't broadcast
|
|
48
|
+
print(s.stake("USDC", amount=1000, claim_lock_end=0, dry_run=True))
|
|
49
|
+
|
|
50
|
+
# When ready, drop dry_run for the real tx
|
|
51
|
+
tx = s.stake("USDC", amount=1000, claim_lock_end=0)
|
|
52
|
+
print("submitted:", tx)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Claim accumulated MRC 73 unlocked-MOR
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
# Per MRC 73, this MOR has no 90-day lockup — claimable immediately.
|
|
59
|
+
tx = s.claim_referrer_rewards("USDC")
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Verified contracts (Ethereum mainnet)
|
|
63
|
+
|
|
64
|
+
| Contract | Address |
|
|
65
|
+
|---|---|
|
|
66
|
+
| USDC DepositPool | `0x6cCE082851Add4c535352f596662521B4De4750E` |
|
|
67
|
+
| USDT DepositPool | `0x3B51989212BEdaB926794D6bf8e9E991218cf116` |
|
|
68
|
+
| wBTC DepositPool | `0xdE283F8309Fd1AA46c95d299f6B8310716277A42` |
|
|
69
|
+
| wETH DepositPool | `0x9380d72aBbD6e0Cc45095A2Ef8c2CA87d77Cb384` |
|
|
70
|
+
| DistributorV2 | `0xDf1AC1AC255d91F5f4B1E3B4Aef57c5350F64C7A` |
|
|
71
|
+
| ChainLinkDataConsumer | `0xd182263d06FDC463c96190005D6359CC3d3Bbc5e` |
|
|
72
|
+
|
|
73
|
+
Sourced from `MorpheusAIs/SmartContracts` v7 deploy script — verified against the on-chain bytecode by `tests/test_read_only.py`.
|
|
74
|
+
|
|
75
|
+
## Public API
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
Staker(w3=..., rpc_url=..., account=..., private_key=..., default_referrer=...)
|
|
79
|
+
|
|
80
|
+
# read (no signer)
|
|
81
|
+
.get_pool_address(asset) -> str
|
|
82
|
+
.get_token_address(asset) -> str
|
|
83
|
+
.get_decimals(asset) -> int
|
|
84
|
+
.get_position(address, asset) -> Position
|
|
85
|
+
.get_referrer_data(referrer, asset) -> ReferrerData
|
|
86
|
+
.get_referrer_tiers(asset) -> list[ReferrerTier]
|
|
87
|
+
.quote_tier(asset, virtual_amount_staked) -> ReferrerTier | None
|
|
88
|
+
|
|
89
|
+
# write (signer required)
|
|
90
|
+
.approve(asset, amount, dry_run=False) -> str (tx hash)
|
|
91
|
+
.stake(asset, amount, claim_lock_end=0, referrer=None, auto_approve=True, dry_run=False) -> str
|
|
92
|
+
.claim_referrer_rewards(asset, receiver=None, layerzero_fee_wei=0, dry_run=False) -> str
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
`asset` is one of `"USDC" | "USDT" | "WBTC" | "WETH"`.
|
|
96
|
+
|
|
97
|
+
## Environment variables
|
|
98
|
+
|
|
99
|
+
- `ETH_RPC_URL` — Ethereum mainnet RPC (free public default works for reads)
|
|
100
|
+
- `PRIVATE_KEY` — for write methods only
|
|
101
|
+
- `HYPNEX_REFERRER` — default referrer address (override per-call with `referrer=`)
|
|
102
|
+
|
|
103
|
+
## Tests
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
pip install -e ".[dev]"
|
|
107
|
+
pytest # read-only mainnet smoke tests, no key needed
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
For write-method tests, run a local Anvil fork (`anvil --fork-url $ETH_RPC_URL`) and set `ETH_RPC_URL=http://localhost:8545` plus a funded test key. Test recipes are in `tests/test_anvil_fork.py` (unimplemented stub — community contributions welcome).
|
|
111
|
+
|
|
112
|
+
## Status & affiliation
|
|
113
|
+
|
|
114
|
+
**Hypnex is not affiliated with the Morpheus AI Foundation.** The contracts you sign into are Morpheus's; this is the unofficial Python toolkit for them. Audit your own transactions; the Code4rena audit ([report](https://code4rena.com/reports/2025-08-morpheus)) covers the contracts, not this client.
|
|
115
|
+
|
|
116
|
+
## License
|
|
117
|
+
|
|
118
|
+
MIT
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Read your stake position from the Morpheus capital pool.
|
|
2
|
+
|
|
3
|
+
Read-only — no key required.
|
|
4
|
+
|
|
5
|
+
Run: python examples/01_check_position.py 0xYourAddress... USDC
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import sys
|
|
9
|
+
|
|
10
|
+
from hypnex_staking import Staker
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def main() -> int:
|
|
14
|
+
if len(sys.argv) != 3:
|
|
15
|
+
print("usage: python 01_check_position.py <address> <USDC|USDT|WBTC|WETH>")
|
|
16
|
+
return 2
|
|
17
|
+
address, asset = sys.argv[1], sys.argv[2]
|
|
18
|
+
s = Staker()
|
|
19
|
+
p = s.get_position(address, asset)
|
|
20
|
+
decimals = s.get_decimals(asset)
|
|
21
|
+
print(f"Position for {address} in {asset.upper()} pool:")
|
|
22
|
+
print(f" deposited : {p.deposited / 10**decimals:,.6f} {asset.upper()}")
|
|
23
|
+
print(f" pending rewards : {p.pending_rewards / 1e18:,.6f} MOR")
|
|
24
|
+
print(f" claim_lock_end : {p.claim_lock_end} (unix)")
|
|
25
|
+
print(f" referrer : {p.referrer}")
|
|
26
|
+
return 0
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
if __name__ == "__main__":
|
|
30
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Read a referrer's data: amount staked under them, virtual amount, pending unlocked MOR.
|
|
2
|
+
|
|
3
|
+
Read-only.
|
|
4
|
+
|
|
5
|
+
Run: python examples/02_get_referrer_data.py 0xReferrerAddress... USDC
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import sys
|
|
9
|
+
|
|
10
|
+
from hypnex_staking import Staker
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def main() -> int:
|
|
14
|
+
if len(sys.argv) != 3:
|
|
15
|
+
print("usage: python 02_get_referrer_data.py <referrer> <USDC|USDT|WBTC|WETH>")
|
|
16
|
+
return 2
|
|
17
|
+
referrer, asset = sys.argv[1], sys.argv[2]
|
|
18
|
+
s = Staker()
|
|
19
|
+
d = s.get_referrer_data(referrer, asset)
|
|
20
|
+
decimals = s.get_decimals(asset)
|
|
21
|
+
print(f"Referrer data for {referrer} in {asset.upper()} pool:")
|
|
22
|
+
print(f" amount staked under referrer : {d.amount_staked / 10**decimals:,.6f} {asset.upper()}")
|
|
23
|
+
print(f" virtual amount (after tier) : {d.virtual_amount_staked / 10**decimals:,.6f}")
|
|
24
|
+
print(f" pending unlocked MOR rewards : {d.pending_rewards / 1e18:,.6f} MOR (MRC 73 — claim anytime)")
|
|
25
|
+
print(f" last claim : {d.last_claim} (unix)")
|
|
26
|
+
return 0
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
if __name__ == "__main__":
|
|
30
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""Read the live referrer-tier table for each pool and quote which tier a given
|
|
2
|
+
virtual stake amount falls in.
|
|
3
|
+
|
|
4
|
+
Read-only.
|
|
5
|
+
|
|
6
|
+
Run: python examples/03_quote_tier.py
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from hypnex_staking import Staker
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def main() -> None:
|
|
13
|
+
s = Staker()
|
|
14
|
+
|
|
15
|
+
for asset in ("USDC", "USDT", "WBTC", "WETH"):
|
|
16
|
+
decimals = s.get_decimals(asset)
|
|
17
|
+
print(f"\n{asset} pool — referrer tiers:")
|
|
18
|
+
tiers = s.get_referrer_tiers(asset)
|
|
19
|
+
if not tiers:
|
|
20
|
+
print(" (no tiers configured on-chain — fall through to base 1% referee bonus)")
|
|
21
|
+
continue
|
|
22
|
+
for i, t in enumerate(tiers):
|
|
23
|
+
# multiplier is PRECISION-scaled (1e25 == 1.0×); convert to bonus %
|
|
24
|
+
multiplier_x = t.multiplier / 1e25
|
|
25
|
+
bonus_pct = (multiplier_x - 1.0) * 100
|
|
26
|
+
print(
|
|
27
|
+
f" tier {i}: ≥ {t.amount_threshold / 10**decimals:>12,.4f} {asset} "
|
|
28
|
+
f"→ {multiplier_x:.4f}× ({bonus_pct:+.1f}%)"
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
print("\nNote: tier thresholds are denominated in the *virtual amount* — i.e. the\n"
|
|
32
|
+
"amount-staked × the referee's claim-lock-time multiplier. Long locks count\n"
|
|
33
|
+
"for more virtual stake, which can push a referrer up a tier.")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
if __name__ == "__main__":
|
|
37
|
+
main()
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""WRITES A REAL TRANSACTION on Ethereum mainnet — moves real funds.
|
|
2
|
+
|
|
3
|
+
Stake `amount` of `asset` into the Morpheus DepositPool with Hypnex Labs as
|
|
4
|
+
the on-chain referrer. The default-referrer override happens via the
|
|
5
|
+
HYPNEX_REFERRER env var or the Staker(default_referrer=...) constructor arg.
|
|
6
|
+
|
|
7
|
+
Always run with --dry-run first. Test against Anvil fork before live.
|
|
8
|
+
|
|
9
|
+
Run:
|
|
10
|
+
ETH_RPC_URL=https://... \\
|
|
11
|
+
PRIVATE_KEY=0x... \\
|
|
12
|
+
python examples/04_stake.py USDC 100 --dry-run
|
|
13
|
+
|
|
14
|
+
To broadcast for real, drop the --dry-run flag.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
import argparse
|
|
18
|
+
import os
|
|
19
|
+
|
|
20
|
+
from hypnex_staking import Staker
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def main() -> int:
|
|
24
|
+
p = argparse.ArgumentParser()
|
|
25
|
+
p.add_argument("asset", choices=["USDC", "USDT", "WBTC", "WETH"])
|
|
26
|
+
p.add_argument("amount", type=float)
|
|
27
|
+
p.add_argument("--claim-lock-end", type=int, default=0,
|
|
28
|
+
help="Unix timestamp for voluntary additional claim lock; 0 = no extra lock")
|
|
29
|
+
p.add_argument("--referrer", type=str, default=None,
|
|
30
|
+
help="Override default referrer (HYPNEX_REFERRER env / Staker default)")
|
|
31
|
+
p.add_argument("--dry-run", action="store_true",
|
|
32
|
+
help="Build but do NOT broadcast — print calldata only")
|
|
33
|
+
args = p.parse_args()
|
|
34
|
+
|
|
35
|
+
rpc = os.environ.get("ETH_RPC_URL")
|
|
36
|
+
pk = os.environ.get("PRIVATE_KEY")
|
|
37
|
+
if not rpc or not pk:
|
|
38
|
+
print("error: set ETH_RPC_URL and PRIVATE_KEY")
|
|
39
|
+
return 2
|
|
40
|
+
|
|
41
|
+
s = Staker(rpc_url=rpc, private_key=pk)
|
|
42
|
+
|
|
43
|
+
print(f" asset : {args.asset}")
|
|
44
|
+
print(f" amount : {args.amount}")
|
|
45
|
+
print(f" claim_lock_end : {args.claim_lock_end}")
|
|
46
|
+
print(f" referrer : {args.referrer or s.default_referrer}")
|
|
47
|
+
print(f" signer : {s.account.address}")
|
|
48
|
+
print(f" pool : {s.get_pool_address(args.asset)}")
|
|
49
|
+
print(f" dry_run : {args.dry_run}")
|
|
50
|
+
print()
|
|
51
|
+
|
|
52
|
+
out = s.stake(
|
|
53
|
+
asset=args.asset,
|
|
54
|
+
amount=args.amount,
|
|
55
|
+
claim_lock_end=args.claim_lock_end,
|
|
56
|
+
referrer=args.referrer,
|
|
57
|
+
dry_run=args.dry_run,
|
|
58
|
+
)
|
|
59
|
+
if args.dry_run:
|
|
60
|
+
print(f" encoded calldata : {out}")
|
|
61
|
+
else:
|
|
62
|
+
print(f" tx hash : {out}")
|
|
63
|
+
return 0
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
if __name__ == "__main__":
|
|
67
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""WRITES A REAL TRANSACTION — claims your accumulated MRC 73 unlocked-MOR rewards.
|
|
2
|
+
|
|
3
|
+
Per MRC 73, referrer MOR is unlocked the moment it accrues — no 90-day delay
|
|
4
|
+
that capital contributors face under MRC 46. This is the lowest-friction MOR
|
|
5
|
+
yield path on the network.
|
|
6
|
+
|
|
7
|
+
Run:
|
|
8
|
+
ETH_RPC_URL=... PRIVATE_KEY=... \\
|
|
9
|
+
python examples/05_claim_referrer_rewards.py USDC --dry-run
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import argparse
|
|
13
|
+
import os
|
|
14
|
+
|
|
15
|
+
from hypnex_staking import Staker
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def main() -> int:
|
|
19
|
+
p = argparse.ArgumentParser()
|
|
20
|
+
p.add_argument("asset", choices=["USDC", "USDT", "WBTC", "WETH"])
|
|
21
|
+
p.add_argument("--receiver", type=str, default=None,
|
|
22
|
+
help="Address to receive the MOR (defaults to signer)")
|
|
23
|
+
p.add_argument("--lz-fee-wei", type=int, default=0,
|
|
24
|
+
help="LayerZero messaging fee if cross-chain forwarding (default 0)")
|
|
25
|
+
p.add_argument("--dry-run", action="store_true")
|
|
26
|
+
args = p.parse_args()
|
|
27
|
+
|
|
28
|
+
rpc = os.environ["ETH_RPC_URL"]
|
|
29
|
+
pk = os.environ["PRIVATE_KEY"]
|
|
30
|
+
s = Staker(rpc_url=rpc, private_key=pk)
|
|
31
|
+
|
|
32
|
+
out = s.claim_referrer_rewards(
|
|
33
|
+
asset=args.asset,
|
|
34
|
+
receiver=args.receiver,
|
|
35
|
+
layerzero_fee_wei=args.lz_fee_wei,
|
|
36
|
+
dry_run=args.dry_run,
|
|
37
|
+
)
|
|
38
|
+
print(f"{'calldata' if args.dry_run else 'tx hash'}: {out}")
|
|
39
|
+
return 0
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
if __name__ == "__main__":
|
|
43
|
+
raise SystemExit(main())
|