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

@tuwaio/quasar-sdk

v0.1.3

Published

Layer 5 (L5) of the TUWA Ecosystem. The Quasar Cloud SDK providing server-side Node.js & Edge utilities for transaction indexing, billing, and backend API integration.

Readme

@tuwaio/quasar-sdk

NPM Version License

The official Layer 5 (L5) server-side Node.js & Edge SDK for the TUWA Quasar Cloud.


🏛️ What is @tuwaio/quasar-sdk?

@tuwaio/quasar-sdk is Layer 5 (L5) of the TUWA ecosystem architecture — the official backend companion to the TUWA client libraries. It serves as the gateway to the Quasar Cloud Engine, allowing your server to securely push transaction logs, query paginated transaction histories, and sync infrastructure states.

It operates strictly on the server (Node.js, Next.js Server Actions, or Edge functions) and uses Secret Keys to communicate with Quasar's iron-dome guarded endpoints.


✨ Key Features

  • ☁️ Cloud Sync: Automatically persist pending and terminal transaction states to the Quasar Database for cross-device history.
  • 🔐 Headless SIWX (CAIP-122) Auth Ready: Seamlessly pairs with @tuwaio/sdk/siwx/server for strict cryptographic verification of user sessions before allowing database writes.
  • ⚡ Edge Ready: Uses ofetch and lightweight cryptography to run seamlessly in Cloudflare Workers and Vercel Edge.
  • 📦 InMemory Sync: Perfectly pairs with @tuwaio/sdk/pulsar (createTxInMemoryStore) to fetch history and hydrate local React states.

💾 Installation

pnpm add @tuwaio/quasar-sdk ofetch @tuwaio/pulsar-core @tuwaio/siwx-core @tuwaio/siwx-server @tuwaio/siwx-react

Note: ofetch and @tuwaio/pulsar-core are required peer dependencies. The @tuwaio/siwx-* packages are required if you intend to use the headless SIWX (CAIP-122) authentication integrations.


🚀 Quick Start (Node.js / Edge)

This is a basic example of how to interact with the Quasar Cloud directly from your secure backend environments (like Next.js API Routes, Server Actions, or NestJS).

import { Quasar, type Transaction } from '@tuwaio/quasar-sdk';
import { verifySiwxPayload, type SiwxSession } from '@tuwaio/sdk/siwx/server';

// Initialize Quasar with your Secret Key from the Dashboard
const quasar = new Quasar({ secretKey: process.env.QUASAR_SDK_SK ?? '' });

/**
 * Example Next.js Server Action to Sync a Transaction
 */
export async function syncTransaction(tx: Transaction, sessionData: SiwxSession) {
  // 1. Verify the client's signature (prevent unauthorized spoofing)
  const isValid = await verifySiwxPayload(sessionData);
  if (!isValid) throw new Error('Invalid signature.');

  // 2. Sync the transaction securely to the Quasar Cloud
  await quasar.pulsar.syncCreate(tx, 'My Application');
  return { success: true };
}

/**
 * Example Next.js Server Action to Fetch History
 */
export async function getHistory(
  params: { walletAddress: string; page: number; limit: number; appName: string },
  sessionData: SiwxSession,
) {
  const isValid = await verifySiwxPayload(sessionData);
  if (!isValid) throw new Error('Invalid signature.');

  // Return the paginated transaction history
  return quasar.pulsar.getHistory(params);
}

🔐 Frontend Authentication (SIWX)

The Quasar SDK relies on the standard SIWX (CAIP-122) protocol for authenticating requests.

You should use the headless useSatelliteSiwxAutoAuth hook provided by @tuwaio/sdk/siwx on your frontend. This hook automatically prompts users to sign a CAIP-122 message when they connect their wallet, and establishes a secure session with your backend.

For detailed frontend integration, see the SIWX Documentation.


🌍 The Full Flow (Production Architecture)

To see how incredibly powerful @tuwaio/quasar-sdk is when combined with @tuwaio/sdk, here is a complete architectural overview without any skipped steps. Notice how the Pulsar Store and Headless SIWX dance together effortlessly:

1. Define Your Transaction Types (types.ts)

First, define the strict union of all possible transactions your app supports.

// src/types.ts
import type { Transaction } from '@tuwaio/sdk/pulsar';

export enum AppTxType {
  SWAP = 'SWAP',
}

export type SwapTx = Transaction & {
  type: AppTxType.SWAP;
  payload: { tokenIn: string; tokenOut: string; amount: number };
};

export type TransactionUnion = SwapTx;

2. Secure Server Proxy (actions.ts)

Proxy calls to Quasar Cloud using your backend to protect secret keys.

// src/app/actions.ts
'use server';

import { Quasar } from '@tuwaio/quasar-sdk';
import { verifySiwxPayload, type SiwxSession } from '@tuwaio/sdk/siwx/server';
import { TransactionUnion } from '@/types';

const quasar = new Quasar({ secretKey: process.env.QUASAR_SDK_SK ?? '' });

export async function syncTransaction(tx: TransactionUnion, sessionData: SiwxSession) {
  const isValid = await verifySiwxPayload(sessionData);
  if (!isValid) throw new Error('Invalid signature.');

  await quasar.pulsar.syncCreate(tx, 'My App');
  return { success: true };
}

export async function getHistory(params: any, sessionData: SiwxSession) {
  const isValid = await verifySiwxPayload(sessionData);
  if (!isValid) throw new Error('Invalid signature.');

  return quasar.pulsar.getHistory(params);
}
// src/hooks/usePulsarStore.ts
'use client';

import { createPulsarStore, createTxInMemoryStore, createBoundedUseStore } from '@tuwaio/sdk/pulsar';
import { pulsarEvmAdapter } from '@tuwaio/evm-sdk/pulsar';
import { pulsarSolanaAdapter } from '@tuwaio/solana-sdk/pulsar';
import { useSiwxSessionStore } from '@tuwaio/sdk/siwx';
import { preFlightTxCheck } from '@tuwaio/quasar-sdk';

import { getHistory, syncTransaction } from '@/app/actions';
import { wagmiConfig, appEVMChains, solanaRPCUrls } from '@/configs/appConfig';
import { TransactionUnion } from '@/types';

const storageName = 'transactions-tracking-storage';

const initialStore = createPulsarStore<TransactionUnion>({
  name: storageName,
  adapter: [pulsarEvmAdapter(wagmiConfig, appEVMChains), pulsarSolanaAdapter({ rpcUrls: solanaRPCUrls })],
  beforeTxProcess: async () => {
    // Ensures we have a valid SIWX session and Quasar Cloud is reachable before executing blockchain logic
    await preFlightTxCheck();
  },
  onRemoteCreate: async (tx) => {
    try {
      // Syncs the new transaction to Quasar via Next.js Server Actions
      const session = useSiwxSessionStore.getState().session;
      if (session) {
        await syncTransaction(tx as TransactionUnion, session);
      }
    } catch (err) {
      console.error('[PulsarHook] Remote sync failed:', err);
    }
  },
});

export const usePulsarStore = createBoundedUseStore(initialStore);

// Wrap with inMemoryStore to enable remote history fetching & pagination
const pulsarInMemoryStore = createTxInMemoryStore<TransactionUnion>({
  localTransactionsPool: initialStore.getState().transactionsPool,
  getHistory: async ({ page, walletAddress }) => {
    try {
      const session = useSiwxSessionStore.getState().session;
      if (!session) return null;

      const history = await getHistory({ walletAddress, page, limit: 10, appName: 'My App' }, session);

      if (!history) return null;

      return { ...history, docs: history.docs as TransactionUnion[] };
    } catch (error) {
      console.error('[PulsarHook] Failed to fetch history:', error);
      throw error;
    }
  },
  onHistoryFetched: async (remoteTxs) => {
    await initialStore.getState().injectExternalPendingTxs(remoteTxs);
  },
});

initialStore.subscribe((state) => pulsarInMemoryStore.getState().syncWithLocalPool(state.transactionsPool));

export const usePulsarInMemoryStore = createBoundedUseStore(pulsarInMemoryStore);

4. Nova Transactions Provider (NovaTransactionsProvider.tsx)

// src/providers/NovaTransactionsProvider.tsx
'use client';

import { useSatelliteConnectStore } from '@tuwaio/sdk/satellite';
import { useInitializeTransactionsPool, type TxInMemoryPagination } from '@tuwaio/sdk/pulsar';
import { getAdapterFromConnectorType } from '@tuwaio/sdk/orbit';
import { NovaTransactionsProvider as NTP } from '@tuwaio/sdk/nova-transactions/providers';
import { usePulsarInMemoryStore, usePulsarStore } from '@/hooks/usePulsarStore';

export function NovaTransactionsProvider({ pagination }: { pagination: TxInMemoryPagination }) {
  const initialTx = usePulsarStore((state) => state.initialTx);
  const closeTxTrackedModal = usePulsarStore((state) => state.closeTxTrackedModal);
  const executeTxAction = usePulsarStore((state) => state.executeTxAction);
  const initializeTransactionsPool = usePulsarStore((state) => state.initializeTransactionsPool);

  const activeConnection = useSatelliteConnectStore((state) => state.activeConnection);
  const getAdapter = usePulsarStore((state) => state.getAdapter);
  const transactionsPool = usePulsarInMemoryStore((state) => state.transactionsPool);

  useInitializeTransactionsPool({ initializeTransactionsPool });

  return (
    <NTP
      transactionsPool={transactionsPool}
      initialTx={initialTx}
      closeTxTrackedModal={closeTxTrackedModal}
      executeTxAction={executeTxAction}
      connectedWalletAddress={activeConnection?.isConnected ? activeConnection.address : undefined}
      connectedAdapterType={getAdapterFromConnectorType(activeConnection?.connectorType ?? 'evm:')}
      adapter={getAdapter()}
      pagination={pagination}
    />
  );
}

5. The Seamless UI Integration (AppProviders.tsx)

// src/providers/AppProviders.tsx
'use client';

import { SatelliteConnectProvider, useSatelliteConnection } from '@tuwaio/sdk/satellite';
import { NovaConnectProvider } from '@tuwaio/sdk/nova-connect';
import { satelliteEVMAdapter } from '@tuwaio/evm-sdk/satellite';
import { EVMConnectorsWatcher } from '@tuwaio/evm-sdk/nova-connect';
import { satelliteSolanaAdapter } from '@tuwaio/solana-sdk/satellite';
import { SolanaConnectorsWatcher } from '@tuwaio/solana-sdk/nova-connect';
import { useSiwx, useSiwxSession } from '@tuwaio/sdk/siwx';
import { isSafeApp, getAdapterFromConnectorType, OrbitAdapter } from '@tuwaio/sdk/orbit';

import { appEVMChains, solanaRPCUrls, wagmiConfig } from '@/configs/appConfig';
import { usePulsarInMemoryStore, usePulsarStore } from '@/hooks/usePulsarStore';
import { NovaTransactionsProvider } from '@/providers/NovaTransactionsProvider';

export function AppProviders({ children }: { children: React.ReactNode }) {
  const getAdapter = usePulsarStore((state) => state.getAdapter);
  const transactionsPool = usePulsarInMemoryStore((state) => state.transactionsPool);

  const isLoading = usePulsarInMemoryStore((state) => state.isLoading);
  const isError = usePulsarInMemoryStore((state) => state.isError);
  const currentPage = usePulsarInMemoryStore((state) => state.currentPage);
  const hasMore = usePulsarInMemoryStore((state) => state.hasMore);
  const fetchNextPage = usePulsarInMemoryStore((state) => state.fetchNextPage);
  const fetchInitial = usePulsarInMemoryStore((state) => state.fetchInitial);

  const pagination = { isLoading, isError, currentPage, hasMore, fetchNextPage };

  // Watch SIWX session to keep connection state aligned
  const siwxSession = useSiwxSession();
  const { signIn } = useSiwx();

  return (
    <SatelliteConnectProvider
      adapter={[satelliteEVMAdapter(wagmiConfig, appEVMChains), satelliteSolanaAdapter({ rpcUrls: solanaRPCUrls })]}
      autoConnect={true}
      callbackAfterConnected={async (connection) => {
        const isEVM = getAdapterFromConnectorType(connection.connectorType) === OrbitAdapter.EVM;
        if (isEVM && isSafeApp) return;

        // Trigger SIWX flow
        await signIn();

        // Fetch history slightly after connection and sign-in
        setTimeout(() => fetchInitial(connection.address), 2000);
      }}
    >
      <EVMConnectorsWatcher wagmiConfig={wagmiConfig} siwx={siwxSession} />
      <SolanaConnectorsWatcher siwx={siwxSession} />

      <NovaTransactionsProvider pagination={pagination} />

      <NovaConnectProvider
        appChains={appEVMChains}
        solanaRPCUrls={solanaRPCUrls}
        transactionPool={transactionsPool}
        pulsarAdapter={getAdapter()}
        withImpersonated
        withBalance
        withChain
        pagination={pagination}
      >
        {children}
      </NovaConnectProvider>
    </SatelliteConnectProvider>
  );
}

6. Creating a Transaction (Usage)

Now you can safely execute strictly-typed, cross-chain transactions anywhere in your app. The store automatically routes the transaction to the correct adapter, and Quasar syncs it to the cloud.

// src/components/SwapButton.tsx
'use client';

import { getAdapterFromConnectorType, OrbitAdapter } from '@tuwaio/sdk/orbit';
import { useSatelliteConnectStore } from '@tuwaio/sdk/satellite';
import { TxActionButton } from '@tuwaio/sdk/nova-transactions';
import { usePulsarStore, usePulsarInMemoryStore } from '@/hooks/usePulsarStore';
import { AppTxType } from '@/types';

export function SwapButton() {
  const executeTxAction = usePulsarStore((s) => s.executeTxAction);
  const getLastTxKey = usePulsarStore((s) => s.getLastTxKey);
  const transactionsPool = usePulsarInMemoryStore((s) => s.transactionsPool);
  const activeConnection = useSatelliteConnectStore((s) => s.activeConnection);

  const handleSwapAction = async () => {
    // Dynamically determine the adapter based on the currently connected wallet
    const adapterType = getAdapterFromConnectorType(activeConnection?.connectorType ?? 'evm:');

    await executeTxAction({
      actionFunction: async () => {
        /* your wagmi/solana contract call */
      },
      params: {
        adapter: adapterType,
        type: AppTxType.SWAP,
        title: 'Token Swap',
        desiredChainID: adapterType === OrbitAdapter.EVM ? 1 : undefined,
        payload: { tokenIn: 'USDC', tokenOut: adapterType === OrbitAdapter.EVM ? 'ETH' : 'SOL', amount: 100 },
      },
    });
  };

  return (
    <TxActionButton
      action={handleSwapAction}
      getLastTxKey={getLastTxKey}
      transactionsPool={transactionsPool}
      walletAddress={activeConnection?.address}
    >
      Cross-Chain Swap
    </TxActionButton>
  );
}

📦 Available Namespaces

This package provides the following server-side utilities and React helpers:

  • Quasar — The main server-side client class instance used to access quasar.pulsar.* methods.
  • preFlightTxCheck — A client-side helper to ensure the user has a valid SIWX session and Quasar Cloud is reachable before prompting wallet signatures.

🤝 Contributing & Support

Contributions are welcome! Please read our main Contribution Guidelines.

If you find this library useful, please consider supporting its development. Every contribution helps!

➡️ View Support Options

📄 License

This project is licensed under the Apache-2.0 License - see the LICENSE file for details.