hypnex-forge 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,69 @@
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
+ registry-contracts/cache/
39
+ registry-contracts/lib/
40
+ registry-contracts/out/
41
+
42
+ # --- Editor / OS ---
43
+ .idea/
44
+ .vscode/
45
+ .DS_Store
46
+ *.swp
47
+ *.swo
48
+ *~
49
+
50
+ # --- Local secrets — never commit ---
51
+ .env
52
+ .env.*
53
+ !.env.example
54
+ .env.local
55
+ .env.production
56
+
57
+ # --- Log + tmp ---
58
+ *.log
59
+ logs/
60
+ tmp/
61
+
62
+ # --- Build outputs in apps/bench ---
63
+ apps/bench/out/
64
+
65
+ # --- Generated bench data is committed (audit trail) but local runs aren't ---
66
+ python-bench/data/*.jsonl
67
+
68
+ # Claude Code session artifacts — never commit
69
+ .claude/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Hypnex Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,248 @@
1
+ Metadata-Version: 2.4
2
+ Name: hypnex-forge
3
+ Version: 0.2.1
4
+ Summary: Python SDK for Forge — the paid tool registry on Morpheus AI (MRC 60). Phase 1 listing rail + Phase 3 pre-paid escrow with relayer-attested per-call settlement on Arbitrum + Base.
5
+ Project-URL: Homepage, https://hypnex.xyz
6
+ Project-URL: Documentation, https://docs.hypnex.xyz/forge
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
+ License-File: LICENSE
12
+ Keywords: agents,forge,hypnex,marketplace,mcp,mor,morpheus,mrc-60,tools,web3
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Requires-Python: >=3.10
21
+ Requires-Dist: eth-account>=0.10.0
22
+ Requires-Dist: web3<8.0,>=6.15.0
23
+ Provides-Extra: dev
24
+ Requires-Dist: pytest>=9.0.3; extra == 'dev'
25
+ Requires-Dist: ruff>=0.5; extra == 'dev'
26
+ Description-Content-Type: text/markdown
27
+
28
+ # hypnex-forge (Python)
29
+
30
+ Python SDK for **Forge** — the paid tool registry on Morpheus AI. Implements **MRC 60** Phase 1 (paid listings) and Phase 3 (on-chain per-call settlement via pre-paid escrow).
31
+
32
+ ```bash
33
+ pip install hypnex-forge
34
+ ```
35
+
36
+ ## Affiliation & monetization
37
+
38
+ This SDK is published by **Hypnex Labs**. Hypnex is not affiliated with the Morpheus AI Foundation.
39
+
40
+ - `register()` costs **1 MOR** (configurable on-chain by claim-admin), forwarded directly to the Hypnex Labs treasury at `0x22B5C0075372E743042b2d62b3D254425Eb957D8` inside the same tx. The SDK auto-approves the MOR allowance on first use.
41
+ - `pricePerCallWei` is what end users pay YOU per call. With Phase 3 escrow, on-chain settlement debits the agent's escrow at this rate, with **90% routed to the tool owner and 10% to the Hypnex treasury** as a protocol fee. The fee is hard-capped at 20% in the contract; admin cannot rug.
42
+
43
+ ## Quickstart — Phase 1 (listings)
44
+
45
+ ### Read-only
46
+
47
+ ```python
48
+ from hypnex_forge import Forge
49
+
50
+ f = Forge(chain="arbitrum")
51
+ print(f.total_tools())
52
+ print(f.list_tools(0, 100))
53
+ print(f.get_listing_fee_wei()) # 10**18 = 1 MOR
54
+ ```
55
+
56
+ ### Register a tool (with signer)
57
+
58
+ ```python
59
+ import os
60
+ from hypnex_forge import Forge
61
+
62
+ f = Forge(
63
+ chain="arbitrum",
64
+ rpc_url=os.environ["ETH_RPC_URL"],
65
+ private_key=os.environ["PRIVATE_KEY"],
66
+ )
67
+
68
+ tx = f.register(
69
+ namespace="myorg",
70
+ name="websearch",
71
+ mcp_uri="https://mcp.example.com/v1",
72
+ categories=["search", "data"],
73
+ price_per_call_wei=int(0.001 * 10**18),
74
+ )
75
+ print("tool registered:", tx)
76
+ ```
77
+
78
+ ## Quickstart — Phase 3 (escrow + per-call settlement)
79
+
80
+ Three actors: the **agent** (who consumes the tool), the **tool owner** (who runs it), and the **Hypnex relayer** (which batches receipts and submits `settle()` on a 4-hourly cron).
81
+
82
+ ### 1. Tool owner: register a signer key
83
+
84
+ ```python
85
+ from hypnex_forge import Escrow, tool_id
86
+
87
+ esc = Escrow(chain="arbitrum", private_key=os.environ["TOOL_OWNER_PK"])
88
+ tid = tool_id("myorg", "websearch")
89
+
90
+ esc.set_signer(tid, "0xYourSessionKeyOrEoa")
91
+ ```
92
+
93
+ ### 2. Agent: pre-fund per-tool escrow
94
+
95
+ ```python
96
+ from hypnex_forge import Escrow, tool_id
97
+
98
+ esc = Escrow(chain="arbitrum", private_key=os.environ["AGENT_PK"])
99
+ tid = tool_id("myorg", "websearch")
100
+
101
+ # Auto-approves MOR allowance on first call.
102
+ esc.deposit(tid, 10 * 10**18) # 10 MOR runway
103
+ print("escrow balance:", esc.balance(tid))
104
+ ```
105
+
106
+ ### 3. Tool server: sign + post receipts
107
+
108
+ After every N calls, the tool's signer key signs a receipt and posts it
109
+ to `relayer.hypnex.xyz`:
110
+
111
+ ```python
112
+ esc = Escrow(chain="arbitrum", private_key=os.environ["TOOL_OWNER_PK"])
113
+ esc.call_with_receipt(
114
+ tool_id=tid,
115
+ agent="0xAgentAddress",
116
+ call_count=100, # cumulative for this period
117
+ period_id=42, # strictly increasing per (toolId, agent)
118
+ )
119
+ # The relayer batches and submits settle() on the next cron tick.
120
+ ```
121
+
122
+ ### 4. Tool owner: withdraw accrued revenue
123
+
124
+ ```python
125
+ print("accrued:", esc.tool_revenue(tid) / 1e18, "MOR")
126
+ esc.withdraw_tool(tid, "0xYourColdWallet")
127
+ ```
128
+
129
+ ### 5. Agent: 24h-delayed self-custody exit
130
+
131
+ If a tool owner misbehaves, agents can pull remaining escrow back:
132
+
133
+ ```python
134
+ esc.agent_request_withdraw(tid) # opens a 24h window
135
+ # ... 24 hours later ...
136
+ esc.agent_execute_withdraw(tid, "0xAgentAddress")
137
+ ```
138
+
139
+ The relayer has the full 24h to flush pending settlements before the
140
+ exit becomes executable.
141
+
142
+ ## Public API
143
+
144
+ ### `Forge` (Phase 1 — listings)
145
+
146
+ ```
147
+ Forge(address=None, chain="arbitrum", w3=None, rpc_url=None,
148
+ account=None, private_key=None)
149
+
150
+ # read
151
+ .total_tools() -> int
152
+ .list_tools(offset=0, limit=100) -> list[bytes32]
153
+ .tools_of(owner) -> list[bytes32]
154
+ .tools_in_category(label_or_bytes32) -> list[bytes32]
155
+ .get_tool(tool_id) -> Tool
156
+ .is_registered(tool_id) -> bool
157
+ .tool_id_of(namespace, name) -> bytes32
158
+ .get_listing_fee_wei() -> int
159
+ .get_claim_admin() -> str
160
+ .get_mor_balance(address=None) -> int
161
+ .get_mor_allowance(owner=None) -> int
162
+
163
+ # write (signer required)
164
+ .register(namespace, name, mcp_uri, categories, price_per_call_wei=0) -> tx
165
+ .update_tool(tool_id, mcp_uri, price_per_call_wei) -> tx
166
+ .set_categories(tool_id, categories) -> tx
167
+ .deactivate(tool_id) -> tx
168
+ .reactivate(tool_id) -> tx
169
+ .transfer_ownership(tool_id, new_owner) -> tx
170
+ ```
171
+
172
+ ### `Escrow` (Phase 3 — per-call settlement)
173
+
174
+ ```
175
+ Escrow(address=None, chain="arbitrum", w3=None, rpc_url=None,
176
+ account=None, private_key=None, relayer_url=None)
177
+
178
+ # read
179
+ .balance(tool_id, agent=None) -> int
180
+ .tool_revenue(tool_id) -> int
181
+ .treasury_revenue() -> int
182
+ .signer_of(tool_id) -> str
183
+ .last_period_id(tool_id, agent) -> int
184
+ .withdraw_unlock_at(tool_id, agent) -> int
185
+ .protocol_fee_bps() -> int
186
+ .relayer_address() -> str
187
+ .claim_admin() -> str
188
+ .quote_settle(tool_id, call_count) -> (total, tool_payout, protocol_fee)
189
+
190
+ # agent-side write
191
+ .deposit(tool_id, amount, auto_approve=True) -> tx
192
+ .agent_request_withdraw(tool_id) -> tx
193
+ .agent_execute_withdraw(tool_id, to=None) -> tx
194
+
195
+ # tool-owner-side write
196
+ .set_signer(tool_id, new_signer) -> tx
197
+ .withdraw_tool(tool_id, to) -> tx
198
+ .sign_receipt(tool_id, agent, call_count, period_id) -> bytes
199
+ .post_receipt(tool_id, agent, call_count, period_id, signature, ...) -> dict
200
+ .call_with_receipt(tool_id, agent, call_count, period_id, ...) -> dict
201
+
202
+ # relayer / claim-admin write
203
+ .settle(tool_id, agent, call_count, period_id, signature) -> tx
204
+ .withdraw_treasury(to) -> tx
205
+ .set_relayer(new_relayer) -> tx
206
+ .set_protocol_fee_bps(new_bps) -> tx
207
+ ```
208
+
209
+ Plus a pure helper:
210
+
211
+ ```
212
+ receipt_struct_hash(*, chain_id, escrow_address, tool_id,
213
+ agent, call_count, period_id) -> bytes
214
+ ```
215
+
216
+ The bytes returned match the on-chain Solidity recovery exactly:
217
+
218
+ ```
219
+ keccak256(abi.encode(chainid, escrow, toolId, agent, callCount, periodId))
220
+ ```
221
+
222
+ wrapped with the EIP-191 `\x19Ethereum Signed Message:\n32` prefix when
223
+ signed.
224
+
225
+ ## Environment variables
226
+
227
+ | Variable | Purpose |
228
+ |---|---|
229
+ | `HYPNEX_FORGE_CHAIN` | Default chain (`arbitrum` or `base`) |
230
+ | `HYPNEX_FORGE_RPC_URL` | Override RPC URL |
231
+ | `HYPNEX_FORGE_ADDRESS` | Override `ForgeToolRegistry` address |
232
+ | `HYPNEX_FORGE_ESCROW_ADDRESS` | Override `ForgeEscrow` address |
233
+ | `HYPNEX_FORGE_RELAYER_URL` | Override relayer endpoint (default `https://relayer.hypnex.xyz`) |
234
+ | `PRIVATE_KEY` | Required for write methods |
235
+
236
+ ## Status
237
+
238
+ - **Phase 1** — paid listings on Arbitrum One + Base mainnet (live since 2026-05-09).
239
+ - **Phase 2** — discovery UI at `forge.hypnex.xyz` (live).
240
+ - **Phase 3** — pre-paid escrow + per-call settlement (`ForgeEscrow`). Live since 2026-05-09:
241
+ - Arbitrum One: [`0x88E32F332A5140Af16c6273d8131bC84BC089Da5`](https://arbiscan.io/address/0x88E32F332A5140Af16c6273d8131bC84BC089Da5#code)
242
+ - Base mainnet: [`0xCC258a7BBF361fd824e87D4b3C0D394De6Fd454F`](https://basescan.org/address/0xCC258a7BBF361fd824e87D4b3C0D394De6Fd454F#code)
243
+
244
+ SDK 0.2.1+ resolves these automatically when you pass `chain="arbitrum"` or `chain="base"`. The Cloudflare Worker relayer at `relayer.hypnex.xyz` is the last operational piece; until it's live, receipts can be submitted directly to `Escrow.settle()` by the configured relayer EOA.
245
+
246
+ ## License
247
+
248
+ MIT (Copyright (c) 2026 Hypnex Labs). The MIT-licensed source includes hard-coded fee routers to the Hypnex Labs treasury for both the listing fee and the Phase-3 protocol fee — see "Affiliation & monetization" above.
@@ -0,0 +1,221 @@
1
+ # hypnex-forge (Python)
2
+
3
+ Python SDK for **Forge** — the paid tool registry on Morpheus AI. Implements **MRC 60** Phase 1 (paid listings) and Phase 3 (on-chain per-call settlement via pre-paid escrow).
4
+
5
+ ```bash
6
+ pip install hypnex-forge
7
+ ```
8
+
9
+ ## Affiliation & monetization
10
+
11
+ This SDK is published by **Hypnex Labs**. Hypnex is not affiliated with the Morpheus AI Foundation.
12
+
13
+ - `register()` costs **1 MOR** (configurable on-chain by claim-admin), forwarded directly to the Hypnex Labs treasury at `0x22B5C0075372E743042b2d62b3D254425Eb957D8` inside the same tx. The SDK auto-approves the MOR allowance on first use.
14
+ - `pricePerCallWei` is what end users pay YOU per call. With Phase 3 escrow, on-chain settlement debits the agent's escrow at this rate, with **90% routed to the tool owner and 10% to the Hypnex treasury** as a protocol fee. The fee is hard-capped at 20% in the contract; admin cannot rug.
15
+
16
+ ## Quickstart — Phase 1 (listings)
17
+
18
+ ### Read-only
19
+
20
+ ```python
21
+ from hypnex_forge import Forge
22
+
23
+ f = Forge(chain="arbitrum")
24
+ print(f.total_tools())
25
+ print(f.list_tools(0, 100))
26
+ print(f.get_listing_fee_wei()) # 10**18 = 1 MOR
27
+ ```
28
+
29
+ ### Register a tool (with signer)
30
+
31
+ ```python
32
+ import os
33
+ from hypnex_forge import Forge
34
+
35
+ f = Forge(
36
+ chain="arbitrum",
37
+ rpc_url=os.environ["ETH_RPC_URL"],
38
+ private_key=os.environ["PRIVATE_KEY"],
39
+ )
40
+
41
+ tx = f.register(
42
+ namespace="myorg",
43
+ name="websearch",
44
+ mcp_uri="https://mcp.example.com/v1",
45
+ categories=["search", "data"],
46
+ price_per_call_wei=int(0.001 * 10**18),
47
+ )
48
+ print("tool registered:", tx)
49
+ ```
50
+
51
+ ## Quickstart — Phase 3 (escrow + per-call settlement)
52
+
53
+ Three actors: the **agent** (who consumes the tool), the **tool owner** (who runs it), and the **Hypnex relayer** (which batches receipts and submits `settle()` on a 4-hourly cron).
54
+
55
+ ### 1. Tool owner: register a signer key
56
+
57
+ ```python
58
+ from hypnex_forge import Escrow, tool_id
59
+
60
+ esc = Escrow(chain="arbitrum", private_key=os.environ["TOOL_OWNER_PK"])
61
+ tid = tool_id("myorg", "websearch")
62
+
63
+ esc.set_signer(tid, "0xYourSessionKeyOrEoa")
64
+ ```
65
+
66
+ ### 2. Agent: pre-fund per-tool escrow
67
+
68
+ ```python
69
+ from hypnex_forge import Escrow, tool_id
70
+
71
+ esc = Escrow(chain="arbitrum", private_key=os.environ["AGENT_PK"])
72
+ tid = tool_id("myorg", "websearch")
73
+
74
+ # Auto-approves MOR allowance on first call.
75
+ esc.deposit(tid, 10 * 10**18) # 10 MOR runway
76
+ print("escrow balance:", esc.balance(tid))
77
+ ```
78
+
79
+ ### 3. Tool server: sign + post receipts
80
+
81
+ After every N calls, the tool's signer key signs a receipt and posts it
82
+ to `relayer.hypnex.xyz`:
83
+
84
+ ```python
85
+ esc = Escrow(chain="arbitrum", private_key=os.environ["TOOL_OWNER_PK"])
86
+ esc.call_with_receipt(
87
+ tool_id=tid,
88
+ agent="0xAgentAddress",
89
+ call_count=100, # cumulative for this period
90
+ period_id=42, # strictly increasing per (toolId, agent)
91
+ )
92
+ # The relayer batches and submits settle() on the next cron tick.
93
+ ```
94
+
95
+ ### 4. Tool owner: withdraw accrued revenue
96
+
97
+ ```python
98
+ print("accrued:", esc.tool_revenue(tid) / 1e18, "MOR")
99
+ esc.withdraw_tool(tid, "0xYourColdWallet")
100
+ ```
101
+
102
+ ### 5. Agent: 24h-delayed self-custody exit
103
+
104
+ If a tool owner misbehaves, agents can pull remaining escrow back:
105
+
106
+ ```python
107
+ esc.agent_request_withdraw(tid) # opens a 24h window
108
+ # ... 24 hours later ...
109
+ esc.agent_execute_withdraw(tid, "0xAgentAddress")
110
+ ```
111
+
112
+ The relayer has the full 24h to flush pending settlements before the
113
+ exit becomes executable.
114
+
115
+ ## Public API
116
+
117
+ ### `Forge` (Phase 1 — listings)
118
+
119
+ ```
120
+ Forge(address=None, chain="arbitrum", w3=None, rpc_url=None,
121
+ account=None, private_key=None)
122
+
123
+ # read
124
+ .total_tools() -> int
125
+ .list_tools(offset=0, limit=100) -> list[bytes32]
126
+ .tools_of(owner) -> list[bytes32]
127
+ .tools_in_category(label_or_bytes32) -> list[bytes32]
128
+ .get_tool(tool_id) -> Tool
129
+ .is_registered(tool_id) -> bool
130
+ .tool_id_of(namespace, name) -> bytes32
131
+ .get_listing_fee_wei() -> int
132
+ .get_claim_admin() -> str
133
+ .get_mor_balance(address=None) -> int
134
+ .get_mor_allowance(owner=None) -> int
135
+
136
+ # write (signer required)
137
+ .register(namespace, name, mcp_uri, categories, price_per_call_wei=0) -> tx
138
+ .update_tool(tool_id, mcp_uri, price_per_call_wei) -> tx
139
+ .set_categories(tool_id, categories) -> tx
140
+ .deactivate(tool_id) -> tx
141
+ .reactivate(tool_id) -> tx
142
+ .transfer_ownership(tool_id, new_owner) -> tx
143
+ ```
144
+
145
+ ### `Escrow` (Phase 3 — per-call settlement)
146
+
147
+ ```
148
+ Escrow(address=None, chain="arbitrum", w3=None, rpc_url=None,
149
+ account=None, private_key=None, relayer_url=None)
150
+
151
+ # read
152
+ .balance(tool_id, agent=None) -> int
153
+ .tool_revenue(tool_id) -> int
154
+ .treasury_revenue() -> int
155
+ .signer_of(tool_id) -> str
156
+ .last_period_id(tool_id, agent) -> int
157
+ .withdraw_unlock_at(tool_id, agent) -> int
158
+ .protocol_fee_bps() -> int
159
+ .relayer_address() -> str
160
+ .claim_admin() -> str
161
+ .quote_settle(tool_id, call_count) -> (total, tool_payout, protocol_fee)
162
+
163
+ # agent-side write
164
+ .deposit(tool_id, amount, auto_approve=True) -> tx
165
+ .agent_request_withdraw(tool_id) -> tx
166
+ .agent_execute_withdraw(tool_id, to=None) -> tx
167
+
168
+ # tool-owner-side write
169
+ .set_signer(tool_id, new_signer) -> tx
170
+ .withdraw_tool(tool_id, to) -> tx
171
+ .sign_receipt(tool_id, agent, call_count, period_id) -> bytes
172
+ .post_receipt(tool_id, agent, call_count, period_id, signature, ...) -> dict
173
+ .call_with_receipt(tool_id, agent, call_count, period_id, ...) -> dict
174
+
175
+ # relayer / claim-admin write
176
+ .settle(tool_id, agent, call_count, period_id, signature) -> tx
177
+ .withdraw_treasury(to) -> tx
178
+ .set_relayer(new_relayer) -> tx
179
+ .set_protocol_fee_bps(new_bps) -> tx
180
+ ```
181
+
182
+ Plus a pure helper:
183
+
184
+ ```
185
+ receipt_struct_hash(*, chain_id, escrow_address, tool_id,
186
+ agent, call_count, period_id) -> bytes
187
+ ```
188
+
189
+ The bytes returned match the on-chain Solidity recovery exactly:
190
+
191
+ ```
192
+ keccak256(abi.encode(chainid, escrow, toolId, agent, callCount, periodId))
193
+ ```
194
+
195
+ wrapped with the EIP-191 `\x19Ethereum Signed Message:\n32` prefix when
196
+ signed.
197
+
198
+ ## Environment variables
199
+
200
+ | Variable | Purpose |
201
+ |---|---|
202
+ | `HYPNEX_FORGE_CHAIN` | Default chain (`arbitrum` or `base`) |
203
+ | `HYPNEX_FORGE_RPC_URL` | Override RPC URL |
204
+ | `HYPNEX_FORGE_ADDRESS` | Override `ForgeToolRegistry` address |
205
+ | `HYPNEX_FORGE_ESCROW_ADDRESS` | Override `ForgeEscrow` address |
206
+ | `HYPNEX_FORGE_RELAYER_URL` | Override relayer endpoint (default `https://relayer.hypnex.xyz`) |
207
+ | `PRIVATE_KEY` | Required for write methods |
208
+
209
+ ## Status
210
+
211
+ - **Phase 1** — paid listings on Arbitrum One + Base mainnet (live since 2026-05-09).
212
+ - **Phase 2** — discovery UI at `forge.hypnex.xyz` (live).
213
+ - **Phase 3** — pre-paid escrow + per-call settlement (`ForgeEscrow`). Live since 2026-05-09:
214
+ - Arbitrum One: [`0x88E32F332A5140Af16c6273d8131bC84BC089Da5`](https://arbiscan.io/address/0x88E32F332A5140Af16c6273d8131bC84BC089Da5#code)
215
+ - Base mainnet: [`0xCC258a7BBF361fd824e87D4b3C0D394De6Fd454F`](https://basescan.org/address/0xCC258a7BBF361fd824e87D4b3C0D394De6Fd454F#code)
216
+
217
+ SDK 0.2.1+ resolves these automatically when you pass `chain="arbitrum"` or `chain="base"`. The Cloudflare Worker relayer at `relayer.hypnex.xyz` is the last operational piece; until it's live, receipts can be submitted directly to `Escrow.settle()` by the configured relayer EOA.
218
+
219
+ ## License
220
+
221
+ MIT (Copyright (c) 2026 Hypnex Labs). The MIT-licensed source includes hard-coded fee routers to the Hypnex Labs treasury for both the listing fee and the Phase-3 protocol fee — see "Affiliation & monetization" above.
@@ -0,0 +1,10 @@
1
+ """Make the in-tree SDK importable when running pytest without `pip install -e .`."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import sys
6
+ from pathlib import Path
7
+
8
+ SRC = Path(__file__).resolve().parent / "src"
9
+ if SRC.is_dir() and str(SRC) not in sys.path:
10
+ sys.path.insert(0, str(SRC))
@@ -0,0 +1,48 @@
1
+ [project]
2
+ name = "hypnex-forge"
3
+ version = "0.2.1"
4
+ description = "Python SDK for Forge — the paid tool registry on Morpheus AI (MRC 60). Phase 1 listing rail + Phase 3 pre-paid escrow with relayer-attested per-call settlement on Arbitrum + Base."
5
+ readme = "README.md"
6
+ license = { text = "MIT" }
7
+ requires-python = ">=3.10"
8
+ authors = [{ name = "Hypnex Labs" }]
9
+ keywords = ["morpheus", "mor", "forge", "tools", "marketplace", "mcp", "mrc-60", "hypnex", "web3", "agents"]
10
+ classifiers = [
11
+ "Development Status :: 3 - Alpha",
12
+ "Intended Audience :: Developers",
13
+ "License :: OSI Approved :: MIT License",
14
+ "Programming Language :: Python :: 3",
15
+ "Programming Language :: Python :: 3.10",
16
+ "Programming Language :: Python :: 3.11",
17
+ "Programming Language :: Python :: 3.12",
18
+ ]
19
+ dependencies = [
20
+ "web3>=6.15.0,<8.0",
21
+ "eth-account>=0.10.0",
22
+ ]
23
+
24
+ [project.optional-dependencies]
25
+ dev = [
26
+ "pytest>=9.0.3",
27
+ "ruff>=0.5",
28
+ ]
29
+
30
+ [project.urls]
31
+ Homepage = "https://hypnex.xyz"
32
+ Documentation = "https://docs.hypnex.xyz/forge"
33
+ Repository = "https://github.com/hypnex-labs/hypnex"
34
+ Issues = "https://github.com/hypnex-labs/hypnex/issues"
35
+
36
+ [build-system]
37
+ requires = ["hatchling"]
38
+ build-backend = "hatchling.build"
39
+
40
+ [tool.hatch.build.targets.wheel]
41
+ packages = ["src/hypnex_forge"]
42
+
43
+ [tool.pytest.ini_options]
44
+ testpaths = ["tests"]
45
+
46
+ [tool.ruff]
47
+ line-length = 100
48
+ target-version = "py39"
@@ -0,0 +1,74 @@
1
+ """hypnex-forge — Python SDK for the Forge tool registry on Morpheus AI.
2
+
3
+ Forge is the Hypnex Labs tools marketplace for the Morpheus AI ecosystem
4
+ and the broader MCP (Model-Context-Protocol) world. Each tool listing on
5
+ the on-chain registry pays a one-time fee in MOR to Hypnex Labs.
6
+
7
+ Monetization notice:
8
+ This SDK routes all listing fees from `register()` calls to the Hypnex
9
+ Labs treasury (0x22B5C0075372E743042b2d62b3D254425Eb957D8). The
10
+ listing fee is configurable on-chain by the claim-admin (default 1
11
+ MOR per listing). The on-chain `pricePerCallWei` you set on a tool
12
+ is what END USERS pay you for calls; that revenue stays with the
13
+ tool owner (Phase 1 — Phase 3 will add on-chain per-call settlement
14
+ with a Hypnex protocol fee).
15
+
16
+ Quickstart (read-only):
17
+
18
+ from hypnex_forge import Forge
19
+
20
+ f = Forge(chain="arbitrum")
21
+ print(f.total_tools())
22
+ print(f.list_tools(0, 100))
23
+ print(f.get_listing_fee_wei()) # 10**18 = 1 MOR
24
+
25
+ Quickstart (with signer):
26
+
27
+ import os
28
+ from hypnex_forge import Forge
29
+
30
+ f = Forge(
31
+ chain="arbitrum",
32
+ rpc_url=os.environ["ETH_RPC_URL"],
33
+ private_key=os.environ["PRIVATE_KEY"],
34
+ )
35
+ tx = f.register(
36
+ namespace="myorg",
37
+ name="websearch",
38
+ mcp_uri="https://mcp.example.com/v1",
39
+ categories=["search", "data"],
40
+ price_per_call_wei=int(0.001 * 10**18), # users pay 0.001 MOR per call
41
+ )
42
+ # SDK auto-approves the listing fee, then submits register().
43
+ """
44
+
45
+ from ._constants import (
46
+ CHAIN_IDS,
47
+ DEFAULT_CHAIN,
48
+ DEFAULT_RELAYER_URL,
49
+ ESCROW_ADDRESSES,
50
+ FORGE_ADDRESSES,
51
+ MOR_ADDRESSES,
52
+ PUBLIC_RPCS,
53
+ )
54
+ from .escrow import Escrow, receipt_struct_hash
55
+ from .forge import Forge, Tool, category_tag, tool_id
56
+
57
+ __version__ = "0.2.1"
58
+
59
+ __all__ = [
60
+ "Forge",
61
+ "Escrow",
62
+ "Tool",
63
+ "category_tag",
64
+ "tool_id",
65
+ "receipt_struct_hash",
66
+ "CHAIN_IDS",
67
+ "DEFAULT_CHAIN",
68
+ "DEFAULT_RELAYER_URL",
69
+ "FORGE_ADDRESSES",
70
+ "ESCROW_ADDRESSES",
71
+ "MOR_ADDRESSES",
72
+ "PUBLIC_RPCS",
73
+ "__version__",
74
+ ]