A powerful TypeScript SDK for interacting with Hydra Heads on Cardano.
Hydra is a layer 2 protocol for Cardano that enables fast, low-cost transactions by creating off-chain "heads" where multiple parties can interact. This package provides a complete SDK for:
- Connecting to and managing Hydra Heads
- Committing and decommitting funds
- Building and submitting transactions within Hydra Heads
- Handling all Hydra protocol operations (init, abort, close, contest, fanout)
- Event-driven architecture for real-time updates
npm install @meshsdk/hydraimport { HydraProvider, HydraInstance } from "@meshsdk/hydra";
import { BlockfrostProvider } from "@meshsdk/core";
const hydraProvider = new HydraProvider({
httpUrl: "http://localhost:4001", // Your Hydra node URL
});
await hydraProvider.connect();
const blockchainProvider = new BlockfrostProvider("YOUR_BLOCKFROST_KEY");
const hydraInstance = new HydraInstance({
provider: hydraProvider,
fetcher: blockchainProvider,
submitter: blockchainProvider,
});await hydraProvider.init();
// Wait for all parties to commit
// Once all parties have committed, the head will open automaticallyconst emptyCommitTx = await hydraInstance.commitEmpty();
await wallet.submitTx(emptyCommitTx);const txHash = await hydraProvider.newTx({
type: "Tx ConwayEra",
cborHex: unsignedTransactionCbor,
});The main class for connecting to and managing Hydra Heads.
new HydraProvider({
httpUrl: string;
wsUrl?: string;
history?: boolean;
address?: string;
})connect()- Establishes connection to the Hydra Headdisconnect(timeout?: number)- Disconnects from the Hydra Head (default timeout: 5 minutes)
init()- Initializes a new Hydra Head (only when status is Idle)abort()- Aborts a head before it opens (only during Initializing phase)close()- Closes an open head, starting the contest periodcontest()- Contests a closed head if neededfanout()- Finalizes the head closure and distributes funds
newTx(transaction: hydraTransaction)- Submits a transaction to the open headrecover(txHash: string)- Recovers a deposit transaction by its hash
fetchUTxOs(address?: string)- Fetches UTxOs from the Hydra HeadfetchProtocolParameters()- Fetches protocol parameters
submitTx(tx: string)- Submits a transaction to the Hydra Head
onStatusChange(event: string, callback: Function)- Listen to Hydra eventsonMessage(callback: Function)- Register a callback for all messages
The provider emits various events:
Greetings- Initial connection message with head statusHeadIsInitializing- Head initialization startedHeadIsOpen- Head is now open and readyHeadIsClosed- Head has been closedHeadIsAborted- Head was abortedTxValid- Transaction was acceptedTxInvalid- Transaction was rejectedSnapshot- New snapshot createdCommit- New commit receivedDecommit- Decommit occurred- And more...
A higher-level interface for interacting with Hydra Heads, providing convenient methods for common operations.
new HydraInstance({
provider: HydraProvider;
fetcher: 'blockchainProvider';
submitter: 'blockchainProvider';
})commitEmpty()- Creates an empty commit transaction (no funds)commitFunds(txHash: string, outputIndex: number)- Commits a specific UTxO to the headcommitBlueprint(txHash: string, outputIndex: number, transaction: hydraTransaction)- Commits a UTxO as a blueprint transaction
decommit()- Decommits all your funds from the head
import { HydraProvider, HydraInstance } from "@meshsdk/hydra";
import { BlockfrostProvider, MeshTxBuilder, MeshWallet } from "@meshsdk/core";
// Setup providers
const hydraProvider = new HydraProvider({
httpUrl: "http://localhost:4001",
});
const blockchainProvider = new BlockfrostProvider("YOUR_BLOCKFROST_KEY");
const hydraInstance = new HydraInstance({
provider: hydraProvider,
fetcher: blockchainProvider,
submitter: blockchainProvider,
});
await hydraProvider.connect();
await hydraProvider.init();
const commitTx = await hydraInstance.commitFunds(txHash, outputIndex);
await wallet.submitTx(commitTx);
hydraProvider.onMessage("HeadIsOpen", async () => {
const txBuilder = new MeshTxBuilder({
fetcher: blockchainProvider,
submitter: blockchainProvider,
params: await hydraProvider.fetchProtocolParameters(),
isHydra: true,
});
// Add your transaction logic
const unsignedTx = await txBuilder
.sendLovelace(address, "1000000")
.complete();
const txHash = await hydraProvider.newTx({
type: "Tx ConwayEra",
cborHex: unsignedTx,
});
console.log("Transaction submitted:", txHash);
});
// When done, close the head
await hydraProvider.close();
await hydraProvider.fanout();const hydraProvider = new HydraProvider({
httpUrl: "http://localhost:4001",
});
await hydraProvider.connect();
hydraProvider.onMessage((message) => {
switch (message.tag) {
case "Greetings":
console.log("Connected! Head status:", message.headStatus);
break;
case "HeadIsOpen":
console.log("Head is now open!");
break;
case "TxValid":
console.log("Transaction accepted:", message.transactionId);
break;
case "TxInvalid":
console.error("Transaction rejected:", message.validationError);
break;
case "Snapshot":
console.log("New snapshot:", message.snapshot);
break;
}
});- Node.js 16+ or modern browser with ES module support
- Access to a Hydra node (local or remote)
- Mesh SDK peer dependencies installed
For more detailed documentation, examples, and guides, visit:
- Official Documentation: meshjs.dev/hydra
- Hydra Protocol Docs: hydra.family/head-protocol
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the terms specified in the LICENSE file.
For support and questions:
- Check the documentation
- Open an issue on GitHub
- Visit the Mesh community forums