@nexus-cross/crossx-sdk-core
v2.1.2
Published
CROSSx Core SDK - Vanilla JavaScript Embedded Wallet SDK
Maintainers
Readme
@nexus-cross/crossx-sdk-core
OAuth-based Embedded Wallet SDK for JavaScript/TypeScript.
Built on Clean Architecture + Hexagonal Architecture — environment-independent business logic with replaceable adapters.
Features
- OAuth Sign-In — Google & Apple social login with automatic session management
- Embedded Wallet — Server-managed HD wallet with client-side PIN protection
- EIP-1193 Provider — Drop-in integration with ethers.js, viem, and wagmi
- Transaction Confirmation — Built-in approval modal before every sign/send (cannot be bypassed)
- Multi-Chain — CAIP-2 standard chain IDs (
eip155:612055) - Multi-Wallet — Multiple addresses per account with wallet selector UI
- Theme Customization — Light/dark mode with granular color token overrides
Installation
npm install @nexus-cross/crossx-sdk-core
# or
pnpm add @nexus-cross/crossx-sdk-core
# or
yarn add @nexus-cross/crossx-sdk-coreQuick Start
import { createCROSSxSDK, ChainId } from '@nexus-cross/crossx-sdk-core';
const sdk = createCROSSxSDK({
projectId: 'your-project-id',
appName: 'My DApp',
theme: 'light',
});
// Restore previous session (if any)
const session = await sdk.initialize();
if (session) {
console.log('Restored:', session.address);
}
// Sign in with OAuth
await sdk.signIn({ provider: 'google' });
// Get wallet address
const addr = await sdk.getAddress();
console.log(addr?.address);
// Sign a message (confirmation modal is shown automatically)
const { signature } = await sdk.signMessage(
ChainId.CROSS_MAINNET,
'Hello CROSSx!',
);API Reference
Initialization & Authentication
// Initialize SDK — restores session if available
const session = await sdk.initialize();
// Sign in (opens OAuth popup)
const result = await sdk.signIn();
const result = await sdk.signIn({ provider: 'google' });
// Sign in + auto-create wallet if none exists
const result = await sdk.signInWithCreate();
// Check authentication status
sdk.isAuthenticated(); // boolean
sdk.currentAddress; // string | null
// Validate session (returns boolean, never throws)
const valid = await sdk.ensureLoggedIn();
// Sign out
await sdk.signOut();User Info
const info = await sdk.getUserInfo();
// { id, email?, loginType?, addresses }Wallet
// Create wallet (when none exists after sign-in)
const { address } = await sdk.createWallet();
// Get active wallet address
const addr = await sdk.getAddress(); // { address, index } | null
const addr = await sdk.getAddress(1); // specific index
// List all wallet addresses
const addrs = await sdk.getAddresses(); // [{ address, index, name? }]
// Open wallet selector modal (multi-wallet)
const selected = await sdk.selectWallet();
// Native balance
const { wei, formatted } = await sdk.getBalance(ChainId.CROSS_MAINNET);
console.log(formatted); // "1.234567 CROSS"
// Nonce
const nonce = await sdk.getNonce(ChainId.CROSS_MAINNET);Signing
// EIP-191 personal_sign
const { signature } = await sdk.signMessage('eip155:612055', 'Hello!');
// EIP-712 Typed Data
const { signature } = await sdk.signTypedData('eip155:612055', typedData);
// Sign transaction (without broadcasting)
const { signedTx, txHash } = await sdk.signTransaction('eip155:612055', tx);Sending Transactions
const tx = {
from: sdk.currentAddress!,
to: '0x...',
value: '0x2386f26fc10000', // hex wei
data: '0x',
};
// Send (returns immediately)
const { txHash } = await sdk.sendTransaction('eip155:612055', tx);
// Send + wait for receipt
const { txHash, receipt } = await sdk.sendTransactionWithWaitForReceipt(
'eip155:612055',
tx,
);
console.log(receipt.status); // '0x1' = successTransaction Confirmation Modal
Every signTransaction, sendTransaction, and signMessage call automatically displays a user approval modal. There is no API to bypass it.
import { CROSSxError, ErrorCode } from '@nexus-cross/crossx-sdk-core';
try {
await sdk.sendTransaction(ChainId.CROSS_MAINNET, tx);
} catch (error) {
if (error instanceof CROSSxError && error.code === ErrorCode.USER_REJECTED) {
console.log('User cancelled');
}
}Receipt Polling
// Single query (null if not yet mined)
const receipt = await sdk.getTransactionReceipt(txHash, 'eip155:612055');
// Poll until mined
const receipt = await sdk.waitForTxAndGetReceipt(txHash, 'eip155:612055', {
intervalMs: 3000,
timeoutMs: 120000,
});EIP-1193 Provider
Standard provider for direct integration with ethers.js, viem, etc.
const provider = sdk.getProvider('eip155:612055');
// ethers.js v6
import { BrowserProvider } from 'ethers';
const ethersProvider = new BrowserProvider(provider);
const signer = await ethersProvider.getSigner();
// viem
import { createWalletClient, custom } from 'viem';
const client = createWalletClient({ transport: custom(provider) });Generic JSON-RPC
// eth_getBalance
const balance = await sdk.walletRpc(
'eth_getBalance',
[address, 'latest'],
'eip155:612055',
);
// eth_call (ERC-20 balanceOf)
const data = '0x70a08231' + address.slice(2).padStart(64, '0');
const raw = await sdk.walletRpc(
'eth_call',
[{ to: tokenAddress, data }, 'latest'],
'eip155:612055',
);Gas Estimation
const gasPrice = await sdk.getGasPrice('eip155:612055');
const gasLimit = await sdk.estimateGas(tx, 'eip155:612055');
const baseFee = await sdk.getBaseFeePerGas('eip155:612055');
const priorityFee = await sdk.getMaxPriorityFeePerGas('eip155:612055');Events
sdk.on('authChanged', ({ isAuthenticated, address }) => { /* ... */ });
sdk.on('addressChanged', ({ address, index }) => { /* ... */ });
sdk.on('initialized', ({ isAuthenticated }) => { /* ... */ });Theme
// Runtime theme switch
sdk.applyTheme('dark');
// With custom color tokens
sdk.applyTheme('dark', {
dark: { primary: '#FF6B35', bg: '#1A0A00' },
});SDKConfig
const sdk = createCROSSxSDK({
// Required
projectId: 'your-project-id',
appName: 'My DApp',
// Theme
theme: 'light', // 'light' | 'dark'
autoDetectTheme: false, // follow OS dark mode
themeTokens: {
light: { primary: '#FF6B35' }, // per-mode color overrides
dark: { primary: '#FF6B35', bg: '#1A0A00' },
},
// Locale
locale: 'en', // 'en' | 'ko'
// Receipt polling defaults
receiptPolling: {
intervalMs: 2000,
timeoutMs: 60000,
},
// Debug logging (only effective in dev builds)
debug: true,
// Custom logger
logger: {
log: (...args) => console.log('[MyApp]', ...args),
warn: (...args) => console.warn('[MyApp]', ...args),
error: (...args) => console.error('[MyApp]', ...args),
},
});Theme Tokens
Override individual semantic color tokens per mode. Unspecified tokens retain their defaults.
| Token | Description | Default (light) | Default (dark) |
|-------|-------------|-----------------|----------------|
| primary | Buttons & accent | #019D92 | #019D92 |
| secondary | Secondary accent | #E70077 | #E70077 |
| onPrimary | Text on primary | #FFFFFF | #FFFFFF |
| bg | Card background | #FFFFFF | #121212 |
| textPrimary | Primary text | #121212 | #FFFFFF |
| textSecondary | Secondary text | rgba(18,18,18,0.7) | rgba(255,255,255,0.7) |
| textTertiary | Tertiary text | rgba(18,18,18,0.5) | rgba(255,255,255,0.5) |
| surfaceDefault | Surface fill | rgba(18,18,18,0.05) | rgba(255,255,255,0.05) |
| borderDefault | Default border | rgba(18,18,18,0.05) | rgba(255,255,255,0.05) |
| borderSubtle | Subtle border | rgba(18,18,18,0.1) | rgba(255,255,255,0.1) |
Chain ID Constants
import { ChainId } from '@nexus-cross/crossx-sdk-core';
ChainId.CROSS_MAINNET // 'eip155:612055'
ChainId.CROSS_TESTNET // 'eip155:612044'
ChainId.BSC_MAINNET // 'eip155:56'
ChainId.BSC_TESTNET // 'eip155:97'
ChainId.RONIN_MAINNET // 'eip155:2020'
ChainId.RONIN_TESTNET // 'eip155:202601'Error Handling
import { CROSSxError, ErrorCode } from '@nexus-cross/crossx-sdk-core';
try {
await sdk.sendTransaction(chainId, tx);
} catch (error) {
if (error instanceof CROSSxError) {
switch (error.code) {
case ErrorCode.USER_REJECTED:
// User cancelled confirmation modal
break;
case ErrorCode.AUTH_NOT_AUTHENTICATED:
// Not signed in
break;
case ErrorCode.PIN_CANCELLED:
// User cancelled PIN entry
break;
}
}
}Public Types
import type {
SDKConfig,
SDKThemeTokens,
AuthResult,
SDKUserInfo,
EvmTransactionRequest,
TransactionReceipt,
TransactionWithReceipt,
SignMessageResp,
SignTxResp,
SignTypedDataResp,
SendTxResp,
SignInOptions,
SignOptions,
ChainIdValue,
ChainInfo,
SDKEventMap,
ConfirmationDetails,
} from '@nexus-cross/crossx-sdk-core';Related Packages
| Package | Description |
|---------|-------------|
| @nexus-cross/crossx-sdk-react | React hooks & provider |
| @nexus-cross/crossx-sdk-wagmi | wagmi connector |
License
MIT
