Guides
NEXUS
Guides

API Reference

Core SDK — API Reference

This page documents the public API surface of CROSSxSDK for JavaScript/TypeScript (current version: 2.4.0). The wallet product's display brand is ONEpocket (formerly CROSSx); the package and class names are unchanged.

Factory

import { createCROSSxSDK } from '@nexus-cross/crossx-sdk-core'

const sdk = createCROSSxSDK(config: SDKConfig): CROSSxSDK

Creates and returns a CROSSxSDK instance. This is the only way to instantiate the SDK — do not use new CROSSxSDK() directly.

Rebrand alias: createONEpocketSDK is exported as an alias of createCROSSxSDK (identical behavior). See Rebrand aliases.

Configuration Types

SDKConfig

interface SDKConfig {
  projectId: string
  appName: string
  useMockWallet?: boolean
  logger?: LoggerPort
  theme?: 'light' | 'dark'
  autoDetectTheme?: boolean
  themeTokens?: SDKThemeTokens
  locale?: 'ko' | 'en'   // default: 'en'
  debug?: boolean
  receiptPolling?: {
    intervalMs?: number   // default: 2000
    timeoutMs?: number    // default: 60000
  }
  migration?: {
    allowSkip?: boolean   // default: true
  }
  showConnectOtherWallets?: boolean  // default: false
  connectOtherWallets?: ConnectOtherWalletItem[]
  persistWalletPreference?: boolean  // default: true
  enableRNBridgeAutoLogin?: boolean  // default: true
  displayDecimals?: number           // default: 6
  pinKeyboard?: 'virtual' | 'native' | (() => 'virtual' | 'native')
}
FieldTypeRequiredDescription
projectIdstringYesProject ID from management console
appNamestringYesApplication name displayed in confirmation modals
useMockWalletbooleanNoEnable mock wallet for testing
loggerLoggerPortNoCustom logger for routing SDK logs
theme'light' | 'dark'NoConfirmation modal theme (default: 'light')
autoDetectThemebooleanNoAuto-detect system dark mode via prefers-color-scheme (default: false)
themeTokensSDKThemeTokensNoPer-mode color overrides
locale'ko' | 'en'NoModal UI language (default: 'en')
debugbooleanNoEnable debug log output
receiptPollingobjectNo{ intervalMs?: number, timeoutMs?: number }
migrationobjectNo{ allowSkip?: boolean } — controls migration UI behavior (default: { allowSkip: true })
showConnectOtherWalletsbooleanNoShow all built-in "Connect with Other Wallets" entries in the login modal (default: false). Clicking an entry emits connectExternalWallet ({ walletId }) and throws EXTERNAL_WALLET_REQUESTED
connectOtherWalletsConnectOtherWalletItem[]NoExternal wallets to show in the login selector. A non-empty array takes precedence over showConnectOtherWallets and shows only the listed items
persistWalletPreferencebooleanNoAuto-save the last selected wallet to storage and restore it on the next initialize() (default: true). Set false to manage wallet selection yourself via initialize({ preferredWalletIndex }) etc.
enableRNBridgeAutoLoginbooleanNoIn the wallet in-app browser (RN Bridge), attempt auto sign-in with the wallet app's session (default: true)
displayDecimalsnumberNoMax decimal places when formatting wei/token amounts for display (default: 6). Trailing zeros are removed
pinKeyboard'virtual' | 'native' | (() => 'virtual' | 'native')NoPIN modal keyboard mode on mobile: 'virtual' (SDK numpad, default) or 'native' (OS keyboard). Pass a function to decide per modal open

SDKThemeTokens

interface SDKThemeTokens {
  light?: SDKColorOverrides
  dark?: SDKColorOverrides
}

SDKColorOverrides

interface SDKColorOverrides {
  primary?: string
  secondary?: string
  onPrimary?: string
  borderDefault?: string
  borderSubtle?: string
  textIconPrimary?: string
  textIconSecondary?: string
  textIconTertiary?: string
  surfaceDefault?: string
  surfaceSubtle?: string
  bg?: string
  error?: string
}

Color format: CSS color string (e.g. '#FF6B35', 'rgba(18,18,18,0.5)').

SignInOptions

interface SignInOptions {
  provider?: 'google' | 'apple'
}

SignInWithCreateOptions

interface SignInWithCreateOptions extends SignInOptions {
  /** Wallet address to auto-select. If present in the wallet list, the selectWallet() modal is skipped. */
  preferredWalletAddress?: string
}

SignOptions

interface SignOptions {
  index?: number
  dappName?: string
  accountName?: string
}

Core API

initialize(opts?)

async initialize(opts?: { preferredWalletIndex?: number; preferredWalletAddress?: string }): Promise<AuthResult | null>
ParameterTypeRequiredDescription
opts.preferredWalletIndexnumberNoWallet derivation index to restore on session resume
opts.preferredWalletAddressstringNoWallet address to restore on session resume (takes the matching wallet if it exists)

Returns: AuthResult if a prior session is restored, null if no session exists.

Initializes the SDK and restores a prior session from persistent storage if available. Must be called once at startup before any other SDK method. When a session is restored, the returned AuthResult reflects the user's previous sign-in state.

whenReady()

async whenReady(): Promise<boolean>

Returns: true once initialization has completed, false if initialization has not been started or failed.

Waits for SDK initialization to finish. Prevents race conditions where isAuthenticated() is checked while initialize() is still in flight (e.g. frameworks that do not await connector setup). If initialization has already completed, resolves immediately with true; if it is in progress, resolves when it finishes; if it was never started, resolves immediately with false.

signIn(options?)

async signIn(options?: SignInOptions): Promise<AuthResult>
ParameterTypeRequiredDescription
options.provider'google' | 'apple'NoOAuth provider to use. If omitted, the SDK displays a provider selection modal.

Returns: AuthResult

Opens the OAuth sign-in flow. If options.provider is not specified, a provider selection modal is displayed. On success, creates a session and returns auth state. Throws if the user cancels.

signInWithCreate(options?)

async signInWithCreate(options?: SignInWithCreateOptions): Promise<SignInWithCreateResult>
ParameterTypeRequiredDescription
options.provider'google' | 'apple'NoOAuth provider to use
options.preferredWalletAddressstringNoWallet address to auto-select. If it exists in the user's wallet list, the wallet selector modal is skipped

Returns: SignInWithCreateResult

Signs in and automatically creates an embedded wallet if the user does not already have one. Also handles legacy CROSSx wallet migration automatically. When the user has two or more wallets, the wallet selector modal is shown (unless preferredWalletAddress matches an existing wallet). Use this method for most onboarding flows.

signInWithOAuthToken(firebaseToken)

async signInWithOAuthToken(firebaseToken: string): Promise<SignInWithCreateResult>
ParameterTypeRequiredDescription
firebaseTokenstringYesFirebase ID token obtained externally (e.g. from a native app deeplink)

Returns: SignInWithCreateResult

Completes sign-in with an externally obtained Firebase ID token instead of opening the OAuth popup — used when the OAuth flow is performed outside the SDK (e.g. a React Native host app passes the token via deeplink; see parseOAuthDeeplink). Behaves like signInWithCreate() afterwards: creates the wallet if needed and shows the wallet selector when the user has multiple wallets. The resulting authChanged event carries source: 'external'.

signInAgain()

async signInAgain(): Promise<AuthResult>

Returns: AuthResult on success, { success: false } on failure.

Re-authenticates the same account after session expiry (SESSION_EXPIRED). Opens OAuth again and verifies that the same account was used; if a different account signs in, the SDK signs it out and prompts the user to retry with the original account.

signInWithJWT(accessToken, refreshToken?)

async signInWithJWT(accessToken: string, refreshToken?: string): Promise<AuthResult>
ParameterTypeRequiredDescription
accessTokenstringYesJWT access token obtained from your backend or Firebase
refreshTokenstringNoOptional refresh token for session renewal

Returns: AuthResult

Authenticates using a pre-obtained JWT access token. Useful for React Native WebView scenarios where Firebase Auth is handled natively and the token is passed to the JS SDK. The JWT signature is verified via JWKS.

signOut()

async signOut(): Promise<void>

Signs out the current user and clears the session from persistent storage. Emits an authChanged event with isAuthenticated: false.

isAuthenticated()

isAuthenticated(): boolean

Returns: true if the user has an active authenticated session, false otherwise.

Synchronous check of the current auth state. Does not trigger a network request.

isLoggedIn()

isLoggedIn(): boolean

Alias for isAuthenticated(). Returns the same value.

ensureLoggedIn()

async ensureLoggedIn(): Promise<boolean>

Returns: true if the session is valid, false if a sign-in is needed.

Verifies that the current session is still valid (e.g. token not expired). Use before operations that require authentication.

getUserInfo()

async getUserInfo(): Promise<SDKUserInfo>

Returns: SDKUserInfo

Retrieves the authenticated user's profile including ID, email, login type, and wallet addresses. Throws AUTH_NOT_AUTHENTICATED if not signed in.

currentAddress

get currentAddress: string | null

Synchronous getter returning the currently active wallet address, or null if not authenticated or no wallet is selected.

currentUserId

get currentUserId: string | null

Synchronous getter returning the authenticated user's ID (JWT sub claim), or null if not authenticated.

Address / Wallet

getAddress(index?)

async getAddress(index?: number): Promise<{ address: string; index: number } | null>
ParameterTypeRequiredDescription
indexnumberNoWallet derivation index. Defaults to the currently selected wallet index.

Returns: { address: string; index: number } or null if no wallet exists at that index.

Returns the address for a specific HD wallet derivation index. If no index is specified, returns the active wallet's address.

getAddresses()

async getAddresses(): Promise<Array<{ address: string; index: number; name?: string }>>

Returns: Array of all wallet addresses for the current user, each with its derivation index and optional user-defined wallet name.

Retrieves all HD wallet addresses derived for this user's account.

createWallet()

async createWallet(): Promise<{ address: string }>

Returns: { address: string } — the newly created wallet address.

Derives a new HD wallet address for the current user. Requires the user to be authenticated.

selectWallet(currentAddress?)

async selectWallet(currentAddress?: string): Promise<{ address: string; index: number; name?: string } | null>
ParameterTypeRequiredDescription
currentAddressstringNoAddress to mark as "currently selected" in the wallet selector modal

Returns: { address: string; index: number; name? } for the wallet the user selected, or null if the user dismisses the modal.

Opens the wallet selector modal, allowing the user to switch between multiple HD wallets. If currentAddress is provided, the matching wallet entry is highlighted with a "selected" tag.

Chain

getChains()

async getChains(): Promise<ChainInfo[]>

Returns: Array of ChainInfo for all supported chains.

Returns all chains configured for the current project. Does not require authentication — only initialize() must have been called.

getChain(chainId)

async getChain(chainId: string): Promise<ChainInfo>
ParameterTypeRequiredDescription
chainIdstringYesCAIP-2 chain ID (e.g. 'eip155:612044')

Returns: ChainInfo for the specified chain.

Returns configuration for a specific chain. Throws INVALID_CHAIN if chainId is not in CAIP-2 format, or CHAIN_NOT_SUPPORTED if the chain is not registered.

Signing

All signing methods display a user confirmation modal before executing.

signMessage(chainId, message, opts?)

async signMessage(
  chainId: string,
  message: string,
  opts?: SignOptions
): Promise<SignMessageResp>
ParameterTypeRequiredDescription
chainIdstringYesCAIP-2 chain ID (e.g. 'eip155:612044')
messagestringYesPlain-text message to sign
opts.indexnumberNoWallet derivation index
opts.dappNamestringNoDApp name shown in the confirmation modal
opts.accountNamestringNoAccount label shown in the confirmation modal

Returns: SignMessageResp

Signs a UTF-8 message using EIP-191 personal sign. Displays a confirmation modal showing the message content and signer address before proceeding.

signTypedData(chainId, typedData, opts?)

async signTypedData(
  chainId: string,
  typedData: unknown,
  opts?: SignOptions
): Promise<SignTypedDataResp>
ParameterTypeRequiredDescription
chainIdstringYesCAIP-2 chain ID. The numeric part must match typedData.domain.chainId.
typedDataunknownYesEIP-712 typed data object with domain.chainId
optsSignOptionsNoWallet index and display options

Returns: SignTypedDataResp

Signs EIP-712 typed structured data for on-chain use. Requires typedData.domain.chainId to match the numeric part of chainId. Throws TYPED_DATA_CHAIN_ID_MISMATCH on mismatch. For typed data without a chain ID, use signTypedDataOffchain().

signTypedDataOffchain(typedData, opts?)

async signTypedDataOffchain(
  typedData: unknown,
  opts?: SignOptions
): Promise<SignTypedDataResp>
ParameterTypeRequiredDescription
typedDataunknownYesEIP-712 typed data object without domain.chainId
optsSignOptionsNoWallet index and display options

Returns: SignTypedDataResp with chainId: '0'

Signs EIP-712 typed data for off-chain use cases (e.g. permit signatures, order books). Use when typedData.domain.chainId is absent or zero.

signTransaction(chainId, tx, opts?)

async signTransaction(
  chainId: string,
  tx: EvmTransactionRequest,
  opts?: SignOptions
): Promise<SignTxResp>
ParameterTypeRequiredDescription
chainIdstringYesCAIP-2 chain ID
txEvmTransactionRequestYesTransaction to sign. tx.from must be non-empty.
optsSignOptionsNoWallet index and display options

Returns: SignTxResp

Signs a transaction without broadcasting it. Gas fields (gasLimit, gasPrice / maxFeePerGas) are resolved automatically if not provided. Returns the RLP-encoded signed transaction and its hash.

Transactions

sendTransaction(chainId, tx, opts?)

async sendTransaction(
  chainId: string,
  tx: EvmTransactionRequest,
  opts?: SignOptions
): Promise<SendTxResp>
ParameterTypeRequiredDescription
chainIdstringYesCAIP-2 chain ID
txEvmTransactionRequestYesTransaction to broadcast. tx.from must be non-empty.
optsSignOptionsNoWallet index and display options

Returns: SendTxResp

Signs and broadcasts a transaction. Displays a confirmation modal before signing. Gas fields are auto-resolved if not provided. Returns immediately after broadcast with status: 'pending'.

sendTransactionWithWaitForReceipt(chainId, tx, opts?)

async sendTransactionWithWaitForReceipt(
  chainId: string,
  tx: EvmTransactionRequest,
  opts?: SignOptions & { intervalMs?: number; timeoutMs?: number }
): Promise<TransactionWithReceipt>
ParameterTypeRequiredDescription
chainIdstringYesCAIP-2 chain ID
txEvmTransactionRequestYesTransaction to broadcast
opts.intervalMsnumberNoReceipt polling interval in ms (default: from SDKConfig.receiptPolling, fallback 2000)
opts.timeoutMsnumberNoPolling timeout in ms (default: from SDKConfig.receiptPolling, fallback 60000)

Returns: TransactionWithReceipt

Signs, broadcasts, and waits for the transaction receipt. Displays a transaction progress modal showing pending and mined states. Polling interval and timeout default to the values set in SDKConfig.receiptPolling.

getTransactionReceipt(txHash, chainId)

async getTransactionReceipt(txHash: string, chainId: string): Promise<TransactionReceipt | null>
ParameterTypeRequiredDescription
txHashstringYesTransaction hash
chainIdstringYesCAIP-2 chain ID

Returns: TransactionReceipt if mined, null if still pending.

Fetches the receipt for a specific transaction hash. Returns null if the transaction has not been mined yet.

waitForTxAndGetReceipt(txHash, chainId, opts?)

async waitForTxAndGetReceipt(
  txHash: string,
  chainId: string,
  opts?: { intervalMs?: number; timeoutMs?: number }
): Promise<TransactionReceipt>
ParameterTypeRequiredDescription
txHashstringYesTransaction hash to poll
chainIdstringYesCAIP-2 chain ID
opts.intervalMsnumberNoBase polling interval in ms (default: 1000)
opts.timeoutMsnumberNoTimeout in ms (default: 60000)

Returns: TransactionReceipt

Polls for a transaction receipt until it is mined or the timeout is reached. Polling starts at the base interval (1000 ms by default) and backs off exponentially — doubling after each attempt, capped at 10000 ms. Throws if the timeout expires before the receipt is available.

Gas

getGasPrice(chainId)

async getGasPrice(chainId: string): Promise<string>
ParameterTypeRequiredDescription
chainIdstringYesCAIP-2 chain ID

Returns: Hex-encoded gas price in Wei (e.g. '0x3b9aca00').

Fetches the current gas price via eth_gasPrice. Use for legacy (pre-EIP-1559) transactions. For EIP-1559 chains, prefer getMaxPriorityFeePerGas() and getBaseFeePerGas().

estimateGas(tx, chainId)

async estimateGas(tx: EvmTransactionRequest, chainId: string): Promise<string>
ParameterTypeRequiredDescription
txEvmTransactionRequestYesTransaction to estimate
chainIdstringYesCAIP-2 chain ID

Returns: Hex-encoded estimated gas limit (e.g. '0x5208').

Calls eth_estimateGas on the specified chain. The estimate reflects gas required at the current block state. Throws GAS_ESTIMATION_FAILED if the call reverts.

getBaseFeePerGas(chainId)

async getBaseFeePerGas(chainId: string): Promise<string | null>
ParameterTypeRequiredDescription
chainIdstringYesCAIP-2 chain ID

Returns: Hex-encoded base fee in Wei, or null on chains that do not support EIP-1559.

Fetches the base fee per gas from the latest block header. Returns null on legacy chains.

getMaxPriorityFeePerGas(chainId)

async getMaxPriorityFeePerGas(chainId: string): Promise<string>
ParameterTypeRequiredDescription
chainIdstringYesCAIP-2 chain ID

Returns: Hex-encoded EIP-1559 priority fee (tip) in Wei.

Fetches the suggested miner priority fee via eth_maxPriorityFeePerGas. Use with getBaseFeePerGas() to construct EIP-1559 transaction fee fields.

Balance / Nonce / RPC

getBalance(chainId)

async getBalance(chainId: string): Promise<{ wei: string; formatted: string; chainId: string }>
ParameterTypeRequiredDescription
chainIdstringYesCAIP-2 chain ID

Returns:

FieldTypeDescription
weistringRaw balance in Wei as a decimal string
formattedstringHuman-readable balance in native token units (e.g. '1.5')
chainIdstringCAIP-2 chain ID the balance was fetched from

Fetches the native token balance for the current wallet on the specified chain.

getNonce(chainId)

async getNonce(chainId: string): Promise<number>
ParameterTypeRequiredDescription
chainIdstringYesCAIP-2 chain ID

Returns: Current transaction count (nonce) as a number.

Returns the number of transactions sent from the current wallet address via eth_getTransactionCount. Unlike the mobile SDKs, this returns a number rather than a hex string.

walletRpc(method, params, chainId)

async walletRpc(method: string, params: any[], chainId: string): Promise<any>
ParameterTypeRequiredDescription
methodstringYesJSON-RPC method name (e.g. 'eth_call')
paramsany[]YesMethod parameters array
chainIdstringYesCAIP-2 chain ID to send the request to

Returns: JSON-RPC result.

Sends a raw JSON-RPC read-only request to the specified chain's RPC endpoint. Intended for read operations (eth_call, eth_getBalance, eth_getCode, etc.). Do not use for signing or sending transactions.

Provider

getProvider(chainId)

getProvider(chainId: string): CROSSxEthereumProvider
ParameterTypeRequiredDescription
chainIdstringYesCAIP-2 chain ID (e.g. 'eip155:612044')

Returns: CROSSxEthereumProvider — an EIP-1193 compatible provider.

Returns an EIP-1193 provider bound to the specified chain. Compatible with ethers.js v6, viem, and other libraries that accept an EIP-1193 provider.

const provider = sdk.getProvider('eip155:612044')

// ethers.js v6
const ethersProvider = new ethers.BrowserProvider(provider)

// viem
const client = createWalletClient({ transport: custom(provider) })

Theme & Locale

applyTheme(themeMode?, themeTokens?)

applyTheme(themeMode?: 'light' | 'dark', themeTokens?: SDKThemeTokens): void
ParameterTypeRequiredDescription
themeMode'light' | 'dark'NoTheme mode to apply
themeTokensSDKThemeTokensNoColor token overrides for light/dark modes

Changes the confirmation modal theme at runtime. Takes effect on the next modal open. Useful for responding to system dark mode changes dynamically.

applyLocale(locale?)

applyLocale(locale?: 'ko' | 'en'): void
ParameterTypeRequiredDescription
locale'ko' | 'en'NoLanguage for modal UI text

Changes the confirmation modal language at runtime. Takes effect on the next modal open.

sdk.applyLocale('ko')
sdk.applyLocale('en')

PIN Management

setPin(pin)

setPin(pin: string): void
ParameterTypeRequiredDescription
pinstringYesPIN to cache in memory

Caches the user's PIN in memory so that signing flows can proceed without displaying a PIN input modal. The PIN is kept only in memory and cleared on clearPin() or signOut().

clearPin()

clearPin(): void

Clears the cached PIN from memory. Subsequent signing flows that require a PIN will prompt the user via the SDK modal.

hasPin()

hasPin(): boolean

Returns: true if a PIN is currently cached in memory, false otherwise.

Checks whether a PIN is cached without exposing the PIN value.

isPinRequired()

isPinRequired(): boolean

Returns: true if the next sign/send operation will require PIN entry (no PIN cached in memory), false otherwise.

Use this to decide whether to show your own PIN prompt before a signing flow:

if (sdk.isPinRequired()) {
  const pin = await showPinModal()
  sdk.setPin(pin)
}
await sdk.signMessage(chainId, message)

setPinKeyboard(mode)

setPinKeyboard(mode: 'virtual' | 'native' | (() => 'virtual' | 'native')): void
ParameterTypeRequiredDescription
mode'virtual' | 'native' | (() => 'virtual' | 'native')YesKeyboard mode: 'virtual' (SDK-rendered numpad), 'native' (OS keyboard), or a function evaluated each time the PIN modal opens

Changes the PIN input modal's keyboard mode at runtime. Takes effect on the next PIN modal open. Also configurable at creation time via SDKConfig.pinKeyboard.

changePin(oldPin, newPin)

async changePin(oldPin: string, newPin: string): Promise<void>
ParameterTypeRequiredDescription
oldPinstringYesCurrent PIN
newPinstringYesNew PIN to set

Changes the user's PIN on the server. The new PIN must satisfy format requirements (no sequential or repeated digit patterns). Throws PIN_WRONG if oldPin is incorrect, or PIN_INVALID / PIN_REPEATED_PATTERN if the new PIN is rejected.

Migration

migrateWallet(pin)

async migrateWallet(pin: string): Promise<MigrateResult>
ParameterTypeRequiredDescription
pinstringYes4-digit PIN used during original CROSSx wallet creation

Returns: MigrateResult

Migrates a legacy CROSSx wallet to an Embedded Wallet using the original 4-digit PIN. After migration, the wallet is accessible via the standard wallet API. Throws MIGRATION_FAILED on failure or MIGRATION_PIN_LOCKED after too many incorrect PIN attempts.

Token History

registerTokenHistory(chainId, txHash, clientVersion)

async registerTokenHistory(
  chainId: string,
  txHash: string,
  clientVersion: string
): Promise<void>
ParameterTypeRequiredDescription
chainIdstringYesCAIP-2 chain ID (e.g. 'eip155:1')
txHashstringYesTransaction hash to register
clientVersionstringYesClient version string (max 64 chars, e.g. 'my-dapp/1.2.3')

Registers a wallet-sent coin/ERC-20 transfer in the token history service. The transaction must already be indexed, have succeeded (status == 1), and be an ERC-20 transfer (0xa9059cbb) or coin transfer (0x00000000). Throws CROSSxError on validation or API errors.

getTokenHistory(options?)

async getTokenHistory(options?: {
  lastTimestamp?: number
  lastTxIndex?: number
}): Promise<TokenHistoryItem[]>
ParameterTypeRequiredDescription
options.lastTimestampnumberNoCursor: timestamp of the last item from the previous page
options.lastTxIndexnumberNoCursor: tx_index of the last item from the previous page

Returns: TokenHistoryItem[]

Fetches transactions previously registered via registerTokenHistory(). Supports cursor-based pagination:

const history = await sdk.getTokenHistory()

if (history.length > 0) {
  const last = history[history.length - 1]
  const nextPage = await sdk.getTokenHistory({
    lastTimestamp: last.timestamp,
    lastTxIndex: last.tx_index,
  })
}

Events

CROSSxSDK extends TypedEventEmitter<SDKEventMap> and supports typed event subscription.

on(event, listener)

on(event: string, listener: Function): () => void

Subscribes to an SDK event. Returns an unsubscribe function.

off(event, listener)

off(event: string, listener: Function): void

Removes an event listener.

Event Types

EventPayloadDescription
authChanged{ isAuthenticated: boolean, address: string | null, userId: string | null, source?: 'external' }Fired when auth state changes (sign in / sign out). source: 'external' marks sign-ins performed via signInWithOAuthToken()
addressChanged{ address: string, index: number, walletName?: string }Fired when the active wallet address changes
initialized{ restored: boolean }Fired when SDK initialization completes
connectExternalWallet{ walletId: string }Fired when the user selects an external wallet row in the login modal (walletId = ConnectOtherWalletItem value)
const unsub = sdk.on('authChanged', (event) => {
  console.log(event.isAuthenticated, event.address)
})

// Cleanup
unsub()

Lifecycle

dispose()

dispose(): void

Cleans up SDK resources including event listeners and internal state. The instance cannot be used after this call. Call this when unmounting an SDK host component or tearing down the application.

Response Types

AuthResult

FieldTypeDescription
successbooleanAuthentication success flag
addressstring?Wallet address (if available)
userUserInfo?User profile
errorstring?Error message on failure
needsMigrationboolean?CROSSx backup found
tokenSignatureVerifiedboolean?JWT verified via JWKS

SignInWithCreateResult

Extends AuthResult with additional fields:

FieldTypeDescription
addressesArray<{ address: string; index: number; name?: string }>Full wallet address list (with optional user-defined wallet names)

SDKUserInfo

FieldTypeDescription
idstringUser identifier (JWT sub)
emailstring?User email
loginTypestring?'google' | 'apple'
addressesstring[]Wallet address list
tokenSignatureVerifiedbooleanJWT verified via JWKS

ChainInfo

FieldTypeDescription
chainIdstringCAIP-2 chain ID (e.g. eip155:612044)
rpcUrlstringJSON-RPC endpoint URL

EvmTransactionRequest

FieldTypeDescription
fromstringSender address
tostringRecipient address
valuestring?Hex wei value
datastring?Calldata hex
gasLimitstring?Hex gas limit
gasPricestring?Legacy gas price
maxFeePerGasstring?EIP-1559 max fee
maxPriorityFeePerGasstring?EIP-1559 priority fee
noncenumber?Nonce (number)
chainIdnumber?Numeric chain ID

SignMessageResp

FieldTypeDescription
chainIdstringCAIP-2 chain ID
signaturestringSignature hex
messagestringOriginal message
addressstringSigner address

SignTypedDataResp

FieldTypeDescription
chainIdstringCAIP-2 chain ID (on-chain) or '0' (off-chain)
signaturestringEIP-712 signature hex
addressstringSigner address

SignTxResp

FieldTypeDescription
chainIdstringCAIP-2 chain ID
signedTxstringRLP-encoded signed tx hex
txHashstringTransaction hash

SendTxResp

FieldTypeDescription
chainIdstringCAIP-2 chain ID
txHashstringBroadcasted tx hash
statusstring'pending' | 'success' | 'failed'

TransactionWithReceipt

FieldTypeDescription
chainIdstringCAIP-2 chain ID
txHashstringTransaction hash
receiptTransactionReceiptMined receipt

TransactionReceipt

FieldTypeDescription
transactionHashstringTransaction hash
blockHashstringBlock hash
blockNumberstringBlock number (hex)
fromstringSender
tostring | nullRecipient (null for contract creation)
gasUsedstringGas used (hex)
effectiveGasPricestringGas price (hex)
status'0x1' | '0x0'Success or reverted
logsany[]Event logs
transactionIndexstringIndex in block
typestringTransaction type

MigrateResult

FieldTypeDescription
addressstringMigrated wallet address

TokenHistoryItem

FieldTypeDescription
txstringTransaction hash
chain_idnumberNumeric chain ID
block_numbernumberBlock number
tx_indexnumberTransaction index (pagination cursor)
from / tostringSender / recipient address
from_alias / to_aliasstring?Address aliases (if any)
tokenstringToken address (0x0...0 for native coin on all chains)
amountstringTransfer amount (wei / smallest unit)
timestampnumberUnix timestamp in seconds (pagination cursor)
statusstring'success' | 'fail'
gas_price / gas_used / max_fee_per_gas / noncenumber?Gas / nonce details
methodnumber[] | nullMethod ID bytes
method_aliasstring?Method alias (if any)

GetTokenHistoryResponse

FieldTypeDescription
rowsTokenHistoryItem[]History items
last_data{ last_timestamp?: number; last_tx_index?: number }?Pagination cursor

RegisterTokenHistoryRequest

FieldTypeDescription
clientVersionstringClient version (required, max 64 chars)

Error Handling

import { CROSSxError, ErrorCode } from '@nexus-cross/crossx-sdk-core'

try {
  await sdk.signTransaction(chainId, tx)
} catch (error) {
  if (error instanceof CROSSxError) {
    console.log(error.code)     // ErrorCode enum
    console.log(error.message)  // Human-readable message
    console.log(error.details)  // Original error
  }
}

Error Codes

CodeDescription
AUTH_NOT_INITIALIZEDSDK not initialized — call initialize() first
AUTH_FAILEDSign in failed
AUTH_TOKEN_INVALIDAuth token is invalid
AUTH_TOKEN_EXPIREDAuth token has expired
AUTH_NOT_AUTHENTICATEDNot authenticated — call signIn() first
ALREADY_AUTHENTICATEDAlready authenticated — sign out first
SESSION_EXPIREDSession expired — both access and refresh tokens invalid, re-login required (see signInAgain())
OAUTH_POPUP_BLOCKEDOAuth popup was blocked or could not be opened
WALLET_NOT_FOUNDWallet not found
WALLET_CREATION_FAILEDWallet creation failed
WALLET_ALREADY_EXISTSWallet already exists for this user (gateway -10004)
ADDRESS_LIMIT_EXCEEDEDDerived address count exceeds the server limit (gateway -10036). The limit (MNEMONIC_ADDRESS_LIMIT = 100) is passed in error.details.limit
WALLET_INCONSISTENT_STATEWallet state inconsistency detected
SIGN_FAILEDSigning failed
SIGN_REJECTEDSigning rejected
SIGNATURE_FAILEDSignature operation failed
TX_FAILEDTransaction failed
TX_REJECTEDTransaction rejected
TRANSACTION_FAILEDTransaction operation failed
TX_INVALID_PARAMSInvalid transaction parameters
NOT_IMPLEMENTEDFeature not implemented
USER_REJECTEDUser rejected in confirmation modal
SIGNATURE_SIGNER_MISMATCHecrecover address mismatch
GAS_ESTIMATION_FAILEDGas estimation failed (eth_gasPrice / eth_estimateGas)
TYPED_DATA_CHAIN_ID_MISMATCHEIP-712 domain.chainId mismatch with path chainId
NETWORK_ERRORNetwork communication error
NETWORK_NOT_CONFIGUREDNetwork adapter not configured
INVALID_CHAINInvalid chain ID format
CHAIN_NOT_SUPPORTEDChain not supported / not registered
CHAIN_ADAPTER_NOT_FOUNDChain adapter not found
PREPARE_FAILEDPre-sign/send preparation failed
PREPARE_EXPIREDPrepared action expired
PREPARE_MISMATCHPrepared action mismatch
MIGRATION_FAILEDWallet migration failed
MIGRATION_BACKUP_EXISTSCROSSx backup found, migration required
MIGRATION_PIN_LOCKEDPIN locked during migration — too many attempts
PIN_NOT_SETPIN is required but not set
PIN_WRONGIncorrect PIN entered
PIN_INVALIDPIN format is invalid (sequential digits not allowed)
PIN_REPEATED_PATTERNPIN repeated digit pattern not allowed (Gateway -10032)
PIN_CANCELLEDUser cancelled PIN input
EXTERNAL_WALLET_REQUESTEDUser requested external wallet connection via "Connect with Other Wallets" button
PIN_LOCKEDPIN locked due to too many failed attempts
PIN_ENCRYPTION_INVALIDPIN ciphertext invalid (gateway -10045) — e.g. stale cached public key. Not counted toward PIN lock; surfaces only after the SDK's automatic retry also fails
PIN_POLICY_VIOLATIONPIN policy violation (gateway -10046)
PIN_ENCRYPTION_FAILEDPIN encryption itself failed (public key fetch/import or WebCrypto failure); no plaintext fallback
BROADCAST_FAILEDTransaction broadcast failed (-10007)
GATEWAY_INTERNAL_ERRORGateway internal error (-10006), retry recommended
GATEWAY_LOCK_CONFLICTLock conflict (-10008), retry recommended
HMAC_REQUIREDHMAC signature header missing (gateway -10040)
HMAC_VERIFICATION_FAILEDHMAC signature verification failed (gateway -10041)
WITHDRAW_FAILEDAccount withdrawal failed (gateway -10013)
USER_NOT_FOUNDUser not found on gateway (-10033) — forces logout
PROJECT_ID_MISSINGX-Project-Id header missing (gateway -10023)
ORIGIN_NOT_ALLOWEDOrigin not in allowed list (gateway -10024)
APP_IDENTIFIER_MISSINGApp identifier missing (gateway -10024)
INVALID_APP_TYPEInvalid X-App-Type value (gateway -10025)
PROJECT_NOT_REGISTEREDProject not whitelisted (gateway -10022)
INVALID_CONFIGInvalid SDK configuration
UNKNOWN_ERRORUnknown error

Chain ID Constants

import { ChainId } from '@nexus-cross/crossx-sdk-core'
ConstantValueChain nameNative symbol
ChainId.ONE_MAINNET'eip155:612055'ONEchain MainnetONE
ChainId.ONE_TESTNET'eip155:612044'ONEchain TestnettONE
ChainId.BSC_MAINNET'eip155:56'BNB Smart ChainBNB
ChainId.BSC_TESTNET'eip155:97'BNB Smart Chain TestnetBNB
ChainId.RONIN_MAINNET'eip155:2020'RoninRON
ChainId.RONIN_SAIGON'eip155:202601'Ronin SaigonRON

ChainId.CROSS_MAINNET / ChainId.CROSS_TESTNET were renamed to ChainId.ONE_MAINNET / ChainId.ONE_TESTNET. The CAIP-2 values are unchanged.

Public Type Exports

import type {
  SDKConfig,
  SDKThemeTokens,
  SDKColorOverrides,
  AuthResult,
  SignInWithCreateResult,
  SignInOptions,
  SignInWithCreateOptions,
  SignOptions,
  SDKUserInfo,
  UserInfo,
  EvmTransactionRequest,
  SignMessageResp,
  SignTypedDataResp,
  SignTxResp,
  SendTxResp,
  TransactionWithReceipt,
  MigrateResult,
  ChainInfo,
  ChainIdValue,
  AddressInfo,
  SDKEventMap,
  AuthChangedEvent,
  AddressChangedEvent,
  InitializedEvent,
  ConnectExternalWalletEvent,
  LoginSelectorResult,
  TokenHistoryItem,
  GetTokenHistoryResponse,
  RegisterTokenHistoryRequest,
  PrepareAction,
  PrepareContext,
  PrepareResult,
  EIP1193Provider,
} from '@nexus-cross/crossx-sdk-core'

import {
  createCROSSxSDK,
  CROSSxSDK,
  CROSSxEthereumProvider,
  ChainId,
  CROSSxError,
  ErrorCode,
  MNEMONIC_ADDRESS_LIMIT,   // 100 — max derivable addresses (ADDRESS_LIMIT_EXCEEDED)
  WALLET_BRAND_NAME,        // 'ONEpocket' — user-facing wallet brand name
  parseOAuthDeeplink,       // parse OAuth deeplinks (RN WebView integration)
  getWalletBrowserInfo,     // detect the wallet in-app browser
  isWalletInAppBrowser,
  waitForWalletBrowser,
  ConnectOtherWalletItem,   // external wallet IDs for SDKConfig.connectOtherWallets
  CONNECT_OTHER_WALLET_DISPLAY_ORDER,
  getConnectOtherWalletLabel,
} from '@nexus-cross/crossx-sdk-core'

Rebrand aliases

The wallet's display brand is ONEpocket (formerly CROSSx). The following exports are aliases of the CROSSx names — identical values/classes, both names remain available:

AliasSame as
createONEpocketSDKcreateCROSSxSDK
ONEpocketSDKCROSSxSDK
ONEpocketErrorCROSSxError
ONEpocketEthereumProviderCROSSxEthereumProvider