Catalog npm
Back to packageRELEASE DETAILS

0.1.0

npm

@0xinfrax/mpc-sdk

InfraX MPC SDK — lightweight independent client for the MPC wallet microservice (email-based key-shard wallets). Wallet module (sendCode/register/recover/status/createWallet) + Session module (unlock/lock/status). No dependency on infrax-dk.

email-recoveryinfraxkey-shardmpcsessionwalletchained25519frostsolanatss
Published8 Aug 2026
Direct dependencies1
Transitive dependenciesNot calculated

README

Current package documentation

@0xinfrax/mpc-sdk

InfraX MPC 独立轻量 SDK —— 面向 MPC 微服务(邮箱分片托管钱包)的零依赖 TypeScript 客户端。 不依赖整包 infrax-dk,版本独立演进(MQ-10 补充 E-5)。

当前覆盖四个模块(19 方法,E-4④ 起支持单邮箱 1:N 多子钱包;链上模块 E-5d 接 TSS 分片签名;Solana 模块 MPC-SOL-5 接 FROST Ed25519 分片签名):

模块方法端点
钱包wallet.sendCodePOST /api/v2/mpc/send-code
钱包wallet.registerPOST /api/v2/mpc/register(每次注册新建一个子钱包,返回 walletId)
钱包wallet.recoverPOST /api/v2/mpc/recover(walletId 可指定子钱包,缺省首个)
钱包wallet.statusGET /api/v2/mpc/status(email 可带 walletId 定位子钱包)
钱包wallet.listWalletsGET /api/v2/mpc/wallets(同邮箱全部子钱包)
钱包wallet.createWalletPOST /api/v2/mpc/send-code(组合入口)
会话session.unlockPOST /api/v2/mpc/session/unlock(walletId 可指定子钱包)
会话session.lockPOST /api/v2/mpc/session/lock
会话session.statusGET /api/v2/mpc/session/status
链上(EVM)chain.balancePOST /api/v2/mpc/balance(原生币 + 可选 ERC20)
链上(EVM)chain.signMessagePOST /api/v2/mpc/sign-message(EIP-191,TSS 分片签名)
链上(EVM)chain.signTypedDataPOST /api/v2/mpc/sign-typed-data(EIP-712,TSS 分片签名)
链上(EVM)chain.sendTransactionPOST /api/v2/mpc/send-transaction(原生币 / ERC20 transfer)
链上(EVM)chain.contractReadPOST /api/v2/mpc/contract-read(只读 eth_call)
链上(EVM)chain.contractWritePOST /api/v2/mpc/contract-write(staticCall 模拟 + TSS 签名广播)
链上(EVM)chain.gasEstimatePOST /api/v2/mpc/gas-estimate
Solanasolana.signPOST /api/v2/mpc/solana/sign(原始 message → 64B Ed25519 签名,FROST 2-of-3)
Solanasolana.sendTransactionPOST /api/v2/mpc/solana/send-transaction(base64 已签名交易 → 广播 + 确认轮询)
Solanasolana.balancePOST {chainRpcUrl}/v1/rpc/solana(getBalance,读 chain-rpc 网关,非 MPC 服务)

E-4④ 单邮箱 1:N:一个邮箱可派生多个 Agent 子钱包(如 50 子钱包并发模型)。register 每次创建新钱包返回 walletId;recover / status / session.unlock 带 walletId 精确命中子钱包,缺省作用于同邮箱首个(向后兼容)。token 一经解锁即绑定到该子钱包,后续链上操作无需再带 walletId。

E-5d 链上模块(TSS 就绪):服务端四签名/交易端点已迁移 cggmp24 TSS 2-of-2 分片签名(服务端仅持分片、不再重建完整私钥,见 docs/TSS_EVALUATION.md);SDK 侧为纯 HTTP 封装——签名端点返回 65B 序列化签名(0x + r||s||v),交易端点返回 txHash;交易类数量参数统一用字符串(服务端 parseUnits/parseEther 自理)。

MPC-SOL-5 Solana 模块(ed25519 / FROST 就绪):钱包须为 ed25519 曲线(register({ curve: 'ed25519' }),或用 seed 导入存量 32B 种子),服务端走独立 FROST 2-of-3 签名链路(projects/mpc-ed25519),与 EVM 路径物理隔离(独立进程 9210/9211/9212)。三处与 EVM 模块的关键差异:

  1. 待签数据是原始 message 字节(hex,≤ 4096B),不是 32B 摘要 —— Ed25519 内部才做 SHA-512,且 Ed25519ph 预哈希变体 Solana 运行时不支持。
  2. 签名是 64B R‖z(128 hex,无 0x),且无恢复 id v —— 验签靠公钥而非恢复地址(@solana/web3.js v1 未导出 Ed25519 验签 API,用 tweetnacl)。
  3. 交易模型由客户端持有:@solana/web3.js 构建交易 → serializeMessage() 交 solana.sign → tx.addSignature() 组装 → base64 交 solana.sendTransaction。服务端不重写交易模型。

EVM 专属端点对 ed25519 钱包返 400(不静默降级):balance / sign-message / sign-typed-data / sign-digest / sign / send-transaction / contract-read / contract-write / gas-estimate;反向 /solana/* 只接受 ed25519 钱包。因此 solana.balance 不经 MPC 服务,由 SDK 直读 chain-rpc 网关(构造时传 chainRpcUrl + chainRpcReadKey)。

安装

npm i @0xinfrax/mpc-sdk

Node.js >= 18(使用原生 fetch,零运行时依赖)。

QuickStart

import { MpcClient, MpcApiError } from '@0xinfrax/mpc-sdk';

const mpc = new MpcClient({
  baseUrl: process.env.MPC_URL ?? 'http://127.0.0.1:9104', // 生产按实际可达地址
  apiKey: process.env.MPC_API_KEY, // MPC 服务鉴权 key(出站 X-API-Key)
});

// 1. 发验证码 → 邮箱收码
await mpc.wallet.sendCode({ email: 'agent@example.com' });

// 2. 注册托管钱包
const reg = await mpc.wallet.register({ email: 'agent@example.com', code: '123456' });
console.log(reg.data.walletAddress);

// 3. 解锁会话(后续链上操作的凭证)
const s = await mpc.session.unlock({ email: 'agent@example.com', code: '123456' });
const token = s.data.token;

// 4. 会话状态
const st = await mpc.session.status({ token });
console.log(st.data.unlocked, st.data.remainingSeconds);

// 5. 链上操作(E-5d,token 即凭证)
const bal = await mpc.chain.balance({ token, chain: 'sepolia' });
console.log(bal.data.nativeBalance, bal.data.nativeSymbol);

const sig = await mpc.chain.signMessage({ token, message: 'hello' });
console.log(sig.data.signature, sig.data.address);

const tx = await mpc.chain.sendTransaction({
  token, to: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8', amount: '0.01', chain: 'sepolia',
});
console.log(tx.data.txHash);

// 6. 锁定会话
await mpc.session.lock(token);

// 7. 邮箱恢复(封装「验证码 → 分片重建 → 地址校验」完整流程)
const recovered = await mpc.wallet.recover({
  email: 'agent@example.com',
  code: '654321',
  expectedAddress: reg.data.walletAddress, // 可选:客户端二次地址校验
});
console.log(recovered.data.walletAddress === reg.data.walletAddress);

Solana(ed25519)用法

import { Connection, PublicKey, SystemProgram, Transaction } from '@solana/web3.js';

const mpc = new MpcClient({
  baseUrl: process.env.MPC_URL!,                        // MPC 服务(sign / sendTransaction)
  apiKey: process.env.MPC_API_KEY,
  chainRpcUrl: process.env.CHAIN_RPC_URL,               // 默认 http://127.0.0.1:9130
  chainRpcReadKey: process.env.CHAIN_RPC_READ_KEY,      // 平台读 key 或订阅 rx_ key(仅 solana.balance 需要)
});

// 0) 钱包(一次性):创建 ed25519 钱包;已有存量 Solana 私钥可用 seed 导入(地址逐字节一致)
await mpc.wallet.sendCode({ email: 'agent@example.com' });
const reg = await mpc.wallet.register({
  email: 'agent@example.com', code: '123456',
  curve: 'ed25519',
  // seed: 'a5c9…'   // 可选:32B 种子 hex(64 hex),导入存量 Solana 私钥
});
console.log(reg.data.walletAddress, reg.data.curve);    // base58 地址 / 'ed25519'

// 1) 解锁会话(token 绑定该子钱包,后续 solana.* 凭 token)
const { data: sess } = await mpc.session.unlock({ email: 'agent@example.com', code: '654321' });

// 2) 余额(经 chain-rpc 网关 getBalance;lamports 与 SOL 双单位)
const { data: bal } = await mpc.solana.balance({ address: sess.address });
console.log(bal.lamports, bal.sol);                     // '4995000' '0.004995'
// ⚠️ fee payer 余额须 > 890880 lamports(免租门槛),否则广播报 InsufficientFundsForRent

// 3) 构建交易(交易模型由客户端持有)→ message 原文交 MPC 签名 → 组装 → 广播
const conn = new Connection('https://api.mainnet-beta.solana.com');
const tx = new Transaction().add(SystemProgram.transfer({
  fromPubkey: new PublicKey(sess.address),
  toPubkey: new PublicKey('GmaDrppBC7P5ARKV8g3djiwP89vz1jLK23V2GBjuAEGB'),
  lamports: 1000,
}));
tx.feePayer = new PublicKey(sess.address);
tx.recentBlockhash = (await conn.getLatestBlockhash()).blockhash;

const { data: signed } = await mpc.solana.sign({
  token: sess.token,
  message: tx.serializeMessage().toString('hex'),   // ← 原始 message(非 32B 摘要)
});
tx.addSignature(new PublicKey(signed.address), Buffer.from(signed.signature, 'hex'));
if (!tx.verifySignatures()) throw new Error('signature mismatch');   // web3.js 内部验签

const { data: sent } = await mpc.solana.sendTransaction({
  token: sess.token,
  transaction: tx.serialize({ requireAllSignatures: true }).toString('base64'),
});
console.log(sent.txHash, sent.confirmed, sent.signatureStatus?.confirmationStatus);

要点:

  • FROST 签名非确定性:同一 message 两次调用返回不同签名,均有效(每方独立随机 nonce)。
  • sign 的 partnerIndex:1(默认,片2)/ 2(片3,仅 2-of-3 钱包可用)。
  • sendTransaction 的 wait:默认 true 轮询 getSignatureStatuses 至 confirmed/finalized;false 仅广播(confirmed:false / reason:'wait=false');reason:'timeout' 不代表失败,须以 txHash 复核。
  • base58 地址大小写敏感:任何环节(含 recover({ expectedAddress }) 客户端校验)都不可 toLowerCase()。
  • 服务端计费:solana_sign 1e14 wei / solana_send_transaction 1e15 wei(余额不足 → 402)。

错误处理

所有失败均抛 MpcApiError(含 HTTP 状态 + 业务 code + 语义 kind);网络/超时抛 MpcNetworkError。

kind语义典型场景
unauthorized (401)未授权缺/错 key;会话不存在或过期
forbidden (403)禁止外部签发 key 被禁用
bad_request (400)参数错误验证码错误/过期(业务 code 1001)
not_found (404)未找到未注册钱包(1004)
conflict (409)冲突恢复地址与期望不一致(SDK 40900)
rate_limited (429)限流验证码尝试次数超限
server_error (5xx)服务端错误分片解密失败(500/1007)
try {
  await mpc.wallet.register({ email, code: '000000' });
} catch (e) {
  if (e instanceof MpcApiError) {
    console.log(e.kind, e.status, e.code, e.message);
    // → bad_request 400 1001 Invalid code
  }
}

与 MCP 对应关系

本 SDK 方法对应 Wallet MCP 工具(mcp-server/src/index.ts):mpc_send_code ↔ wallet.sendCode、mpc_register ↔ wallet.register、mpc_recover ↔ wallet.recover、mpc_status ↔ wallet.status、mpc_create_wallet ↔ wallet.createWallet、mpc_session_unlock/lock/status ↔ session.unlock/lock/status。入站(经 MCP 调用)沿用 inboundAuth(MCP_API_KEY),出站(本 SDK)统一 X-API-Key。

开发

npm run build   # tsc → dist/
npm publish     # 发布 @0xinfrax/mpc-sdk(@0xinfrax scope)

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Declared dependencies 1

Native requirements
1 direct targetsNot calculated transitive count
Package / targetRequirementRelationship
typescript
Environment
{
  "local_name": "typescript",
  "alias": false,
  "peer_metadata": null
}
^5.0.0development

Distribution files

1 collected
Distribution 1

Source distribution

Source file
Checksums from source
{
  "shasum": "fe8dbb7e3a406b653e2e4fa2d677552426104ce6",
  "tarball": "https://registry.npmjs.org/@0xinfrax/mpc-sdk/-/mpc-sdk-0.1.0.tgz",
  "fileCount": 14,
  "integrity": "sha512-gXiKITstkG20MOw6xQ2iF6YTWdpvm65nCP2j1v3AcnwU0hsB6LH38rJrIIk70PbFfTCsAd4kIaJGMu/Uu6YEWg==",
  "signatures": [
    {
      "sig": "MEQCIFtiryDemPz/X2pHTLEe56SGtvjntH9Uh7sCnthbYUWiAiAvW3ay8GBvKcDkfgcHCr/P5T5aujiJOE/Gpa3D6U6Bdw==",
      "keyid": "SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"
    }
  ],
  "unpackedSize": 25438
}

Metadata history

Meaningful changes
Current collected state Current

Observed since 21 Oct, 08:56 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package_version:aa4dc7d87fb64e61e2fed2f1b08a79b46c236bf706f2e702712d028dd1ece2d7

Other collected versions

0.4.019 Sept0.3.09 Aug0.2.09 AugView all collected versions →