@nexus-cross/crossx-sdk-react
v2.3.7
Published
CROSSx React SDK - React Hooks and Components for Embedded Wallet
Maintainers
Readme
@nexus-cross/crossx-sdk-react
React hooks and provider for integrating the CROSSx Embedded Wallet into React applications.
Using wagmi? Use
@nexus-cross/crossx-sdk-wagmiinstead. This package is for apps that use CROSSx wallet exclusively, without wagmi.
Installation
npm install @nexus-cross/crossx-sdk-react
# or
pnpm add @nexus-cross/crossx-sdk-reactPeer dependency: react ^18.0.0
Quick Start
1. Wrap your app with CROSSxProvider
import { CROSSxProvider } from '@nexus-cross/crossx-sdk-react';
const config = {
projectId: 'your-project-id',
appName: 'My DApp',
theme: 'light' as const,
};
function App() {
return (
<CROSSxProvider config={config}>
<YourApp />
</CROSSxProvider>
);
}The provider automatically calls createCROSSxSDK(config) → sdk.initialize() on mount, restoring any existing session.
2. Sign in / Sign out — useAuth
import { useAuth } from '@nexus-cross/crossx-sdk-react';
function LoginButton() {
const { signIn, signOut, isAuthenticated, isLoading, error } = useAuth();
if (isLoading) return <p>Loading...</p>;
return isAuthenticated ? (
<button onClick={signOut}>Sign Out</button>
) : (
<div>
<button onClick={signIn}>Sign In</button>
{error && <p style={{ color: 'red' }}>{error}</p>}
</div>
);
}3. Sign & Send — useWallet
import { useWallet } from '@nexus-cross/crossx-sdk-react';
import { ChainId } from '@nexus-cross/crossx-sdk-react';
function WalletActions() {
const { address, signMessage, sendTransaction, isLoading, error } = useWallet();
const handleSign = async () => {
const result = await signMessage(ChainId.CROSS_MAINNET, 'Hello CROSSx!');
console.log('Signature:', result.signature);
};
const handleSend = async () => {
const result = await sendTransaction(ChainId.CROSS_MAINNET, {
from: address!,
to: '0x...',
value: '0x2386f26fc10000',
});
console.log('txHash:', result.txHash);
};
return (
<div>
<p>Address: {address ?? '—'}</p>
<button onClick={handleSign} disabled={isLoading}>Sign Message</button>
<button onClick={handleSend} disabled={isLoading}>Send Transaction</button>
{error && <p style={{ color: 'red' }}>{error}</p>}
</div>
);
}4. Direct SDK access — useCROSSx
For features not covered by hooks (balance, nonce, RPC, typed data signing, etc.), access the SDK instance directly.
import { useCROSSx } from '@nexus-cross/crossx-sdk-react';
function AdvancedPanel() {
const { sdk, isInitialized, isAuthenticated, walletAddress } = useCROSSx();
const handleGetBalance = async () => {
if (!sdk) return;
const { formatted } = await sdk.getBalance('eip155:612055');
console.log('Balance:', formatted);
};
const handleSignTypedData = async () => {
if (!sdk) return;
const result = await sdk.signTypedData('eip155:612055', {
types: { /* EIP-712 type definitions */ },
primaryType: 'Permit',
domain: { /* domain separator */ },
message: { /* typed message */ },
});
console.log('Signature:', result.signature);
};
if (!isInitialized) return <p>Initializing...</p>;
return (
<div>
<p>Authenticated: {isAuthenticated ? 'Yes' : 'No'}</p>
<p>Address: {walletAddress ?? '—'}</p>
<button onClick={handleGetBalance}>Get Balance</button>
<button onClick={handleSignTypedData}>EIP-712 Sign</button>
</div>
);
}API Reference
<CROSSxProvider>
| Prop | Type | Description |
|------|------|-------------|
| config | SDKConfig | SDK configuration object |
| children | ReactNode | Child components |
Key SDKConfig fields:
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| projectId | string | — | Required. Project ID from the management console |
| appName | string | — | Required. App name shown in confirmation modals |
| theme | 'light' \| 'dark' | 'light' | Confirmation modal theme |
| autoDetectTheme | boolean | false | Follow OS dark mode setting |
| themeTokens | SDKThemeTokens | — | Per-mode color overrides |
| locale | 'en' \| 'ko' | 'en' | Modal UI language |
| debug | boolean | true | Debug logging (dev builds only) |
useAuth()
Authentication state and actions.
const {
isAuthenticated, // boolean
isLoading, // boolean
error, // string | null
signIn, // () => Promise<AuthResult>
signOut, // () => Promise<void>
} = useAuth();useWallet()
Wallet address, message signing, and transaction sending.
const {
address, // string | null — wallet address (0x...)
isLoading, // boolean
error, // string | null
signMessage, // (chainId, message) => Promise<SignMessageResp>
sendTransaction, // (chainId, tx) => Promise<SendTxResp>
} = useWallet();signMessage(chainId, message)
| Parameter | Type | Example |
|-----------|------|---------|
| chainId | string | ChainId.CROSS_MAINNET |
| message | string | 'Hello CROSSx!' |
Returns: { chainId, signature, message, address }
sendTransaction(chainId, tx)
| Parameter | Type | Description |
|-----------|------|-------------|
| chainId | string | CAIP-2 chain ID |
| tx | EvmTransactionRequest | Transaction object |
Returns: { chainId, txHash, status }
useCROSSx()
Direct access to the SDK instance and global state.
const {
sdk, // CROSSxSDK | null
isInitialized, // boolean
isAuthenticated, // boolean
walletAddress, // string | null
} = useCROSSx();Available methods via sdk:
| Method | Description |
|--------|-------------|
| sdk.signMessage(chainId, msg) | EIP-191 personal sign |
| sdk.signTypedData(chainId, data) | EIP-712 typed data sign |
| sdk.signTransaction(chainId, tx) | Sign without broadcasting |
| sdk.sendTransaction(chainId, tx) | Sign + broadcast |
| sdk.sendTransactionWithWaitForReceipt(chainId, tx) | Send + poll receipt |
| sdk.getBalance(chainId) | Native balance |
| sdk.getNonce(chainId) | Current nonce |
| sdk.walletRpc(method, params, chainId) | Generic JSON-RPC |
| sdk.getProvider(chainId) | EIP-1193 provider |
| sdk.createWallet() | Manual wallet creation |
| sdk.selectWallet() | Open wallet selector |
| sdk.applyTheme('dark') | Runtime theme switch |
Chain ID Constants
import { ChainId } from '@nexus-cross/crossx-sdk-react';
ChainId.CROSS_MAINNET // 'eip155:612055'
ChainId.CROSS_TESTNET // 'eip155:612044'Confirmation Modal
All sign/send operations automatically display an approval modal:
- Message Sign — "Signature Request" modal
- EIP-712 Typed Data — Structured key-value display
- Transaction — Recipient, amount, and fee details
On mobile (≤480px), the modal automatically renders as a bottom sheet.
Theme Customization
// At initialization
<CROSSxProvider config={{ theme: 'dark' }}>
// Runtime switch
const { sdk } = useCROSSx();
sdk?.applyTheme('dark');
// Custom colors
<CROSSxProvider config={{
theme: 'light',
themeTokens: {
light: { primary: '#FF6B35', bg: '#F5F0EB' },
dark: { primary: '#FF6B35', bg: '#1A0A00' },
},
}}>Comparison with wagmi Package
| | @nexus-cross/crossx-sdk-react | @nexus-cross/crossx-sdk-wagmi |
|---|---|---|
| Dependencies | React only | wagmi + viem + @tanstack/react-query |
| Approach | CROSSx-specific hooks | wagmi standard hooks (useAccount, etc.) |
| EIP-1193 | Via sdk.getProvider() | Automatic (wagmi connector) |
| Best for | CROSSx-only apps | Multi-wallet apps (MetaMask, etc.) |
Troubleshooting
useCROSSx must be used within CROSSxProvider
Wrap your app root with <CROSSxProvider>.
OAuth popup doesn't open
Check browser popup blocker, or use config.oauthDisplayMode = 'modal'.
Related Packages
| Package | Description |
|---------|-------------|
| @nexus-cross/crossx-sdk-core | Core SDK (vanilla JS) |
| @nexus-cross/crossx-sdk-wagmi | wagmi connector |
License
MIT
