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.
Project description
hypnex-forge (Python)
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).
pip install hypnex-forge
Affiliation & monetization
This SDK is published by Hypnex Labs. Hypnex is not affiliated with the Morpheus AI Foundation.
register()costs 1 MOR (configurable on-chain by claim-admin), forwarded directly to the Hypnex Labs treasury at0x22B5C0075372E743042b2d62b3D254425Eb957D8inside the same tx. The SDK auto-approves the MOR allowance on first use.pricePerCallWeiis 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.
Quickstart — Phase 1 (listings)
Read-only
from hypnex_forge import Forge
f = Forge(chain="arbitrum")
print(f.total_tools())
print(f.list_tools(0, 100))
print(f.get_listing_fee_wei()) # 10**18 = 1 MOR
Register a tool (with signer)
import os
from hypnex_forge import Forge
f = Forge(
chain="arbitrum",
rpc_url=os.environ["ETH_RPC_URL"],
private_key=os.environ["PRIVATE_KEY"],
)
tx = f.register(
namespace="myorg",
name="websearch",
mcp_uri="https://mcp.example.com/v1",
categories=["search", "data"],
price_per_call_wei=int(0.001 * 10**18),
)
print("tool registered:", tx)
Quickstart — Phase 3 (escrow + per-call settlement)
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).
1. Tool owner: register a signer key
from hypnex_forge import Escrow, tool_id
esc = Escrow(chain="arbitrum", private_key=os.environ["TOOL_OWNER_PK"])
tid = tool_id("myorg", "websearch")
esc.set_signer(tid, "0xYourSessionKeyOrEoa")
2. Agent: pre-fund per-tool escrow
from hypnex_forge import Escrow, tool_id
esc = Escrow(chain="arbitrum", private_key=os.environ["AGENT_PK"])
tid = tool_id("myorg", "websearch")
# Auto-approves MOR allowance on first call.
esc.deposit(tid, 10 * 10**18) # 10 MOR runway
print("escrow balance:", esc.balance(tid))
3. Tool server: sign + post receipts
After every N calls, the tool's signer key signs a receipt and posts it
to relayer.hypnex.xyz:
esc = Escrow(chain="arbitrum", private_key=os.environ["TOOL_OWNER_PK"])
esc.call_with_receipt(
tool_id=tid,
agent="0xAgentAddress",
call_count=100, # cumulative for this period
period_id=42, # strictly increasing per (toolId, agent)
)
# The relayer batches and submits settle() on the next cron tick.
4. Tool owner: withdraw accrued revenue
print("accrued:", esc.tool_revenue(tid) / 1e18, "MOR")
esc.withdraw_tool(tid, "0xYourColdWallet")
5. Agent: 24h-delayed self-custody exit
If a tool owner misbehaves, agents can pull remaining escrow back:
esc.agent_request_withdraw(tid) # opens a 24h window
# ... 24 hours later ...
esc.agent_execute_withdraw(tid, "0xAgentAddress")
The relayer has the full 24h to flush pending settlements before the exit becomes executable.
Public API
Forge (Phase 1 — listings)
Forge(address=None, chain="arbitrum", w3=None, rpc_url=None,
account=None, private_key=None)
# read
.total_tools() -> int
.list_tools(offset=0, limit=100) -> list[bytes32]
.tools_of(owner) -> list[bytes32]
.tools_in_category(label_or_bytes32) -> list[bytes32]
.get_tool(tool_id) -> Tool
.is_registered(tool_id) -> bool
.tool_id_of(namespace, name) -> bytes32
.get_listing_fee_wei() -> int
.get_claim_admin() -> str
.get_mor_balance(address=None) -> int
.get_mor_allowance(owner=None) -> int
# write (signer required)
.register(namespace, name, mcp_uri, categories, price_per_call_wei=0) -> tx
.update_tool(tool_id, mcp_uri, price_per_call_wei) -> tx
.set_categories(tool_id, categories) -> tx
.deactivate(tool_id) -> tx
.reactivate(tool_id) -> tx
.transfer_ownership(tool_id, new_owner) -> tx
Escrow (Phase 3 — per-call settlement)
Escrow(address=None, chain="arbitrum", w3=None, rpc_url=None,
account=None, private_key=None, relayer_url=None)
# read
.balance(tool_id, agent=None) -> int
.tool_revenue(tool_id) -> int
.treasury_revenue() -> int
.signer_of(tool_id) -> str
.last_period_id(tool_id, agent) -> int
.withdraw_unlock_at(tool_id, agent) -> int
.protocol_fee_bps() -> int
.relayer_address() -> str
.claim_admin() -> str
.quote_settle(tool_id, call_count) -> (total, tool_payout, protocol_fee)
# agent-side write
.deposit(tool_id, amount, auto_approve=True) -> tx
.agent_request_withdraw(tool_id) -> tx
.agent_execute_withdraw(tool_id, to=None) -> tx
# tool-owner-side write
.set_signer(tool_id, new_signer) -> tx
.withdraw_tool(tool_id, to) -> tx
.sign_receipt(tool_id, agent, call_count, period_id) -> bytes
.post_receipt(tool_id, agent, call_count, period_id, signature, ...) -> dict
.call_with_receipt(tool_id, agent, call_count, period_id, ...) -> dict
# relayer / claim-admin write
.settle(tool_id, agent, call_count, period_id, signature) -> tx
.withdraw_treasury(to) -> tx
.set_relayer(new_relayer) -> tx
.set_protocol_fee_bps(new_bps) -> tx
Plus a pure helper:
receipt_struct_hash(*, chain_id, escrow_address, tool_id,
agent, call_count, period_id) -> bytes
The bytes returned match the on-chain Solidity recovery exactly:
keccak256(abi.encode(chainid, escrow, toolId, agent, callCount, periodId))
wrapped with the EIP-191 \x19Ethereum Signed Message:\n32 prefix when
signed.
Environment variables
| Variable | Purpose |
|---|---|
HYPNEX_FORGE_CHAIN |
Default chain (arbitrum or base) |
HYPNEX_FORGE_RPC_URL |
Override RPC URL |
HYPNEX_FORGE_ADDRESS |
Override ForgeToolRegistry address |
HYPNEX_FORGE_ESCROW_ADDRESS |
Override ForgeEscrow address |
HYPNEX_FORGE_RELAYER_URL |
Override relayer endpoint (default https://relayer.hypnex.xyz) |
PRIVATE_KEY |
Required for write methods |
Status
-
Phase 1 — paid listings on Arbitrum One + Base mainnet (live since 2026-05-09).
-
Phase 2 — discovery UI at
forge.hypnex.xyz(live). -
Phase 3 — pre-paid escrow + per-call settlement (
ForgeEscrow). Live since 2026-05-09:- Arbitrum One:
0x88E32F332A5140Af16c6273d8131bC84BC089Da5 - Base mainnet:
0xCC258a7BBF361fd824e87D4b3C0D394De6Fd454F
SDK 0.2.1+ resolves these automatically when you pass
chain="arbitrum"orchain="base". The Cloudflare Worker relayer atrelayer.hypnex.xyzis the last operational piece; until it's live, receipts can be submitted directly toEscrow.settle()by the configured relayer EOA. - Arbitrum One:
License
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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hypnex_forge-0.2.3.tar.gz.
File metadata
- Download URL: hypnex_forge-0.2.3.tar.gz
- Upload date:
- Size: 163.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f70feb1bca151fb3cccc52a4b4bf3333ace16c59ff02933172087a5fa433bf91
|
|
| MD5 |
a930e4ee8f4b582b6b810ac4794d3e62
|
|
| BLAKE2b-256 |
91deb99a3f5268f00167271e29079a89c79474195b856e0681ab3ccaaf678437
|
File details
Details for the file hypnex_forge-0.2.3-py3-none-any.whl.
File metadata
- Download URL: hypnex_forge-0.2.3-py3-none-any.whl
- Upload date:
- Size: 17.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
03ffb6af4e0c8ff7bf5d762c62688e15d244cca229af7999d3788abdae51836f
|
|
| MD5 |
93ad429e874a9e1453dca42404d9e719
|
|
| BLAKE2b-256 |
2e64416acab58603e14768bef188868c2343181a6a6f851f738a78958b3df34b
|