Migration
@hydra-sdk/bridge v1.x → v2.0
@hydra-sdk/bridge 2.0 targets hydra-node 2.x. It is a breaking change, and bridge 1.x is end of life.
next dist-tag — latest still resolves to 1.3.2.pnpm add @hydra-sdk/bridge@next
Why it breaks
hydra-node v2 implements ADR-33 and removes the commit phase. A head now opens directly, so there is nothing to abort and no Committed step; funds enter an open head through incremental deposits instead.
What you have to change
| v1.x | v2.0 |
|---|---|
bridge.commands.abort() | Removed — no commit phase to abort |
bridge.commands.initSync() | Resolves on HeadIsOpen, not HeadIsInitializing |
HeadIsOpen handlers | Reads parties; utxo is gone — take the UTxO set from SnapshotConfirmed or querySnapshotUtxo() |
HeadIsFinalized.utxo | Renamed to finalizedUTxO |
HydraHeadStatus | No Initializing / Final |
HydraHeadInfo | Now a union over `Idle |
Greetings / ClientMessage | No seq / timestamp — they are sent untimed |
Full details
The complete list, including the new APIs (safeClose(), submitL2Tx(), pendingDeposits(), recoverDeposit()) and the wire-format fixes found by testing against a live node, is in MIGRATION-v2.md.
Migration to v1.1.x (legacy)
This guide helps you upgrade from previous versions of Hydra SDK to v1.1.x, which introduces a new utilities system and improved developer experience.
What's Changed
New Utilities System
Version 1.1.0 introduces a completely revamped utilities system with organized namespaces:
Before (v1.0.x):
// Individual utility imports (if available)
import { someUtility } from '@hydra-sdk/core/utils/some-utility'
After (v1.1.x):
// Organized namespace imports
import {
ParserUtils,
TimeUtils,
DatumUtils,
PolicyUtils,
Serializer,
Deserializer
} from '@hydra-sdk/core'
Breaking Changes
1. Utility Function Organization
Before:
// Direct imports from utils (if they existed)
import { hexToBytes, bytesToHex } from '@hydra-sdk/core/utils'
After:
// Namespaced utility imports
import { ParserUtils } from '@hydra-sdk/core'
const hex = ParserUtils.bytesToHex(bytes)
const bytes = ParserUtils.hexToBytes(hex)
2. Time/Slot Utilities
Before:
// Manual slot calculations or external libraries
const currentSlot = calculateSlot(Date.now())
After:
import { TimeUtils, SLOT_CONFIG_NETWORK } from '@hydra-sdk/core'
const currentSlot = TimeUtils.unixTimeToEnclosingSlot(
Date.now(),
SLOT_CONFIG_NETWORK.PREPROD
)
const futureSlot = TimeUtils.unixTimeToEnclosingSlot(
Date.now() + 3600000,
SLOT_CONFIG_NETWORK.PREPROD
)
3. Datum Creation
Before:
// Manual WASM operations
import { CardanoWASM } from '@hydra-sdk/cardano-wasm'
const datum = CardanoWASM.PlutusData.new_integer(
CardanoWASM.BigInt.from_str('42')
)
After:
import { DatumUtils } from '@hydra-sdk/core'
const datum = DatumUtils.mkInt(42)
const bytesDatum = DatumUtils.mkBytes('deadbeef')
const constrDatum = DatumUtils.mkConstr(0, [datum, bytesDatum])
Migration Steps
Step 1: Update Dependencies
# Update to latest version
npm update @hydra-sdk/core @hydra-sdk/bridge @hydra-sdk/transaction @hydra-sdk/cardano-wasm
# Or with specific version
npm install @hydra-sdk/core@^1.1.0 @hydra-sdk/cardano-wasm
Step 2: Update Imports
Replace individual utility imports with namespace imports:
// OLD - Remove these
import { someUtility } from '@hydra-sdk/core/utils/some-utility'
import { CardanoWASM } from '@hydra-sdk/cardano-wasm'
// NEW - Use these instead
import {
ParserUtils,
TimeUtils,
DatumUtils,
PolicyUtils,
Serializer,
Deserializer,
Resolver,
Converter,
BuildKeys,
ProviderUtils,
CostModels
} from '@hydra-sdk/core'
Step 3: Replace Manual Operations
Data Conversion
// OLD
const hex = Buffer.from(bytes).toString('hex')
const bytes = Buffer.from(hex, 'hex')
// NEW
import { ParserUtils } from '@hydra-sdk/core'
const hex = ParserUtils.bytesToHex(bytes)
const bytes = ParserUtils.hexToBytes(hex)
Time Calculations
// OLD
const slot = Math.floor((Date.now() - SHELLEY_START) / SLOT_LENGTH) + SHELLEY_SLOT_START
// NEW
import { TimeUtils, SLOT_CONFIG_NETWORK } from '@hydra-sdk/core'
const slot = TimeUtils.unixTimeToEnclosingSlot(Date.now(), SLOT_CONFIG_NETWORK.PREPROD)
Datum Creation
// OLD - Complex WASM operations
import { CardanoWASM } from '@hydra-sdk/cardano-wasm'
const datum = CardanoWASM.PlutusData.new_constr_plutus_data(
CardanoWASM.ConstrPlutusData.new(
CardanoWASM.BigNum.from_str('0'),
list
)
)
// NEW - Simple utility functions
import { DatumUtils } from '@hydra-sdk/core'
const datum = DatumUtils.mkConstr(0, [field1, field2])
Step 4: Update Provider Usage
If you were using custom provider implementations:
// OLD - Custom provider setup
class MyProvider {
async getUtxos(address) {
// Custom implementation
}
}
// NEW - Use built-in providers or extend base
import { ProviderUtils } from '@hydra-sdk/core'
const provider = new ProviderUtils.BlockfrostProvider({
apiKey: 'your-blockfrost-api-key',
network: 'preprod'
})
// Or extend a built-in provider to customize behavior
class MyProvider extends ProviderUtils.BlockfrostProvider {
constructor() {
super({ apiKey: 'your-blockfrost-api-key', network: 'preprod' })
}
// Inherited `.fetcher` / `.submitter` still work
async getUtxos(address: string) {
return this.fetcher.fetchAddressUTxOs(address)
}
}
Common Migration Patterns
Pattern 1: Metadata Creation
Before:
const metadata = {
721: {
[policyId]: {
[tokenName]: {
name: Buffer.from(name).toString('hex'),
image: Buffer.from(image).toString('hex')
}
}
}
}
After:
import { ParserUtils, DatumUtils } from '@hydra-sdk/core'
const metadata = {
721: {
[policyId]: {
[tokenName]: {
name: ParserUtils.stringToHex(name),
image: ParserUtils.stringToHex(image)
}
}
}
}
// Or create as datum
const metadataDatum = DatumUtils.mkMap([
[DatumUtils.mkBytes(ParserUtils.stringToHex("name")),
DatumUtils.mkBytes(ParserUtils.stringToHex(name))],
[DatumUtils.mkBytes(ParserUtils.stringToHex("image")),
DatumUtils.mkBytes(ParserUtils.stringToHex(image))]
])
Pattern 2: Transaction Timing
Before:
// Manual slot calculation
const validFrom = getCurrentSlot()
const validUntil = validFrom + 7200 // 1 hour in slots
After:
import { TimeUtils, SLOT_CONFIG_NETWORK } from '@hydra-sdk/core'
const validFrom = TimeUtils.unixTimeToEnclosingSlot(Date.now(), SLOT_CONFIG_NETWORK.PREPROD)
const validUntil = TimeUtils.unixTimeToEnclosingSlot(Date.now() + 3600000, SLOT_CONFIG_NETWORK.PREPROD)
Pattern 3: Policy Script Creation
Before:
// Manual WASM operations for policy
import { CardanoWASM } from '@hydra-sdk/cardano-wasm'
const keyHash = CardanoWASM.Ed25519KeyHash.from_hex(publicKeyHash)
const scriptPubkey = CardanoWASM.ScriptPubkey.new(keyHash)
const policy = CardanoWASM.NativeScript.new_script_pubkey(scriptPubkey)
After:
import { PolicyUtils } from '@hydra-sdk/core'
const policy = PolicyUtils.buildPolicyScriptFromPubkey({
type: 'sig',
keyHash: publicKeyHash
})
// Or from address
const policy = PolicyUtils.buildMintingPolicyScriptFromAddress(address)
Testing Your Migration
1. Basic Functionality Test
import {
AppWallet,
NETWORK_ID,
ParserUtils,
TimeUtils,
DatumUtils
} from '@hydra-sdk/core'
// Test wallet creation (should work as before)
const wallet = new AppWallet({
networkId: NETWORK_ID.PREPROD,
key: { type: 'mnemonic', words: AppWallet.brew() }
})
// Test new utilities
const hex = ParserUtils.stringToHex('test')
const slot = TimeUtils.resolveSlotNo('preprod')
const datum = DatumUtils.mkInt(42)
console.log('Migration test passed:', {
address: wallet.getAccount(0, 0).baseAddressBech32,
hex,
slot,
datumHex: datum.to_hex()
})
2. Data Conversion Test
import { ParserUtils } from '@hydra-sdk/core'
const testData = [
'Hello World',
'🚀 Hydra SDK',
'Special chars: åøæ'
]
testData.forEach(str => {
const hex = ParserUtils.stringToHex(str)
const back = Buffer.from(hex, 'hex').toString('utf8')
console.assert(str === back, `Conversion failed for: ${str}`)
})
console.log('Data conversion tests passed')
3. Time Utilities Test
import { TimeUtils, SLOT_CONFIG_NETWORK } from '@hydra-sdk/core'
const networks = ['MAINNET', 'PREPROD', 'PREVIEW'] as const
networks.forEach(network => {
const slot = TimeUtils.unixTimeToEnclosingSlot(Date.now(), SLOT_CONFIG_NETWORK[network])
console.assert(typeof slot === 'number' && slot > 0, `Invalid slot for network: ${network}`)
})
console.log('Time utilities tests passed')
Troubleshooting
Common Issues
- Import Errors
Error: Module not found: @hydra-sdk/core/utils/...
Solution: Use namespace imports instead of deep imports. - Type Errors with Utilities
Error: Property 'stringToHex' does not exist on type...
Solution: Import the correct namespace:ParserUtils.stringToHex - Slot Calculation Issues
Error: Invalid network parameter
Solution: Use exact network strings:'mainnet','preprod', or'preview'
Getting Help
If you encounter issues during migration:
- Check the Utilities API Reference
- Review Working with Utilities Guide
- Look at Utilities Examples
- Join our community Discord for support
Benefits of v1.1.0
After migration, you'll enjoy:
- Better Developer Experience: Organized, predictable utility functions
- Type Safety: Comprehensive TypeScript definitions
- Performance: Optimized utility implementations
- Maintainability: Cleaner, more readable code
- Future-Proof: Foundation for upcoming features
The migration effort pays off with significantly improved development experience and code quality.
