Devolopers - SDKs APIs & Contracts
Build on Methexis with contracts, a lightweight SDK, and optional indexer APIs for convenience. On‑chain state is canonical; off‑chain services (IPFS/Arweave + indexers) make it fast to integrate.
Status: Testnet first. Addresses and package names marked TBA will be published in Releases.
TL;DR — 5‑minute Quickstart (testnet)
# 1) Install SDKs (JS or Python)
npm i @methexis/sdk # JS/TS
# or
pip install methexis-sdk # Python
# 2) Configure RPC + signer (env)
export ETH_RPC=https://rpc.testnet.example.org
export WALLET=0xYOUR_ADDR
# 3) Register a dataset (hash + manifest URI)
mhx data register \
--content-hash 0xA3F5...7C1E \
--meta-uri ipfs://bafy.../manifest.yaml \
--bond 80
What just happened: you pinned data to IPFS, registered it on‑chain, and posted a refundable bond. A committee will now review your dataset.
Environments
Testnet
Ethereum testnet
https://rpc.testnet.example.org
TBA
(published in Releases)
Mainnet
Ethereum
https://…
TBA
(after audit)
Chain ID: TBA • Block explorer: TBA
Packages
JavaScript/TypeScript:
@methexis/sdk
(Ethers v6 under the hood)Python:
methexis-sdk
(web3.py + requests)CLI:
mhx
(thin wrapper over contracts & IPFS helpers)
Source:
https://github.com/methexisxyz
(modules: token, staking, rewards, governance, data‑registry, validator)
Core Contracts & ABIs (overview)
Token (ERC‑20):
$MTHX
Staking / Rewards
Data Registry →
registerDataset(bytes32 contentHash, string metaURI)
;setDatasetStatus(uint256 id, Status)
Training Coordination →
startRound
,submitModelUpdate
,finalizeRound
Governance (DAO) →
propose
,vote
,queue
,execute
Events (minimal schema)
DatasetRegistered(datasetId, contentHash, submitter)
DatasetStatusChanged(datasetId, status)
RoundStarted(roundId, prevModelHash)
ModelProposed(roundId, modelHash, signers, metricsURI)
ModelFinalized(roundId, modelHash)
RewardsDistributed(roundId, total, breakdownURI)
Slashed(account, amount, reason)
Full ABIs are published with releases. You can also import them from the SDK.
JavaScript / TypeScript (Ethers v6) examples
1) Setup
import { ethers } from "ethers";
import { getContracts } from "@methexis/sdk"; // helper that returns typed ethers.Contract
const provider = new ethers.JsonRpcProvider(process.env.ETH_RPC!);
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, provider);
const { DataRegistry, Training, Staking, Governance } = await getContracts({
chain: "testnet", signer: wallet,
});
2) Register a dataset
// contentHash = sha256 of the archive; metaURI = ipfs://<manifestCID>
const tx = await DataRegistry.registerDataset(
"0xA3F5...7C1E",
"ipfs://bafy.../manifest.yaml"
);
const receipt = await tx.wait();
const evt = receipt.logs.find(l => l.fragment?.name === "DatasetRegistered");
console.log("datasetId:", evt?.args?.datasetId?.toString());
3) Watch validation status → drive UX
DataRegistry.on("DatasetStatusChanged", (datasetId, status) => {
console.log("status", datasetId.toString(), status);
// update your UI: Pending → Accepted/Rejected
});
4) Listen to training lifecycle
Training.on("RoundStarted", (roundId, prevHash) =>
console.log("Round", roundId.toString(), "prev", prevHash)
);
Training.on("ModelProposed", (roundId, modelHash, signers, metricsURI) =>
console.log("Proposed", { roundId: roundId.toString(), modelHash, metricsURI })
);
Training.on("ModelFinalized", (roundId, modelHash) =>
console.log("Finalized", roundId.toString(), modelHash)
);
Training.on("RewardsDistributed", (roundId, total, breakdownURI) =>
console.log("Rewards", roundId.toString(), total.toString(), breakdownURI)
);
5) Propose a governance change
// Example: setValidatorRewardShare(62%)
const iface = new ethers.Interface(["function setValidatorRewardShare(uint256 bps)"]);
const callData = iface.encodeFunctionData("setValidatorRewardShare", [6200]); // 62.00%
const txP = await Governance.propose(callData, "Increase validator share to 62%");
await txP.wait();
console.log("Proposal submitted");
Python (web3.py) examples
from web3 import Web3
from methexis_sdk import load_contracts
web3 = Web3(Web3.HTTPProvider(os.environ["ETH_RPC"]))
acct = web3.eth.account.from_key(os.environ["PRIVATE_KEY"])
contracts = load_contracts(web3, acct, chain="testnet")
# Register dataset
tx = contracts.DataRegistry.functions.registerDataset(
"0xA3F5...7C1E",
"ipfs://bafy.../manifest.yaml"
).build_transaction({"from": acct.address, "nonce": web3.eth.get_transaction_count(acct.address)})
signed = web3.eth.account.sign_transaction(tx, private_key=os.environ["PRIVATE_KEY"])
txhash = web3.eth.send_raw_transaction(signed.rawTransaction)
print("tx", web3.to_hex(txhash))
Indexer API (optional convenience)
While contracts/events are the source of truth, an indexer helps you avoid manual log scans.
REST (proposed):
GET /v1/datasets/:id -> { id, contentHash, status, submitter, metaURI }
GET /v1/datasets?status=Accepted -> [...paged results...]
GET /v1/rounds/:roundId -> { roundId, prevModelHash, modelHash, metricsURI, finalizedAt }
GET /v1/rewards/:roundId -> { total, breakdownURI, allocations[] }
GET /v1/validators/:addr -> { stake, uptime, roundsParticipated, slashes[] }
GET /v1/events?from_block=... -> stream of canonical events
Webhooks (proposed):
dataset.status.changed
— payload:{ datasetId, status }
round.finalized
— payload:{ roundId, modelHash, metricsURI }
rewards.distributed
— payload:{ roundId, total, breakdownURI }
API keys are issued per project; rate limits apply. The indexer mirrors on‑chain data and links off‑chain URIs.
Data flow helpers
Hashing (sha256) & IPFS upload (JS)
import { create } from "ipfs-http-client";
import { createHash } from "crypto";
import fs from "fs";
const ipfs = create({ url: "https://ipfs.your-gateway.example/api/v0" });
const buf = fs.readFileSync("./cleancode-docs-v1.tar.zst");
const contentHash = "0x" + createHash("sha256").update(buf).digest("hex");
const { cid } = await ipfs.add(buf, { pin: true });
const manifestCID = await ipfs.add(fs.readFileSync("./manifest.yaml"));
console.log({ contentHash, archiveCID: cid.toString(), manifestURI: `ipfs://${manifestCID.cid}` });
Event‑driven architecture (recommended)
Subscribe to DatasetStatusChanged and RoundStarted/Finalized to drive UX.
Use idempotent handlers (event replay safe).
Handle reorgs: wait N confirmations (e.g., 12) before acting on payments or irreversible actions.
Contract interaction patterns
Always simulate (staticcall / eth_call) before sending txs that mutate state.
Gas & revert handling: surface revert reasons to users.
Timelock awareness: governance changes aren’t immediate; poll timelock or listen to
Queued
/Executed
(ABI TBA).Multisig compatibility: proposals can be composed & signed by Safe; execution still goes through DAO where required.
Versioning & Compatibility
Semver for SDKs and contract releases (
vMAJOR.MINOR.PATCH
).Breaking changes → new contract addresses (posted in Releases); SDK will expose both
v1
andv2
namespaces during migration.Deprecations are announced at least one quarter in advance in the Roadmap page.
Security & Keys
Prefer hardware wallets or remote signers.
Never store private keys in code or CI; use vaults / KMS.
Rotate API keys and restrict by IP where possible (indexer).
Monitor for Slashed events and set alerts.
Testing & Local Dev
Local anvil/Hardhat/Foundry support (fork testnet).
Mock IPFS gateway + fixtures for dataset manifests.
Contract interfaces shipped with the SDK for quick tests.
Example (Foundry):
forge test -vvv
# Deploy to local dev chain
forge script script/Deploy.s.sol --broadcast --rpc-url http://localhost:8545
Error Model (SDK)
MhxError
base class withcode
andcontext
.Common codes:
E_NO_FUNDS
,E_REVERTED
,E_BAD_MANIFEST
,E_POLICY_VIOLATION
,E_RATE_LIMIT
,E_TIMEOUT
.All network calls support retry with backoff and abort signals.
Frequently Used Recipes
“Show me all Accepted datasets since block X” → indexer
GET /v1/datasets?status=Accepted&from_block=X
or filterDatasetStatusChanged
and querystatus=Accepted
.“Notify users when a round finalizes” → subscribe to
ModelFinalized
+RewardsDistributed
, then send webhook.“Governance dashboard” → index proposals from
ProposalCreated
(ABI TBA), tally votes per block, show timelock ETA.
Support & Links
Releases & Addresses: GitHub → Releases
Package registry: npm / PyPI
Status page: TBA
Responsible disclosure: see Audits & Security page
Last updated