zcash_sign_mpc
Sign a message hash through Ika 2PC-MPC without exposing the full private key. Uses two on-chain transactions and returns a DER-encoded ECDSA signature.
Instructions
Sign a message hash through Ika 2PC-MPC. Two on-chain transactions: presign + sign. Neither party sees the full private key. Returns DER-encoded ECDSA signature.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| wallet_id | Yes | dWallet object ID from create_wallet | |
| message_hash | Yes | Hex-encoded 32-byte message hash (sighash) to sign | |
| chain | Yes | Chain determines hash algorithm (DoubleSHA256 or KECCAK256) | |
| encryption_seed | Yes | Hex encryption seed from wallet creation | |
| sui_private_key | Yes | Sui private key for signing the MPC transactions | |
| ika_coin_id | No | IKA coin object ID |
Implementation Reference
- src/tools/sign-mpc.ts:19-57 (handler)Handler function for 'zcash_sign_mpc'. Accepts wallet_id, message_hash, chain, encryption_seed, sui_private_key, and optional ika_coin_id. Returns instructions for using the @frontiercompute/zcash-ika package to perform 2PC-MPC signing.
async ({ wallet_id, message_hash, chain, encryption_seed, sui_private_key, ika_coin_id }) => { try { const hashAlgo: Record<string, string> = { "zcash-transparent": "DoubleSHA256", bitcoin: "DoubleSHA256", ethereum: "KECCAK256", }; const result = { status: "sign_requires_zcash_ika_package", instructions: { step1: "import { sign } from '@frontiercompute/zcash-ika'", step2: `const sig = await sign(config, { messageHash: Buffer.from('${message_hash}', 'hex'), walletId: '${wallet_id}', chain: '${chain}', encryptionSeed: '${encryption_seed}' })`, }, signing_params: { curve: "secp256k1", algorithm: "ECDSA", hash: hashAlgo[chain], }, flow: [ "TX 1: Request presign (pre-compute MPC ephemeral key share)", "Poll for presign completion (up to 5 min on testnet)", "TX 2: Approve message + request signature", "Poll for sign completion", "Parse DER-encoded ECDSA signature from output", ], wallet_id, message_hash, chain, }; return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }], }; } catch (err) { const msg = err instanceof Error ? err.message : String(err); return { content: [{ type: "text" as const, text: `Error: ${msg}` }], isError: true }; } } - src/tools/sign-mpc.ts:9-17 (schema)Input schema/type definitions for the zcash_sign_mpc tool using Zod. Defines wallet_id, message_hash, chain (zcash-transparent|bitcoin|ethereum), encryption_seed, sui_private_key, and optional ika_coin_id.
{ wallet_id: z.string().describe("dWallet object ID from create_wallet"), message_hash: z.string().describe("Hex-encoded 32-byte message hash (sighash) to sign"), chain: z .enum(["zcash-transparent", "bitcoin", "ethereum"]) .describe("Chain determines hash algorithm (DoubleSHA256 or KECCAK256)"), encryption_seed: z.string().describe("Hex encryption seed from wallet creation"), sui_private_key: z.string().describe("Sui private key for signing the MPC transactions"), ika_coin_id: z.string().optional().describe("IKA coin object ID"), - src/tools/sign-mpc.ts:4-59 (registration)Registration of the 'zcash_sign_mpc' tool on the McpServer via the registerSignMpcTool function.
export function registerSignMpcTool(server: McpServer) { server.tool( "zcash_sign_mpc", "Sign a message hash through Ika 2PC-MPC. Two on-chain transactions: presign + sign. " + "Neither party sees the full private key. Returns DER-encoded ECDSA signature.", { wallet_id: z.string().describe("dWallet object ID from create_wallet"), message_hash: z.string().describe("Hex-encoded 32-byte message hash (sighash) to sign"), chain: z .enum(["zcash-transparent", "bitcoin", "ethereum"]) .describe("Chain determines hash algorithm (DoubleSHA256 or KECCAK256)"), encryption_seed: z.string().describe("Hex encryption seed from wallet creation"), sui_private_key: z.string().describe("Sui private key for signing the MPC transactions"), ika_coin_id: z.string().optional().describe("IKA coin object ID"), }, async ({ wallet_id, message_hash, chain, encryption_seed, sui_private_key, ika_coin_id }) => { try { const hashAlgo: Record<string, string> = { "zcash-transparent": "DoubleSHA256", bitcoin: "DoubleSHA256", ethereum: "KECCAK256", }; const result = { status: "sign_requires_zcash_ika_package", instructions: { step1: "import { sign } from '@frontiercompute/zcash-ika'", step2: `const sig = await sign(config, { messageHash: Buffer.from('${message_hash}', 'hex'), walletId: '${wallet_id}', chain: '${chain}', encryptionSeed: '${encryption_seed}' })`, }, signing_params: { curve: "secp256k1", algorithm: "ECDSA", hash: hashAlgo[chain], }, flow: [ "TX 1: Request presign (pre-compute MPC ephemeral key share)", "Poll for presign completion (up to 5 min on testnet)", "TX 2: Approve message + request signature", "Poll for sign completion", "Parse DER-encoded ECDSA signature from output", ], wallet_id, message_hash, chain, }; return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }], }; } catch (err) { const msg = err instanceof Error ? err.message : String(err); return { content: [{ type: "text" as const, text: `Error: ${msg}` }], isError: true }; } } ); } - src/index.ts:24-49 (registration)Import and invocation of registerSignMpcTool in the main server entry point.
import { registerSignMpcTool } from "./tools/sign-mpc.js"; import { registerShieldTool } from "./tools/shield.js"; import { registerVerifyEvmTool } from "./tools/verify-evm.js"; const server = new McpServer({ name: "zcash-mcp", version: "1.2.0", }); registerBalanceTool(server); registerSendTool(server); registerMemoTool(server); registerAttestTool(server); registerVerifyTool(server); registerStatsTool(server); registerChainTools(server); registerAnchorTools(server); registerEventTools(server); registerInvoiceTool(server); registerWatchTool(server); registerReceiptTool(server); registerIdentityTool(server); registerReputationTool(server); registerCrosschainTool(server); registerCreateWalletTool(server); registerSignMpcTool(server);