npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ravenhouse/omni-sdk

v0.1.61

Published

Raven House Omni SDK

Readme

@ravenhouse/omni-sdk

TypeScript SDK for bridging tokens between Ethereum (L1) and Aztec (L2) with privacy-preserving features.

Full documentation: https://docs.ravenhouse.xyz/omni-sdk

Installation

bun add @ravenhouse/omni-sdk

Quick Start

import { RavenBridge, AzguardBrowserWalletClient } from '@ravenhouse/omni-sdk'
import { useBridgeL1ToL2 } from '@ravenhouse/omni-sdk/react'
import { DEVNET_CONFIG } from '@ravenhouse/omni-sdk/config'

// Create once outside component
const bridge = new RavenBridge({ network: DEVNET_CONFIG })

function BridgeComponent() {
  const { bridgeL1ToL2, isLoading, steps, result, error } = useBridgeL1ToL2(bridge)

  const handleBridge = async () => {
    // l1Wallet: wagmi wallet client (extended with publicActions)
    // wallet: Wallet from @aztec/aztec.js/wallet (provided by @aztec/wallet-sdk)
    const l2Wallet = new AzguardBrowserWalletClient(aztecWallet, aztecAddress)

    await bridgeL1ToL2({
      l1Wallet,
      l2Wallet,
      token: bridge.getToken('RHT')!,
      amount: '100',
      isPrivate: true,
    })
  }

  return (
    <div>
      <button onClick={handleBridge} disabled={isLoading}>Bridge</button>

      {steps.map((step) => (
        <div key={step.id}>
          {step.label}: {step.status}
          {step.txHash && <a href={step.explorerUrl}>View TX</a>}
        </div>
      ))}

      {error && <p>Error: {error.message}</p>}
      {result && <p>Done! {result.finalTxHash}</p>}
    </div>
  )
}

Bridge Flows

L1 → L2 (3 steps): Deposit to L1 portal → Sync (3 L2 blocks) → Claim on L2

L2 → L1 (3 steps): Burn on L2 + exit → Wait for block proof → Withdraw on L1

Both flows support isPrivate: true (shielded balance) and isPrivate: false (public balance).

Wallet Interfaces

L1 Wallet

Any Wagmi/Viem wallet client extended with publicActions:

const l1Wallet = walletClient.extend(publicActions) // from wagmi/actions + viem

The SDK expects { account: { address: string }, extend(actions): ... }.

L2 Wallet (AzguardBrowserWalletClient)

Wraps any Wallet from @aztec/aztec.js/wallet (provided by the Azguard extension via @aztec/wallet-sdk) and implements the SDK's L2WalletClient interface:

import { AzguardBrowserWalletClient } from '@ravenhouse/omni-sdk'

const l2Wallet = new AzguardBrowserWalletClient(
  wallet,       // Wallet from @aztec/aztec.js/wallet
  aztecAddress, // AztecAddress of the connected account
)

The adapter translates the SDK's internal operation protocol into direct Aztec.js contract calls:

| Operation | What the adapter does | |---|---| | claim_private | TokenBridge.claim_private(...).send() | | claim_public | TokenBridge.claim_public(...).send() | | exit_to_l1_public | BatchCall([SetPublicAuthwit, exit_to_l1_public]).send() | | exit_to_l1_private | wallet.createAuthWit(burn_private)exit_to_l1_private.send({ authWitnesses }) |

Custom L2 Wallet

If you have a different wallet, implement the L2WalletClient interface directly:

import type { L2WalletClient } from '@ravenhouse/omni-sdk'

const myL2Wallet: L2WalletClient = {
  account: '0x...',   // Aztec address string
  sessionId: 'my-session',
  request: async (method, params) => { /* handle execute operations */ },
}

API

RavenBridge

const bridge = new RavenBridge({ network: DEVNET_CONFIG })

bridge.bridgeL1ToL2({ l1Wallet, l2Wallet, token, amount, isPrivate, onStep? })
bridge.bridgeL2ToL1({ l1Wallet, l2Wallet, token, amount, isPrivate, onStep? })
bridge.getSupportedTokens()  // → TokenConfig[]
bridge.getToken('RHT')       // → TokenConfig | undefined

React Hooks

import { useBridgeL1ToL2, useBridgeL2ToL1 } from '@ravenhouse/omni-sdk/react'

const { bridgeL1ToL2, isLoading, steps, currentStep, result, error, reset } = useBridgeL1ToL2(bridge)
const { bridgeL2ToL1, isLoading, steps, currentStep, result, error, reset } = useBridgeL2ToL1(bridge)

All state is managed internally. steps updates in real-time as each bridge step progresses.

Checkpoint Callbacks

Both bridge methods accept optional callbacks that fire after critical mid-flow steps. Use these to persist recovery data in case the user closes the browser before the operation completes.

// L1 → L2: called after the L1 deposit succeeds (before the L2 claim)
await bridgeL1ToL2({
  ...params,
  onDepositComplete: async ({ claimSecret, messageLeafIndex }) => {
    await db.savePendingClaim({ claimSecret, messageLeafIndex })
  },
})

// L2 → L1: called after the L2 burn succeeds (before the L1 withdrawal)
await bridgeL2ToL1({
  ...params,
  onBurnComplete: async ({ txHash, blockNumber }) => {
    await db.savePendingWithdrawal({ l2TxHash: txHash, blockNumber })
  },
})

Errors thrown inside these callbacks are silently swallowed. The bridge continues regardless.

Types

interface BridgeStep {
  id: string
  label: string
  status: 'pending' | 'loading' | 'completed' | 'error'
  description?: string
  txHash?: string
  explorerUrl?: string
  error?: Error
}

interface BridgeResult {
  success: boolean
  direction: 'l1-to-l2' | 'l2-to-l1'
  amount: string
  symbol: string
  finalTxHash?: string
  message: string
  steps: BridgeStep[]
}

Configuration

import { DEVNET_CONFIG, DEVNET_TOKENS } from '@ravenhouse/omni-sdk/config'

DEVNET_CONFIG includes Aztec devnet endpoints, token addresses (portal, bridge), and block explorer URLs. Token configs follow the TokenConfig shape with l1 and l2 address sections.

Browser Setup (Next.js)

Add to next.config.js:

const webpack = require('webpack')

const nextConfig = {
  webpack: (config, { isServer }) => {
    if (!isServer) {
      config.resolve.fallback = {
        ...config.resolve.fallback,
        fs: false, 'fs/promises': false, net: false, tls: false, tty: false,
        os: require.resolve('os-browserify/browser'),
        crypto: require.resolve('crypto-browserify'),
        stream: require.resolve('stream-browserify'),
        buffer: require.resolve('buffer/'),
        process: require.resolve('process/browser'),
        util: require.resolve('util/'),
        path: require.resolve('path-browserify'),
      }
      config.plugins.push(
        new webpack.ProvidePlugin({ Buffer: ['buffer', 'Buffer'], process: 'process/browser' })
      )
      config.resolve.alias = { ...config.resolve.alias, pino: 'pino/browser.js' }
    }
    return config
  },
}
module.exports = nextConfig

Submodule Exports

| Import path | Contents | |---|---| | @ravenhouse/omni-sdk | RavenBridge, AzguardBrowserWalletClient, all types | | @ravenhouse/omni-sdk/react | useBridgeL1ToL2, useBridgeL2ToL1 | | @ravenhouse/omni-sdk/config | DEVNET_CONFIG, DEVNET_TOKENS | | @ravenhouse/omni-sdk/contracts/l2 | TokenBridgeContract, TokenContract | | @ravenhouse/omni-sdk/ethereum | L1TokenPortalManager, PortalManager | | @ravenhouse/omni-sdk/vite | Vite plugin for browser polyfills |

Troubleshooting

Sync step is slow. Normal. The SDK waits for 3 L2 blocks (~30-90s on devnet).

Proof step is slow (L2->L1). Normal. Block proving takes 5-15 minutes on devnet.

TypeScript: "separate declarations of private property 'config'". Happens when RavenBridge is created in the same file that imports from @ravenhouse/omni-sdk/react. The tsup build inlines class declarations in each entry point. Fix: cast bridge as any when passing to useBridgeL1ToL2(bridge as any).


MIT © Cyphronix Software

Internal Team understanding

  • What is ISignatureTransfer ?
  • We need to figure out the aztec Fee Juice portal address for sepolia and for mainnet. Testnet: 0xd3361019e40026ce8a9745c19e67fd3acc10d596 Mainnet: 0x2891f8b941067f8b5a3f34545a30cf71e3e23617

Fee Juice(Aztec token): Testnet: 0x762c132040fda6183066fa3b14d985ee55aa3c18 Mainnet: 0xa27ec0006e59f245217ff08cd52a7e8b169e62d2

Permit2 Sepolia address: 0x000000000022D473030F116dDEE9F6B43aC78BA3