@0xobelisk/react 1.2.0-pre.100

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,189 @@
1
+ /**
2
+ * Dubhe Provider - useRef Pattern for Client Management
3
+ *
4
+ * Features:
5
+ * - 🎯 Single client instances across application lifecycle
6
+ * - ⚡ useRef-based storage (no re-initialization on re-renders)
7
+ * - 🔧 Provider pattern for dependency injection
8
+ * - 🛡️ Complete type safety with strict TypeScript
9
+ * - 📦 Context-based client sharing
10
+ */
11
+ import { ReactNode } from 'react';
12
+ import { Dubhe } from '@0xobelisk/sui-client';
13
+ import { DubheGraphqlClient } from '@0xobelisk/graphql-client';
14
+ import { DubheECSWorld } from '@0xobelisk/ecs';
15
+ import { DubheGrpcClient } from '@0xobelisk/grpc-client';
16
+ import type { DubheConfig, DubheReturn } from './types';
17
+ /**
18
+ * Context interface for Dubhe client instances
19
+ * All clients are stored using useRef to ensure single initialization
20
+ */
21
+ interface DubheContextValue {
22
+ getContract: () => Dubhe;
23
+ getGraphqlClient: () => DubheGraphqlClient;
24
+ getGrpcClient: () => DubheGrpcClient;
25
+ getEcsWorld: () => DubheECSWorld;
26
+ getAddress: () => string;
27
+ getMetrics: () => {
28
+ initTime: number;
29
+ requestCount: number;
30
+ lastActivity: number;
31
+ };
32
+ config: DubheConfig;
33
+ updateConfig: (newConfig: Partial<DubheConfig>) => void;
34
+ resetClients: (options?: {
35
+ resetContract?: boolean;
36
+ resetGraphql?: boolean;
37
+ resetGrpc?: boolean;
38
+ resetEcs?: boolean;
39
+ }) => void;
40
+ }
41
+ /**
42
+ * Props interface for DubheProvider component
43
+ */
44
+ interface DubheProviderProps {
45
+ /** Configuration for Dubhe initialization */
46
+ config: Partial<DubheConfig>;
47
+ /** Child components that will have access to Dubhe clients */
48
+ children: ReactNode;
49
+ }
50
+ /**
51
+ * DubheProvider Component - useRef Pattern Implementation
52
+ *
53
+ * This Provider uses useRef to store client instances, ensuring they are:
54
+ * 1. Created only once during component lifecycle
55
+ * 2. Persisted across re-renders without re-initialization
56
+ * 3. Shared efficiently via React Context
57
+ *
58
+ * Key advantages over useMemo:
59
+ * - useRef guarantees single initialization (useMemo can re-run on dependency changes)
60
+ * - No dependency array needed (eliminates potential re-initialization bugs)
61
+ * - Better performance for heavy client objects
62
+ * - Clearer separation of concerns via Provider pattern
63
+ *
64
+ * @param props - Provider props containing config and children
65
+ * @returns Provider component wrapping children with Dubhe context
66
+ *
67
+ * @example
68
+ * ```typescript
69
+ * // App root setup
70
+ * function App() {
71
+ * const dubheConfig = {
72
+ * network: 'devnet',
73
+ * packageId: '0x123...',
74
+ * metadata: contractMetadata,
75
+ * credentials: {
76
+ * secretKey: process.env.NEXT_PUBLIC_PRIVATE_KEY
77
+ * }
78
+ * };
79
+ *
80
+ * return (
81
+ * <DubheProvider config={dubheConfig}>
82
+ * <MyApplication />
83
+ * </DubheProvider>
84
+ * );
85
+ * }
86
+ * ```
87
+ */
88
+ export declare function DubheProvider({ config, children }: DubheProviderProps): import("react/jsx-runtime").JSX.Element;
89
+ /**
90
+ * Custom hook to access Dubhe context
91
+ * Provides type-safe access to all Dubhe client instances
92
+ *
93
+ * @returns DubheContextValue with all client getters and config
94
+ * @throws Error if used outside of DubheProvider
95
+ *
96
+ * @example
97
+ * ```typescript
98
+ * function MyComponent() {
99
+ * const dubheContext = useDubheContext();
100
+ *
101
+ * const contract = dubheContext.getContract();
102
+ * const graphqlClient = dubheContext.getGraphqlClient();
103
+ * const ecsWorld = dubheContext.getEcsWorld();
104
+ * const address = dubheContext.getAddress();
105
+ *
106
+ * return <div>Connected as {address}</div>;
107
+ * }
108
+ * ```
109
+ */
110
+ export declare function useDubheContext(): DubheContextValue;
111
+ /**
112
+ * Enhanced hook that mimics the original useDubhe API
113
+ * Uses the Provider pattern internally but maintains backward compatibility
114
+ *
115
+ * @returns DubheReturn object with all instances and metadata
116
+ *
117
+ * @example
118
+ * ```typescript
119
+ * function MyComponent() {
120
+ * const { contract, graphqlClient, ecsWorld, address } = useDubheFromProvider();
121
+ *
122
+ * const handleTransaction = async () => {
123
+ * const tx = new Transaction();
124
+ * await contract.tx.my_system.my_method({ tx });
125
+ * };
126
+ *
127
+ * return <button onClick={handleTransaction}>Execute</button>;
128
+ * }
129
+ * ```
130
+ */
131
+ export declare function useDubheFromProvider(): DubheReturn;
132
+ /**
133
+ * Individual client hooks for components that only need specific instances
134
+ * These are more efficient than useDubheFromProvider for single-client usage
135
+ */
136
+ /**
137
+ * Hook for accessing only the Dubhe contract instance
138
+ */
139
+ export declare function useDubheContractFromProvider(): Dubhe;
140
+ /**
141
+ * Hook for accessing only the GraphQL client instance
142
+ */
143
+ export declare function useDubheGraphQLFromProvider(): DubheGraphqlClient;
144
+ /**
145
+ * Hook for accessing only the ECS World instance
146
+ */
147
+ export declare function useDubheECSFromProvider(): DubheECSWorld;
148
+ /**
149
+ * Hook for accessing only the gRPC client instance
150
+ */
151
+ export declare function useDubheGrpcFromProvider(): DubheGrpcClient;
152
+ /**
153
+ * Hook for accessing configuration update methods
154
+ *
155
+ * @returns Object with updateConfig and resetClients methods
156
+ *
157
+ * @example
158
+ * ```typescript
159
+ * function ConfigUpdater() {
160
+ * const { updateConfig, resetClients, config } = useDubheConfigUpdate();
161
+ *
162
+ * const switchNetwork = () => {
163
+ * updateConfig({
164
+ * network: 'testnet',
165
+ * packageId: '0xnew...'
166
+ * });
167
+ * };
168
+ *
169
+ * return (
170
+ * <div>
171
+ * <p>Current network: {config.network}</p>
172
+ * <button onClick={switchNetwork}>Switch to Testnet</button>
173
+ * <button onClick={resetClients}>Reset Clients</button>
174
+ * </div>
175
+ * );
176
+ * }
177
+ * ```
178
+ */
179
+ export declare function useDubheConfigUpdate(): {
180
+ updateConfig: (newConfig: Partial<DubheConfig>) => void;
181
+ resetClients: (options?: {
182
+ resetContract?: boolean;
183
+ resetGraphql?: boolean;
184
+ resetGrpc?: boolean;
185
+ resetEcs?: boolean;
186
+ }) => void;
187
+ config: DubheConfig;
188
+ };
189
+ export {};
@@ -0,0 +1,100 @@
1
+ import { SuiMoveNormalizedModules, Dubhe } from '@0xobelisk/sui-client';
2
+ import type { DubheGraphqlClient } from '@0xobelisk/graphql-client';
3
+ import type { DubheECSWorld } from '@0xobelisk/ecs';
4
+ import type { DubheGrpcClient } from '@0xobelisk/grpc-client';
5
+ /**
6
+ * Network type
7
+ */
8
+ export type NetworkType = 'mainnet' | 'testnet' | 'devnet' | 'localnet';
9
+ /**
10
+ * Modern Dubhe client configuration for auto-initialization
11
+ * Aligned with @0xobelisk/client configuration for consistency
12
+ */
13
+ export interface DubheConfig {
14
+ /** Network type */
15
+ network: NetworkType;
16
+ /** Contract package ID */
17
+ packageId: string;
18
+ /** Contract metadata (required for contract instantiation) */
19
+ metadata: any;
20
+ /** Dubhe Schema ID (optional, for enhanced features) */
21
+ dubheSchemaId?: string;
22
+ /** Dubhe metadata (enables GraphQL/ECS features) */
23
+ dubheMetadata?: any;
24
+ /** Authentication credentials */
25
+ credentials?: {
26
+ /** Private key (base64 or hex string) */
27
+ secretKey?: string;
28
+ /** Mnemonic phrase (12 or 24 words) */
29
+ mnemonics?: string;
30
+ };
31
+ /** Service endpoints configuration */
32
+ endpoints?: {
33
+ /** Full node RPC URLs (can provide multiple for redundancy) */
34
+ fullnodeUrls?: string[];
35
+ /** GraphQL endpoint URL */
36
+ graphql?: string;
37
+ /** WebSocket endpoint URL for subscriptions */
38
+ websocket?: string;
39
+ /** gRPC endpoint URL */
40
+ grpc?: string;
41
+ /** Dubhe Channel API URL */
42
+ channelUrl?: string;
43
+ };
44
+ /** Performance and behavior options */
45
+ options?: {
46
+ /** Enable batch query optimization */
47
+ enableBatchOptimization?: boolean;
48
+ /** Default cache timeout (milliseconds) */
49
+ cacheTimeout?: number;
50
+ /** Request debounce delay (milliseconds) */
51
+ debounceMs?: number;
52
+ /** Auto-reconnect on WebSocket errors */
53
+ reconnectOnError?: boolean;
54
+ };
55
+ }
56
+ /**
57
+ * Type alias for consistency with @0xobelisk/client package
58
+ */
59
+ export type ClientConfig = DubheConfig;
60
+ /**
61
+ * Return type for the main useDubhe hook
62
+ */
63
+ export interface DubheReturn {
64
+ /** Dubhe contract instance */
65
+ contract: Dubhe;
66
+ /** GraphQL client (always available, uses default localhost endpoint if not configured) */
67
+ graphqlClient: DubheGraphqlClient;
68
+ /** gRPC client (always available, uses default localhost endpoint if not configured) */
69
+ grpcClient: DubheGrpcClient;
70
+ /** ECS World instance (always available, depends on GraphQL client) */
71
+ ecsWorld: DubheECSWorld;
72
+ /** Contract metadata */
73
+ metadata: SuiMoveNormalizedModules;
74
+ /** Network type */
75
+ network: NetworkType;
76
+ /** Package ID */
77
+ packageId: string;
78
+ /** Dubhe Schema ID (if provided) */
79
+ dubheSchemaId?: string;
80
+ /** User address */
81
+ address: string;
82
+ /** Configuration options used */
83
+ options?: {
84
+ enableBatchOptimization?: boolean;
85
+ cacheTimeout?: number;
86
+ debounceMs?: number;
87
+ reconnectOnError?: boolean;
88
+ };
89
+ /** Performance metrics */
90
+ metrics?: {
91
+ initTime?: number;
92
+ requestCount?: number;
93
+ lastActivity?: number;
94
+ };
95
+ }
96
+ /**
97
+ * Compatibility alias for DubheReturn
98
+ * @deprecated Use DubheReturn instead for better consistency
99
+ */
100
+ export type ContractReturn = DubheReturn;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Utility Functions for Dubhe Configuration Management
3
+ *
4
+ * Features:
5
+ * - Configuration validation and error handling
6
+ * - Smart configuration merging with proper type safety
7
+ * - Type-safe configuration validation
8
+ */
9
+ import type { DubheConfig } from './types';
10
+ /**
11
+ * Merge multiple configuration objects with proper deep merging
12
+ * Later configurations override earlier ones
13
+ *
14
+ * @param baseConfig - Base configuration (usually defaults)
15
+ * @param overrideConfig - Override configuration (user provided)
16
+ * @returns Merged configuration
17
+ */
18
+ export declare function mergeConfigurations(baseConfig: Partial<DubheConfig>, overrideConfig?: Partial<DubheConfig>): Partial<DubheConfig>;
19
+ /**
20
+ * Validate configuration and ensure required fields are present
21
+ * Throws descriptive errors for missing required fields
22
+ *
23
+ * @param config - Configuration to validate
24
+ * @returns Validated and typed configuration
25
+ * @throws Error if required fields are missing or invalid
26
+ */
27
+ export declare function validateConfig(config: Partial<DubheConfig>): DubheConfig;
28
+ /**
29
+ * Generate a configuration summary for debugging
30
+ * Hides sensitive information like private keys
31
+ *
32
+ * @param config - Configuration to summarize
33
+ * @returns Safe configuration summary
34
+ */
35
+ export declare function getConfigSummary(config: DubheConfig): object;
package/package.json ADDED
@@ -0,0 +1,104 @@
1
+ {
2
+ "name": "@0xobelisk/react",
3
+ "version": "1.2.0-pre.100",
4
+ "description": "React integration for Dubhe framework with Sui blockchain support",
5
+ "keywords": [
6
+ "dubhe",
7
+ "react",
8
+ "blockchain",
9
+ "sui",
10
+ "web3"
11
+ ],
12
+ "homepage": "https://github.com/0xobelisk/dubhe/tree/main/packages/react#readme",
13
+ "bugs": "https://github.com/0xobelisk/dubhe/issues",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "https://github.com/0xobelisk/dubhe.git"
17
+ },
18
+ "license": "Apache-2.0",
19
+ "author": "team@obelisk.build",
20
+ "exports": {
21
+ ".": {
22
+ "source": "./src/index.ts",
23
+ "import": "./dist/index.mjs",
24
+ "require": "./dist/index.js",
25
+ "types": "./dist/index.d.ts"
26
+ },
27
+ "./sui": {
28
+ "source": "./src/sui/index.ts",
29
+ "import": "./dist/sui/index.mjs",
30
+ "require": "./dist/sui/index.js",
31
+ "types": "./dist/sui/index.d.ts"
32
+ }
33
+ },
34
+ "main": "./dist/index.js",
35
+ "module": "./dist/index.mjs",
36
+ "types": "./dist/index.d.ts",
37
+ "files": [
38
+ "dist",
39
+ "src"
40
+ ],
41
+ "dependencies": {
42
+ "@nanostores/react": "^0.8.0",
43
+ "nanostores": "^0.11.4",
44
+ "@0xobelisk/grpc-client": "1.2.0-pre.100",
45
+ "@0xobelisk/sui-client": "1.2.0-pre.100",
46
+ "@0xobelisk/graphql-client": "1.2.0-pre.100",
47
+ "@0xobelisk/ecs": "1.2.0-pre.100"
48
+ },
49
+ "devDependencies": {
50
+ "@types/node": "^20.8.7",
51
+ "@types/react": "^19.0.0",
52
+ "@types/react-dom": "^19.0.0",
53
+ "@typescript-eslint/eslint-plugin": "^6.8.0",
54
+ "@typescript-eslint/parser": "^6.8.0",
55
+ "eslint": "^9.0.0",
56
+ "eslint-config-prettier": "^9.1.0",
57
+ "eslint-plugin-prettier": "^5.0.1",
58
+ "prettier": "3.3.3",
59
+ "react": "^18.0.0",
60
+ "react-dom": "^18.0.0",
61
+ "tsup": "^7.1.0",
62
+ "typescript": "^5.2.2"
63
+ },
64
+ "peerDependencies": {
65
+ "react": "^18.0.0 || ^19.0.0",
66
+ "react-dom": "^18.0.0 || ^19.0.0",
67
+ "zod": "^3.25.0 || ^4.0.0",
68
+ "@0xobelisk/sui-client": "1.2.0-pre.100"
69
+ },
70
+ "peerDependenciesMeta": {
71
+ "@0xobelisk/sui-client": {
72
+ "optional": true
73
+ },
74
+ "react": {
75
+ "optional": true
76
+ },
77
+ "react-dom": {
78
+ "optional": true
79
+ }
80
+ },
81
+ "engines": {
82
+ "node": ">=18.0.0"
83
+ },
84
+ "publishConfig": {
85
+ "access": "public"
86
+ },
87
+ "scripts": {
88
+ "build": "npm run build:types && npm run build:tsup",
89
+ "build:tsup": "tsup ./src/index.ts ./src/sui/index.ts --format esm,cjs --sourcemap --dts",
90
+ "build:types": "tsc --build",
91
+ "clean": "rm -rf tsconfig.tsbuildinfo ./dist",
92
+ "format": "prettier --write .",
93
+ "format:check": "prettier --check .",
94
+ "format:fix": "prettier --write '**/*.{ts,tsx,json,md}'",
95
+ "lint": "eslint . --ext .ts --ext .tsx",
96
+ "test": "pnpm test:typecheck",
97
+ "test:typecheck": "tsc --noEmit",
98
+ "type-check": "tsc --noEmit",
99
+ "validate": "pnpm format:check && pnpm type-check",
100
+ "watch": "pnpm run clean & pnpm run watch:types & pnpm run watch:tsup",
101
+ "watch:tsup": "tsup ./src/index.ts ./src/sui/index.ts --format esm,cjs --clean --splitting --watch --dts",
102
+ "watch:types": "tsc --watch"
103
+ }
104
+ }
package/src/index.ts ADDED
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @0xobelisk/react - Modern Dubhe React Integration
3
+ *
4
+ * 🚀 Provides simple, powerful React experience for multi-chain blockchain development
5
+ *
6
+ * Currently supported:
7
+ * - Sui blockchain ✅
8
+ * - Aptos blockchain (coming soon)
9
+ * - Initia blockchain (coming soon)
10
+ */
11
+
12
+ // Sui integration
13
+ export * from './sui/index';
14
+ // TODO: Future extensions
15
+ // export * from './aptos/index';
16
+ // export * from './initia/index';
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Configuration Management for Dubhe React Integration
3
+ *
4
+ * Features:
5
+ * - Type-safe configuration interface
6
+ * - Configuration validation and error handling
7
+ * - Smart merging of defaults and explicit config
8
+ * - No environment variable handling (developers should handle environment variables themselves)
9
+ */
10
+
11
+ import { useMemo } from 'react';
12
+ import type { DubheConfig } from './types';
13
+ import { mergeConfigurations, validateConfig } from './utils';
14
+
15
+ /**
16
+ * Default configuration object with sensible defaults
17
+ */
18
+ export const DEFAULT_CONFIG: Partial<DubheConfig> = {
19
+ endpoints: {
20
+ graphql: 'http://localhost:4000/graphql',
21
+ websocket: 'ws://localhost:4000/graphql'
22
+ },
23
+ options: {
24
+ enableBatchOptimization: true,
25
+ cacheTimeout: 5000,
26
+ debounceMs: 100,
27
+ reconnectOnError: true
28
+ }
29
+ };
30
+
31
+ /**
32
+ * Configuration Hook: useDubheConfig
33
+ *
34
+ * Merges defaults with explicit configuration provided by the developer
35
+ *
36
+ * Note: Environment variables should be handled by the developer before passing to this hook
37
+ *
38
+ * @param config - Complete or partial configuration object
39
+ * @returns Complete, validated DubheConfig
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * // Basic usage with explicit config
44
+ * const config = useDubheConfig({
45
+ * network: 'testnet',
46
+ * packageId: '0x123...',
47
+ * metadata: contractMetadata,
48
+ * credentials: {
49
+ * secretKey: process.env.NEXT_PUBLIC_PRIVATE_KEY // Handle env vars yourself
50
+ * }
51
+ * });
52
+ *
53
+ * // With helper function to handle environment variables
54
+ * const getConfigFromEnv = () => ({
55
+ * network: process.env.NEXT_PUBLIC_NETWORK as NetworkType,
56
+ * packageId: process.env.NEXT_PUBLIC_PACKAGE_ID,
57
+ * credentials: {
58
+ * secretKey: process.env.NEXT_PUBLIC_PRIVATE_KEY
59
+ * }
60
+ * });
61
+ *
62
+ * const config = useDubheConfig({
63
+ * ...getConfigFromEnv(),
64
+ * metadata: contractMetadata
65
+ * });
66
+ * ```
67
+ */
68
+ export function useDubheConfig(config: Partial<DubheConfig>): DubheConfig {
69
+ // Memoize the stringified config to detect actual changes
70
+ const configKey = useMemo(() => {
71
+ return JSON.stringify(config);
72
+ }, [config]);
73
+
74
+ return useMemo(() => {
75
+ // Merge configurations: defaults -> user provided config
76
+ const mergedConfig = mergeConfigurations(DEFAULT_CONFIG, config);
77
+
78
+ // Validate the final configuration
79
+ const validatedConfig = validateConfig(mergedConfig);
80
+
81
+ // if (process.env.NODE_ENV === 'development') {
82
+ // console.log('🔧 Dubhe Config:', {
83
+ // ...validatedConfig,
84
+ // credentials: validatedConfig.credentials?.secretKey ? '[REDACTED]' : undefined
85
+ // });
86
+ // }
87
+
88
+ return validatedConfig;
89
+ }, [configKey]);
90
+ }