Catalog npm
Back to packageRELEASE DETAILS

1.2.0-pre.93

npm

@0xobelisk/react

React integration for Dubhe framework with Sui blockchain support

blockchaindubhereactsuiweb3
Published30 Nov 2025
Direct dependencies20
Transitive dependenciesNot calculated

README

Current package documentation

@0xobelisk/react

Modern React integration for Dubhe framework with Provider pattern and multi-chain support.

🚀 Features

  • 🎯 Provider Pattern - Single initialization with React Context sharing
  • ⚡ Performance Optimized - useRef pattern prevents re-initialization
  • 🛡️ Type Safety - Complete TypeScript support with strict typing
  • 🌐 Multi-Chain Ready - Extensible architecture for multiple blockchains
  • 📦 Individual Hooks - Granular access to specific functionality
  • 🔧 Configuration Driven - Flexible setup with smart defaults

📦 Installation

# Core React package
npm install @0xobelisk/react

# Peer dependencies
npm install react react-dom @0xobelisk/sui-client zod

# Optional dependencies for enhanced features
npm install @0xobelisk/graphql-client @0xobelisk/ecs

Requirements

  • React: 18.0.0+ or 19.0.0+
  • Node.js: 18.0.0+
  • TypeScript: 5.0+ (recommended)

🌐 Multi-Chain Support

BlockchainStatusImport Path
Sui✅ Ready@0xobelisk/react/sui
Aptos🚧 Coming Soon@0xobelisk/react/aptos
Initia🚧 Coming Soon@0xobelisk/react/initia

🚀 Quick Start

Basic Provider Setup

import React from 'react';
import { DubheProvider, useDubhe } from '@0xobelisk/react/sui';
import { Transaction } from '@0xobelisk/sui-client';
import metadata from './contracts/metadata.json';

// App root with Provider
function App() {
  const config = {
    network: 'devnet' as const,
    packageId: process.env.NEXT_PUBLIC_PACKAGE_ID!,
    metadata,
    credentials: {
      secretKey: process.env.NEXT_PUBLIC_PRIVATE_KEY // ⚠️ LOCAL DEVELOPMENT ONLY  // ⚠️ LOCAL DEVELOPMENT ONLY
    }
  };

  return (
    <DubheProvider config={config}>
      <MyDApp />
    </DubheProvider>
  );
}

// Component using shared clients
function MyDApp() {
  const { contract, address, network } = useDubhe();

  const handleTransaction = async () => {
    try {
      const tx = new Transaction();
      const result = await contract.tx.counter_system.increment({ tx });
      console.log('Success:', result.digest);
    } catch (error) {
      console.error('Transaction failed:', error);
    }
  };

  return (
    <div>
      <p>Connected: {address}</p>
      <p>Network: {network}</p>
      <button onClick={handleTransaction}>Execute Transaction</button>
    </div>
  );
}

🎯 Provider Pattern

DubheProvider Component

The DubheProvider uses React Context with useRef pattern to ensure single client initialization:

import { DubheProvider } from '@0xobelisk/react/sui';
import type { DubheConfig } from '@0xobelisk/react/sui';

function App() {
  const config: DubheConfig = {
    network: 'devnet',
    packageId: '0x123...',
    metadata: contractMetadata,
    // Optional features
    dubheSchemaId: '0xabc...', // Optional: Dubhe Schema ID
    dubheMetadata: dubheConfigMetadata, // Enables GraphQL + ECS
    credentials: {
      secretKey: process.env.NEXT_PUBLIC_PRIVATE_KEY // ⚠️ LOCAL DEVELOPMENT ONLY  // ⚠️ LOCAL DEVELOPMENT ONLY
    },
    endpoints: {
      fullnodeUrls: ['https://fullnode.devnet.sui.io:443'], // Optional: Custom RPC endpoints
      graphql: process.env.NEXT_PUBLIC_GRAPHQL_URL,
      websocket: process.env.NEXT_PUBLIC_GRAPHQL_WS_URL,
      grpc: 'http://localhost:8080' // Optional: Custom gRPC endpoint
    },
    options: {
      enableBatchOptimization: true,
      cacheTimeout: 5000,
      debounceMs: 100,
      reconnectOnError: true
    }
  };

  return (
    <DubheProvider config={config}>
      <YourApp />
    </DubheProvider>
  );
}

Key Benefits of Provider Pattern

  • Single Initialization: Clients created once using useRef
  • Context Sharing: All components access same instances
  • No Re-renders: useRef prevents unnecessary re-initialization
  • Type Safety: Full TypeScript support across the tree

🪝 Hook Usage

Primary Hook: useDubhe()

Access all Dubhe features in one hook:

import { useDubhe } from '@0xobelisk/react/sui';

function MyComponent() {
  const {
    contract, // Dubhe contract instance
    graphqlClient, // GraphQL client (if dubheMetadata provided)
    ecsWorld, // ECS World (if GraphQL available)
    address, // User address
    network, // Current network
    packageId, // Contract package ID
    metadata // Contract metadata
  } = useDubhe();

  return (
    <div>
      <p>Contract: {contract ? '✅' : '❌'}</p>
      <p>GraphQL: {graphqlClient ? '✅' : '❌'}</p>
      <p>ECS: {ecsWorld ? '✅' : '❌'}</p>
    </div>
  );
}

Individual Hooks

For components that only need specific functionality:

import React, { useEffect } from 'react';
import { useDubheContract, useDubheGraphQL, useDubheECS } from '@0xobelisk/react/sui';
import { Transaction } from '@0xobelisk/sui-client';

// Contract-only component
function TransactionComponent() {
  const contract = useDubheContract();

  const executeTransaction = async () => {
    const tx = new Transaction();
    await contract.tx.my_system.my_method({ tx });
  };

  return <button onClick={executeTransaction}>Execute</button>;
}

// GraphQL-only component
function DataComponent() {
  const graphqlClient = useDubheGraphQL();

  useEffect(() => {
    if (graphqlClient) {
      graphqlClient.query({ query: '{ entities { id } }' }).then((result) => console.log(result));
    }
  }, [graphqlClient]);

  return <div>Data component</div>;
}

// ECS-only component
function ECSComponent() {
  const ecsWorld = useDubheECS();

  useEffect(() => {
    if (ecsWorld) {
      ecsWorld.getComponent('MyComponent').then((components) => console.log(components));
    }
  }, [ecsWorld]);

  return <div>ECS component</div>;
}

⚙️ Configuration Reference

DubheConfig Interface

interface DubheConfig {
  /** Network type */
  network: 'mainnet' | 'testnet' | 'devnet' | 'localnet';

  /** Contract package ID */
  packageId: string;

  /** Contract metadata (required for contract instantiation) */
  metadata: SuiMoveNormalizedModules;

  /** Dubhe Schema ID (optional, for enhanced features) */
  dubheSchemaId?: string;

  /** Dubhe metadata (enables GraphQL/ECS features) */
  dubheMetadata?: any;

  /** Authentication credentials */
  credentials?: {
    secretKey?: string; // ⚠️ LOCAL DEVELOPMENT ONLY - see security warning below
    mnemonics?: string; // ⚠️ LOCAL DEVELOPMENT ONLY - see security warning below
  };

  /** Service endpoints configuration */
  endpoints?: {
    graphql?: string; // Default: 'http://localhost:4000/graphql'
    websocket?: string; // Default: 'ws://localhost:4000/graphql'
  };

  /** Performance and behavior options */
  options?: {
    enableBatchOptimization?: boolean; // Default: true
    cacheTimeout?: number; // Default: 5000ms
    debounceMs?: number; // Default: 100ms
    reconnectOnError?: boolean; // Default: true
  };
}

Environment Variable Configuration

// .env.local
NEXT_PUBLIC_NETWORK=devnet
NEXT_PUBLIC_PACKAGE_ID=0x123...
NEXT_PUBLIC_PRIVATE_KEY=suiprivkey...
NEXT_PUBLIC_GRAPHQL_URL=http://localhost:4000/graphql
NEXT_PUBLIC_GRAPHQL_WS_URL=ws://localhost:4000/graphql

// App configuration
function App() {
  const config = {
    network: process.env.NEXT_PUBLIC_NETWORK as NetworkType,
    packageId: process.env.NEXT_PUBLIC_PACKAGE_ID!,
    metadata: contractMetadata,
    credentials: {
      secretKey: process.env.NEXT_PUBLIC_PRIVATE_KEY  // ⚠️ LOCAL DEVELOPMENT ONLY  // ⚠️ LOCAL DEVELOPMENT ONLY
    },
    endpoints: {
      graphql: process.env.NEXT_PUBLIC_GRAPHQL_URL,
      websocket: process.env.NEXT_PUBLIC_GRAPHQL_WS_URL
    }
  };

  return (
    <DubheProvider config={config}>
      <MyApp />
    </DubheProvider>
  );
}

🔐 Security Warning

⚠️ IMPORTANT SECURITY NOTICE

secretKey and mnemonics are for LOCAL DEVELOPMENT ONLY!

  • ❌ NEVER use secretKey/mnemonics in production
  • ❌ NEVER commit private keys to version control
  • ❌ NEVER expose private keys in client-side code

For production applications:

  • ✅ Use official wallet providers for transaction signing
  • ✅ Implement proper wallet integration (Sui Wallet, etc.)
  • ✅ Let users connect their own wallets securely

Proper wallet integration example:

// For production - use wallet providers instead of secretKey
const config = {
  network: 'mainnet',
  packageId: process.env.NEXT_PUBLIC_PACKAGE_ID!,
  metadata
  // ✅ NO credentials - let wallet handle signing
};

Keep your private keys safe! If compromised, attackers can steal all funds.

📚 Practical Examples

Basic Contract Usage

import React, { useState } from 'react';
import { DubheProvider, useDubhe } from '@0xobelisk/react/sui';
import { Transaction } from '@0xobelisk/sui-client';

function CounterApp() {
  const { contract, address } = useDubhe();
  const [counter, setCounter] = useState(0);

  const queryCounter = async () => {
    try {
      const result = await contract.query.counter_system.get({});
      setCounter(result);
    } catch (error) {
      console.error('Query failed:', error);
    }
  };

  const incrementCounter = async () => {
    try {
      const tx = new Transaction();
      const result = await contract.tx.counter_system.increment({ tx });
      console.log('Transaction:', result.digest);
      await queryCounter(); // Refresh counter
    } catch (error) {
      console.error('Transaction failed:', error);
    }
  };

  return (
    <div>
      <h1>Counter: {counter}</h1>
      <p>Address: {address}</p>
      <button onClick={queryCounter}>Refresh</button>
      <button onClick={incrementCounter}>Increment</button>
    </div>
  );
}

GraphQL Integration

import React, { useEffect, useState } from 'react';
import { useDubhe } from '@0xobelisk/react/sui';

function DataComponent() {
  const { graphqlClient, ecsWorld } = useDubhe();
  const [entities, setEntities] = useState([]);

  // Real-time subscription
  useEffect(() => {
    if (graphqlClient) {
      const subscription = graphqlClient
        .subscribe({
          query: `
          subscription {
            entities {
              id
              components {
                type
                value
              }
            }
          }
        `
        })
        .subscribe((result) => {
          setEntities(result.data.entities);
        });

      return () => subscription.unsubscribe();
    }
  }, [graphqlClient]);

  // ECS component queries
  const queryComponents = async () => {
    if (ecsWorld) {
      const components = await ecsWorld.getComponent('CounterComponent');
      console.log('Components:', components);
    }
  };

  return (
    <div>
      <h2>Real-time Entities: {entities.length}</h2>
      <button onClick={queryComponents}>Query Components</button>

      {graphqlClient ? (
        <p>✅ GraphQL Connected</p>
      ) : (
        <p>❌ GraphQL Unavailable (add dubheMetadata to config)</p>
      )}
    </div>
  );
}

Error Handling

import React from 'react';
import { DubheProvider, useDubhe } from '@0xobelisk/react/sui';

function ErrorHandlingExample() {
  const { contract } = useDubhe();

  const handleTransactionWithRetry = async () => {
    const maxRetries = 3;
    let attempt = 0;

    while (attempt < maxRetries) {
      try {
        const tx = new Transaction();
        const result = await contract.tx.my_system.my_method({ tx });
        console.log('Success:', result.digest);
        return result;
      } catch (error) {
        attempt++;
        console.error(`Attempt ${attempt} failed:`, error);

        if (attempt === maxRetries) {
          throw error;
        }

        // Wait before retry
        await new Promise((resolve) => setTimeout(resolve, 1000));
      }
    }
  };

  return <button onClick={handleTransactionWithRetry}>Execute with Retry</button>;
}

🔧 TypeScript Support

Type Exports

import type {
  NetworkType,
  DubheConfig,
  ClientConfig, // Alias for DubheConfig (for consistency with @0xobelisk/client)
  DubheReturn,
  ContractReturn // Alias for DubheReturn
} from '@0xobelisk/react/sui';

Type-Safe Configuration

const config: DubheConfig = {
  network: 'devnet', // Type-safe network selection
  packageId: '0x123...',
  metadata: contractMetadata, // Typed metadata
  credentials: {
    secretKey: process.env.NEXT_PUBLIC_PRIVATE_KEY // ⚠️ LOCAL DEVELOPMENT ONLY
  }
};

const result: DubheReturn = useDubhe();
// Full type safety for all return values

🛠️ Development

# Watch mode for development
npm run watch

# Type checking
npm run type-check

# Build package
npm run build

# Run tests
npm run test

# Format code
npm run format

📖 API Reference

DubheReturn Interface

interface DubheReturn {
  contract: Dubhe; // Enhanced contract instance
  graphqlClient: DubheGraphqlClient | null; // GraphQL client (if enabled)
  grpcClient: DubheGrpcClient; // gRPC client
  ecsWorld: DubheECSWorld | null; // ECS World (if enabled)
  metadata: SuiMoveNormalizedModules; // Contract metadata
  network: NetworkType; // Current network
  packageId: string; // Package ID
  dubheSchemaId?: string; // Schema ID (if provided)
  address: string; // User address
  options?: DubheOptions; // Configuration options
  metrics?: DubheMetrics; // Performance metrics
}

DubheConfig Interface

Configuration aligned with @0xobelisk/client for consistency:

interface DubheConfig {
  // Required fields
  network: NetworkType; // 'mainnet' | 'testnet' | 'devnet' | 'localnet'
  packageId: string; // Contract package ID
  metadata: any; // Contract metadata (from dubhe schemagen)

  // Optional fields
  dubheSchemaId?: string; // Dubhe Schema ID for enhanced features
  dubheMetadata?: any; // Dubhe metadata for GraphQL/ECS features

  // Credentials
  credentials?: {
    secretKey?: string; // Private key (base64 or hex)
    mnemonics?: string; // 12 or 24 word mnemonic phrase
  };

  // Endpoints
  endpoints?: {
    fullnodeUrls?: string[]; // Full node RPC URLs (multiple for redundancy)
    graphql?: string; // GraphQL endpoint (default: http://localhost:4000/graphql)
    websocket?: string; // WebSocket endpoint (default: ws://localhost:4000/graphql)
    grpc?: string; // gRPC endpoint (default: http://localhost:8080)
  };

  // Options
  options?: {
    enableBatchOptimization?: boolean; // Default: true
    cacheTimeout?: number; // Default: 5000 (ms)
    debounceMs?: number; // Default: 100 (ms)
    reconnectOnError?: boolean; // Default: true
  };
}

// Type alias for consistency with @0xobelisk/client
type ClientConfig = DubheConfig;

Available Hooks

  • useDubhe() → DubheReturn - Complete Dubhe ecosystem
  • useDubheContract() → Dubhe - Contract instance only
  • useDubheGraphQL() → DubheGraphqlClient | null - GraphQL client only
  • useDubheECS() → DubheECSWorld | null - ECS World only
  • useContract() → DubheReturn - Alias for useDubhe()

🚨 Error Handling

The package includes comprehensive error handling:

// Configuration validation
try {
  const { contract } = useDubhe();
} catch (error) {
  console.error('Configuration error:', error.message);
}

// Provider context validation
function MyComponent() {
  try {
    const dubhe = useDubhe();
  } catch (error) {
    // Error: useDubhe must be used within a DubheProvider
  }
}

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Declared dependencies 23

Native requirements
20 direct targetsNot calculated transitive count
Package / targetRequirementRelationship
nanostores
Environment
{
  "local_name": "nanostores",
  "alias": false,
  "peer_metadata": null
}
^0.11.4runtime
@0xobelisk/ecs
Environment
{
  "local_name": "@0xobelisk/ecs",
  "alias": false,
  "peer_metadata": null
}
1.2.0-pre.93runtime
@nanostores/react
Environment
{
  "local_name": "@nanostores/react",
  "alias": false,
  "peer_metadata": null
}
^0.8.0runtime
@0xobelisk/sui-client
Environment
{
  "local_name": "@0xobelisk/sui-client",
  "alias": false,
  "peer_metadata": null
}
1.2.0-pre.93runtime
@0xobelisk/grpc-client
Environment
{
  "local_name": "@0xobelisk/grpc-client",
  "alias": false,
  "peer_metadata": null
}
1.2.0-pre.93runtime
@0xobelisk/graphql-client
Environment
{
  "local_name": "@0xobelisk/graphql-client",
  "alias": false,
  "peer_metadata": null
}
1.2.0-pre.93runtime
tsup
Environment
{
  "local_name": "tsup",
  "alias": false,
  "peer_metadata": null
}
^7.1.0development
react
Environment
{
  "local_name": "react",
  "alias": false,
  "peer_metadata": null
}
^18.0.0development
eslint
Environment
{
  "local_name": "eslint",
  "alias": false,
  "peer_metadata": null
}
^9.0.0development
prettier
Environment
{
  "local_name": "prettier",
  "alias": false,
  "peer_metadata": null
}
3.3.3development
react-dom
Environment
{
  "local_name": "react-dom",
  "alias": false,
  "peer_metadata": null
}
^18.0.0development
typescript
Environment
{
  "local_name": "typescript",
  "alias": false,
  "peer_metadata": null
}
^5.2.2development
@types/node
Environment
{
  "local_name": "@types/node",
  "alias": false,
  "peer_metadata": null
}
^20.8.7development
@types/react
Environment
{
  "local_name": "@types/react",
  "alias": false,
  "peer_metadata": null
}
^19.0.0development
@types/react-dom
Environment
{
  "local_name": "@types/react-dom",
  "alias": false,
  "peer_metadata": null
}
^19.0.0development
eslint-config-prettier
Environment
{
  "local_name": "eslint-config-prettier",
  "alias": false,
  "peer_metadata": null
}
^9.1.0development
eslint-plugin-prettier
Environment
{
  "local_name": "eslint-plugin-prettier",
  "alias": false,
  "peer_metadata": null
}
^5.0.1development
@typescript-eslint/parser
Environment
{
  "local_name": "@typescript-eslint/parser",
  "alias": false,
  "peer_metadata": null
}
^6.8.0development
@typescript-eslint/eslint-plugin
Environment
{
  "local_name": "@typescript-eslint/eslint-plugin",
  "alias": false,
  "peer_metadata": null
}
^6.8.0development
zod
Environment
{
  "local_name": "zod",
  "alias": false,
  "peer_metadata": null
}
^3.25.0 || ^4.0.0peer
react
Environment
{
  "local_name": "react",
  "alias": false,
  "peer_metadata": {
    "optional": true
  }
}
^18.0.0 || ^19.0.0peer
react-dom
Environment
{
  "local_name": "react-dom",
  "alias": false,
  "peer_metadata": {
    "optional": true
  }
}
^18.0.0 || ^19.0.0peer
@0xobelisk/sui-client
Environment
{
  "local_name": "@0xobelisk/sui-client",
  "alias": false,
  "peer_metadata": {
    "optional": true
  }
}
1.2.0-pre.93peer

Distribution files

1 collected
Distribution 1

Source distribution

Source file
Checksums from source
{
  "shasum": "8f5b69f04f68aa602dc8ae9c48862d4eab4b0e90",
  "tarball": "https://registry.npmjs.org/@0xobelisk/react/-/react-1.2.0-pre.93.tgz",
  "fileCount": 29,
  "integrity": "sha512-fsKC8EqJXhv9DdTw0a/AZIiajdbg1s+Yvjyu+qaGganjKan0NKnXL7QwRSpAFjLrdCIkEmoM5IENw0S3Yg8xBg==",
  "signatures": [
    {
      "sig": "MEQCIAnCMUwHq1FiOc2tzXwsdHbVlPcfwqCUhbUC2tk1t/P/AiACr/3Sz4yd71du3d3ssqQsX4PAxJLtlnEZHubJThjG0Q==",
      "keyid": "SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"
    }
  ],
  "unpackedSize": 276638
}

Repository

PENDING
0xobelisk/dubhe

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 21 Oct, 09:20 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package_version:94c02ec2b37fdd88ff697ea2e4eae882abf55f6844fecaf73930d97c5ce0ece1

Other collected versions

2.0.029 Jun1.2.0-pre.12522 Jun1.2.0-pre.12419 May1.2.0-pre.12318 May1.2.0-pre.12213 May1.2.0-pre.12112 MayView all collected versions →