Cliente TypeScript de Mpcium
Un cliente TypeScript para interactuar con el servicio de computación multipartita (MPC) de Mpcium, que permite generar y gestionar billeteras y firmar transacciones en múltiples blockchains.
Firma desde el cliente
Los nodos de MPCIUM se coordinan para firmar la transacción
Requisitos previos
Importante: antes de usar este cliente TypeScript, necesitas configurar los nodos MPC de Mpcium. Los nodos proporcionan la infraestructura MPC subyacente a la que se conecta este cliente. Sigue las instrucciones de instalación y configuración para desplegar los nodos MPC necesarios. Normalmente, necesitarás ejecutar varios nodos (por ejemplo, 3 nodos en una configuración de umbral 2 de 3) antes de usar este cliente.
Descripción general
Mpcium es un servicio que proporciona gestión segura de claves y firma de transacciones mediante computación multipartita. Esta biblioteca cliente te permite:
- Generar claves criptográficas sin exponer material de claves privadas
- Firmar transacciones para múltiples redes blockchain
- Recibir los resultados de las operaciones criptográficas mediante suscripciones a eventos
Tipos de clave y blockchains compatibles
- ECDSA: Bitcoin, Ethereum y otras cadenas compatibles con EVM
- EdDSA: Solana, Polkadot, Cardano y otras cadenas basadas en EdDSA
Instalación
npm install @fystack/mpcium-ts
Ejemplo de código disponible en GitHub
Crear un cliente
- Debes generar
event_initiator.keymediante mpcium-cli antes de usar este cliente
import { connect } from "nats";
import { MpciumClient } from "@fystack/mpcium-ts";
async function setupClient() {
// First, establish NATS connection
const nc = await connect({ servers: "nats://localhost:4222" });
// Create client with key path
const mpcClient = await MpciumClient.create({
nc: nc,
keyPath: "./event_initiator.key",
});
return mpcClient;
}
Cliente cifrado (recomendado para uso en producción)
const mpcClient = await MpciumClient.create({
nc: nc,
keyPath: "./event_initiator.key.age",
password: "your-secure-password", // Stored and load secure vault like KMS, Hashicorp vault
});
Generar una billetera
import { connect } from "nats";
import { MpciumClient } from "@fystack/mpcium-ts";
import fs from "fs";
async function generateWallet() {
const nc = await connect({ servers: "nats://localhost:4222" });
const mpcClient = await MpciumClient.create({
nc: nc,
keyPath: "./event_initiator.key",
});
// Store wallets in a file (for testing only)
const walletsFile = "./examples/wallets.json";
const wallets = fs.existsSync(walletsFile)
? JSON.parse(fs.readFileSync(walletsFile, "utf8"))
: {};
// Subscribe to wallet creation results
mpcClient.onWalletCreationResult((event) => {
console.log("Received wallet creation result:", event);
// Store wallet info with wallet_id as key
wallets[event.wallet_id] = {
wallet_id: event.wallet_id,
ecdsa_pub_key: event.ecdsa_pub_key,
eddsa_pub_key: event.eddsa_pub_key,
};
// Save to file (in production, use a database)
fs.writeFileSync(walletsFile, JSON.stringify(wallets, null, 2));
console.log(`Wallet ${event.wallet_id} saved to wallets.json`);
console.log(
"NOTE: File storage is for testing only. Use a database in production."
);
});
// Create the wallet
const walletID = await mpcClient.createWallet();
console.log(`CreateWallet request sent, wallet ID: ${walletID}`);
// Wait for result and handle cleanup
process.on("SIGINT", async () => {
await mpcClient.cleanup();
await nc.drain();
process.exit(0);
});
}
Firmar una transacción de Solana
import { connect } from "nats";
import { MpciumClient, KeyType } from "@fystack/mpcium-ts";
import {
Connection,
Transaction,
SystemProgram,
PublicKey,
LAMPORTS_PER_SOL,
} from "@solana/web3.js";
import fs from "fs";
async function signSolanaTransaction(walletId) {
const nc = await connect({ servers: "nats://localhost:4222" });
const mpcClient = await MpciumClient.create({
nc: nc,
keyPath: "./event_initiator.key",
});
// Get wallet information from wallets.json
const walletsFile = "./examples/wallets.json";
const wallets = JSON.parse(fs.readFileSync(walletsFile, "utf8"));
const wallet = wallets[walletId];
if (!wallet) {
throw new Error(`Wallet ${walletId} not found`);
}
// Connect to Solana devnet
const connection = new Connection(
"https://api.devnet.solana.com",
"confirmed"
);
// Create public key from wallet data
const publicKeyBuffer = Buffer.from(wallet.eddsa_pub_key, "base64");
const fromPublicKey = new PublicKey(publicKeyBuffer);
// Create transaction
const transaction = new Transaction().add(
SystemProgram.transfer({
fromPubkey: fromPublicKey,
toPubkey: new PublicKey("4LKprD1XvTuBupHqWXoS42XsEBHp7qALo3giDBRCNhAV"),
lamports: LAMPORTS_PER_SOL * 0.01,
})
);
// Get recent blockhash
const { blockhash } = await connection.getLatestBlockhash();
transaction.recentBlockhash = blockhash;
transaction.feePayer = fromPublicKey;
// Serialize transaction message
const serializedTx = transaction.serializeMessage();
// Listen for signing results
mpcClient.onSignResult((event) => {
if (event.result_type === 1) {
// Success
const signature = Buffer.from(event.signature, "base64");
transaction.addSignature(fromPublicKey, signature);
if (transaction.verifySignatures()) {
connection
.sendRawTransaction(transaction.serialize())
.then((txId) => console.log(`Transaction sent: ${txId}`));
}
}
});
// Send signing request
await mpcClient.signTransaction({
walletId: walletId,
keyType: KeyType.Ed25519,
networkInternalCode: "solana:devnet",
tx: Buffer.from(serializedTx).toString("base64"),
});
}
Ejemplo completo: sign-solana.ts
Pruebas
1. Genera una billetera MPC
npx ts-node ./examples/generate-wallet.ts
Connected to NATS at localhost:4222
Subscribed to wallet creation results
CreateWallet request sent for wallet: a99900b2-0ef8-4d7e-8c3f-2ef85abbae4c
CreateWallet sent, awaiting result... walletID: a99900b2-0ef8-4d7e-8c3f-2ef85abbae4c
Received wallet creation result: {
wallet_id: 'a99900b2-0ef8-4d7e-8c3f-2ef85abbae4c',
ecdsa_pub_key: '1ftOqTd9z540F7J6bSLJJ8gqn85HlyQKetWB4mACDFBhaodgiNr9ILL5wZ95yWpaqQc77f02rQklUeDSZhLVVA==',
eddsa_pub_key: 'm0qUKZlxmzgYA9sRh1Q7cQJHT8jEdUQjbic8hQNHG2o='
}
Solana wallet address: BTC9kvDchPvu84iMzLbhYBg5bWma4QHDAFumpF41ErjT
Ethereum wallet address: 0x309bdE4d218e44E4a391f4c43Bf6226156D3255b
Wallet saved to wallets.json with ID: a99900b2-0ef8-4d7e-8c3f-2ef85abbae4c
2. Transfiere Solana a la billetera
- Usa Phantom para transferir SOL de devnet a la billetera
3. Firma una transacción de Solana
npx ts-node ./examples/sign-solana.ts a99900b2-0ef8-4d7e-8c3f-2ef85abbae4c
4. Firma una transacción de Ethereum
npx ts-node ./examples/sign-eth.ts a99900b2-0ef8-4d7e-8c3f-2ef85abbae4c