@hydra-sdk/bridge

The bridge package provides complete Hydra Layer 2 integration with real-time event handling, Head lifecycle management, and transaction processing.

Installation

bash
npm install @hydra-sdk/bridge

Key Classes

HydraBridge

Main class for connecting to and managing Hydra Heads.

Constructor

typescript
import { HydraBridge } from '@hydra-sdk/bridge'

// Direct WebSocket connection
const bridge = new HydraBridge({
  url: 'ws://localhost:4001',
  verbose: true
})

// Using custom connector
const bridge = new HydraBridge({
  connector: customConnector,
  verbose: true
})

Connection Management

connect() Connect to the Hydra Node:

typescript
bridge.connect()

disconnect() Disconnect from the Hydra Node:

typescript
bridge.disconnect()

connected() Check connection status:

typescript
const isConnected = bridge.connected()
console.log('Connected:', isConnected)

Head Information

headInfo() Get current head information:

typescript
const info = await bridge.headInfo()
console.log({
  headId: info.headId,
  headStatus: info.headStatus,
  vkey: info.vkey
})

Protocol Parameters

getProtocolParameters() Get Cardano protocol parameters:

typescript
const protocolParams = await bridge.getProtocolParameters()
console.log('Protocol Parameters:', protocolParams)

UTxO Management

querySnapshotUtxo() Query current snapshot UTxOs:

typescript
const utxoObject = await bridge.querySnapshotUtxo()
console.log('Snapshot UTxO:', utxoObject)

snapshotUtxoArray() Get UTxO array from snapshot:

typescript
const utxoArray = bridge.snapshotUtxoArray()
console.log('UTxO Array:', utxoArray)

queryAddressUTxO(address) Query UTxOs for specific address:

typescript
const addressUtxos = await bridge.queryAddressUTxO('addr_test1...')
console.log('Address UTxOs:', addressUtxos)

addressesInHead() Get all addresses in current head:

typescript
const addresses = await bridge.addressesInHead()
console.log('Addresses in Head:', addresses)

Transaction Operations

submitTxSync(transaction, options) Submit transaction and wait for confirmation:

typescript
const result = await bridge.submitTxSync({
  type: 'Witnessed Tx ConwayEra',
  description: 'Ledger Cddl Format',
  cborHex: signedTxCbor,
  txId: transactionId
}, { timeout: 30000 })

console.log('Transaction result:', result)

commit(data) Commit UTxOs to head:

typescript
const result = await bridge.commit({
  cborHex: commitTxCbor,
  description: 'Commit transaction'
})

submitCardanoTransaction(data) Submit transaction to Cardano network:

typescript
const result = await bridge.submitCardanoTransaction({
  cborHex: txCbor,
  description: 'Cardano transaction'
})

Event Handling

The bridge provides comprehensive event handling:

typescript
// Connection events
bridge.events.on('onConnected', () => {
  console.log('Connected to Hydra Node')
})

bridge.events.on('onDisconnected', () => {
  console.log('Disconnected from Hydra Node')
})

bridge.events.on('onConnectError', (error) => {
  console.error('Connection error:', error)
})

// Head lifecycle events
bridge.events.on('onMessage', (payload) => {
  console.log('Received message:', payload)
  
  switch (payload.tag) {
    case 'HeadIsInitializing':
      console.log('Head initializing with parties:', payload.parties)
      break
    case 'HeadIsOpen':
      console.log('Head is open:', payload.utxo)
      break
    case 'HeadIsClosed':
      console.log('Head closed:', payload.utxo)
      break
    case 'TxValid':
      console.log('Transaction valid:', payload.transaction)
      break
    case 'TxInvalid':
      console.log('Transaction invalid:', payload.transaction, payload.validationError)
      break
    case 'SnapshotConfirmed':
      console.log('Snapshot confirmed:', payload.snapshot)
      break
  }
})

Commands

Execute Hydra Head commands through the commands object:

commands.init() Initialize a new Hydra Head:

typescript
bridge.commands.init()

commands.close() Close the Hydra Head:

typescript
bridge.commands.close()

commands.abort() Abort Head initialization:

typescript
bridge.commands.abort()

commands.fanout() Execute fanout after Head closure:

typescript
bridge.commands.fanout()

commands.contest() Contest a Head closure:

typescript
bridge.commands.contest()

commands.recover(recoverTxId) Recover from a specific transaction:

typescript
bridge.commands.recover('tx_hash_here')

commands.newTx(cborHex, description, callback) Submit a new transaction to the Head:

typescript
bridge.commands.newTx(
  signedTxCbor,
  'Payment transaction',
  () => console.log('Transaction sent')
)

commands.decommit(payload) Decommit UTxOs from head:

typescript
const result = await bridge.commands.decommit({
  cborHex: decommitTxCbor,
  txId: transactionId,
  timeout: 30000
})

commands.initSync(retry, interval) Initialize head with retry logic:

typescript
const result = await bridge.commands.initSync(3, 20000)
console.log('Head initialized:', result)

HexcoreConnector

Advanced connector for Hexcore API integration with Socket.IO.

Constructor

typescript
import { HexcoreConnector } from '@hydra-sdk/bridge'

const connector = new HexcoreConnector(
  'https://game-api.hexcore.dev',
  {
    socketIoOptions: {
      auth: {
        token: 'your_jwt_token'
      },
      transports: ['websocket'],
      timeout: 20000
    }
  }
)

Usage with HydraBridge

typescript
import { HydraBridge, HexcoreConnector } from '@hydra-sdk/bridge'

const bridge = new HydraBridge({
  connector: new HexcoreConnector('https://game-api.hexcore.dev', {
    socketIoOptions: {}
  })
})

bridge.connect()

Advanced Hexcore Integration

typescript
import { HydraBridge, HexcoreConnector } from '@hydra-sdk/bridge'
import { AppWallet } from '@hydra-sdk/core'
import { CardanoWASM } from '@hydra-sdk/cardano-wasm'

async function connectToHexcore() {
  const connector = new HexcoreConnector('https://game-api.hexcore.dev', {
    socketIoOptions: {
      auth: {
        token: 'your_jwt_token'
      },
      timeout: 20000
    }
  })

  const bridge = new HydraBridge({
    connector: connector,
    verbose: true
  })

  bridge.events.on('onConnected', () => {
    console.log('Connected to Hexcore API')
  })

  bridge.events.on('onError', (error) => {
    console.error('Hexcore error:', error)
  })

  await bridge.connect()

  // Query UTxOs and inspect inline datums
  const utxos = await bridge.queryAddressUTxO('addr_test1qqgagp6hm64jsxphelk494rpwysrkk8gzlhn8cnaueqqsqmfksxjux7q5ulgtfe9f40zt2sz0w4rw9t06kft8qa0w2cqxzut0c')
  
  utxos.forEach(utxo => {
    console.log('UTxO:', utxo)
    
    // Check for inline datums
    if (utxo.output.inlineDatum) {
      console.log('Inline Datum (Basic):', 
        utxo.output.inlineDatum.to_json(CardanoWASM.PlutusDatumSchema.BasicConversions)
      )
      console.log('Inline Datum (Detailed):', 
        utxo.output.inlineDatum.to_json(CardanoWASM.PlutusDatumSchema.DetailedSchema)
      )
    }
  })
}

Vue.js Integration Example

vue
<script lang="ts" setup>
import { AppWallet, deserializeTx, NETWORK_ID } from '@hydra-sdk/core'
import { HydraBridge, HexcoreConnector } from '@hydra-sdk/bridge'
import { TxBuilder } from '@hydra-sdk/transaction'
import { CardanoWASM } from '@hydra-sdk/cardano-wasm'

const hydraBridge = ref<HydraBridge | null>(null)
const { walletConfig } = useWalletConfig()

onMounted(async () => {
  hydraBridge.value = new HydraBridge({
    connector: new HexcoreConnector('https://game-api.hexcore.dev', {
      socketIoOptions: {}
    })
  })
  
  hydraBridge.value.connect()
  
  hydraBridge.value.events.on('onConnected', () => {
    console.log('Hydra Bridge connected to Hexcore')
  })
})

onBeforeUnmount(() => {
  if (hydraBridge.value) {
    hydraBridge.value.disconnect()
  }
})

async function queryUTxOs() {
  if (!walletConfig.value.mnemonic) {
    console.error('Wallet configuration is not set.')
    return
  }

  const wallet = new AppWallet({
    key: {
      type: 'mnemonic',
      words: walletConfig.value.mnemonic.split(' ')
    },
    networkId: walletConfig.value.network
  })
  
  const account = wallet.getAccount(0, 0)

  const utxos = await hydraBridge.value!.queryAddressUTxO(account.baseAddressBech32)
  
  utxos.forEach(utxo => {
    console.log('UTxO:', utxo)
    if (utxo.output.inlineDatum) {
      console.log('Inline Datum:', 
        utxo.output.inlineDatum.to_json(CardanoWASM.PlutusDatumSchema.BasicConversions)
      )
    }
  })
}
</script>

<template>
  <div>
    <h3>Hydra Bridge with Hexcore</h3>
    <button @click="queryUTxOs">Query UTxOs</button>
  </div>
</template>