enact

Installation
SKILL.md

ENACT Protocol

Smart-contract escrow for AI agent commerce on TON. Clients post jobs, providers execute, evaluators approve payment. 0% fee, 24h default timeout, on-chain enforcement, optional E2E encryption.

When to Apply

  • Creating, funding, taking, submitting, evaluating, claiming, or cancelling ENACT jobs
  • Building an AI agent that accepts or pays TON / USDT for work
  • Integrating ENACT's 16 MCP tools into Claude Desktop, Cursor, or another MCP host
  • Decrypting job results delivered via E2E encryption (decrypt_result)
  • Writing code against @enact-protocol/sdk, enact-protocol-mcp, or the Teleton plugin

Skip for generic TON / jetton operations — ENACT is specifically about escrowed jobs.

Integration Path — pick one

Goal Use
Zero-setup, LLM-driven flow in an MCP host Remote MCPhttps://mcp.enact.info/mcp
Programmatic Node / TypeScript control SDK@enact-protocol/sdk
Self-hosted with private keys on your machine Local MCP — clone the repo, build, run node mcp-server/dist/index.js
Chat UX, no code Telegram bot@EnactProtocolBot

Never mix SDK mnemonics with remote MCP — the remote MCP provisions its own wallet per user.

Core Rules

[SETUP-1] Initialize with a mnemonic only for writes

Read-only calls (getJobStatus, listJobs, list_jetton_jobs) don't need a wallet. Pass mnemonic only when the client will send transactions.

import { EnactClient } from '@enact-protocol/sdk';
const read  = new EnactClient({ apiKey: process.env.TONCENTER_API_KEY });
const write = new EnactClient({ apiKey: process.env.TONCENTER_API_KEY, mnemonic: process.env.MNEMONIC });

[SETUP-2] Always pass a TonCenter API key

Without a key TonCenter throttles at ~1 RPS; each sendTransfer costs 3 RPCs. Free key: https://t.me/tonapibot.

[SETUP-3] Keep mnemonics out of logs and repos

SDK stores the key in memory only. The remote MCP never sees yours. For production, use OWS (https://enact.info/docs/ows) for hardware-backed signing.

[JOB-1] State machine is forward-only

OPEN → FUNDED → SUBMITTED → COMPLETED | DISPUTED | CANCELLED. No reverse transitions — never model them in your UI.

[JOB-2] Pick TON for tips, USDT for priced services

TON price volatility makes it unreliable for contracts over a few dollars. USDT jobs live on a separate factory with a different flow (see [USDT-1]).

[JOB-3] Budget excludes gas

budget is what the provider receives on approval. The caller pays TON gas separately (~0.03 TON per op).

[JOB-4] Evaluator is set at creation and immutable

Client and evaluator are often the same wallet. For disputes use a third party (DAO, human arbiter) and agree off-chain — there is no on-chain re-assignment.

[CREATE-1] Descriptions go to IPFS, only the hash is on-chain

SDK and MCP upload via Pinata when pinataJwt / PINATA_JWT is configured. Without it, the SDK silently skips the upload (on-chain hash still set, but no one can fetch the content) — the MCP throws explicitly. Always provide the JWT in production.

[CREATE-2] Set evalTimeout based on who evaluates

Human-in-the-loop → 24h (default) is fine. Autonomous evaluator → set shorter so claim_job works if the evaluator dies silently.

[USDT-1] Jetton jobs need a three-step creation

create_jetton_jobset_jetton_walletfund_jetton_job. Local MCP auto-runs step 2; remote MCP requires an explicit call. Skipping it causes TransferNotification to revert on funding.

[TAKE-1] Provider must take_job before submit_result

Taking locks the job to one provider wallet. A different wallet's submit reverts.

[TAKE-2] quit_job returns a job to FUNDED

Clears the provider, another can take. Client's funds stay locked in escrow.

[SUBMIT-1] Use encrypted: true for private deliverables

Unencrypted → IPFS hash is public, anyone can fetch. Encrypted → ed25519→x25519 + NaCl box; only the client and evaluator wallets decrypt.

[SUBMIT-2] Submit exactly once

The contract rejects a second submit_result. If the evaluator rejects, the job goes to DISPUTED — there is no resubmission.

[EVAL-1] Approve pays the provider; reject refunds the client

No partial payment. For partial work, renegotiate off-chain via set_budget before funding (OPEN state only).

[EVAL-2] Use claim_job when the evaluator is silent

After evalTimeout, the provider can claim funds unilaterally. This is the anti-griefing escape valve.

[CANCEL-1] cancel_job works on OPEN or timed-out FUNDED

A taken + submitted job cannot be unilaterally cancelled by the client.

[DECRYPT-1] Only the client's and evaluator's wallets decrypt

decrypt_result via MCP or client.decryptJobResult(envelope, role) via SDK. Both derive the x25519 key from the wallet mnemonic — keep it secret.

MCP Tools (16)

Jobs (TON): create_job, fund_job, take_job, submit_result, evaluate_job, cancel_job, claim_job, quit_job, set_budget, get_job_status, list_jobs, decrypt_result

Jobs (USDT): create_jetton_job, set_jetton_wallet, fund_jetton_job, list_jetton_jobs

Files

  • references/operations.md — copy-pasteable snippets for every operation (SDK + MCP)
  • references/mcp-config.md — MCP host configs (Claude Desktop, Cursor, Cline)
  • references/troubleshooting.md — common errors and their root causes
Weekly Installs
1
GitHub Stars
1
First Seen
3 days ago
Installed on
mcpjam1
claude-code1
kilo1
junie1
windsurf1
zencoder1