API Reference

Unity SDK API Reference

This page documents the public API surface of CROSSxSDK for Unity.

Configuration Types

SDKConfig

class SDKConfig
{
    string ProjectId { get; set; }                       // default: "unity-sample"
    string AppId { get; set; }                           // default: Application.identifier
    string AppName { get; set; }                         // default: "App"
    SDKLoginProvider LoginProvider { get; set; }         // default: All
    string DefaultChainId { get; set; }                  // default: "eip155:1"
    string Locale { get; set; }                          // default: "en"

    ThemeMode Theme { get; set; }                        // default: Dark
    ThemeTokens ThemeTokens { get; set; }

    string OAuthServerUrl { get; set; }
    string AuthApiUrl { get; set; }
    string EmbeddedWalletGatewayUrl { get; set; }

    bool Debug { get; set; }                             // default: false

    string CustomUriScheme => $"crossx-{ProjectId}"     // read-only
}

Gateway whitelist headers are added automatically on authenticated wallet/RPC calls:

  • X-Project-Id: ProjectId
  • X-App-Id: AppId (defaults to Application.identifier)
  • X-App-Type: android / ios / windows (per build target)
enum SDKLoginProvider { All, Google, Apple }

All shows the login provider selector modal. Google and Apple go directly to that provider. Default is All.

Theme

enum ThemeMode { Light, Dark, System }

class ThemeTokens
{
    ThemeColorOverrides Light { get; set; }
    ThemeColorOverrides Dark { get; set; }
}

ThemeColorOverrides

class ThemeColorOverrides
{
    Color? Primary
    Color? Secondary
    Color? OnPrimary
    Color? BorderDefault
    Color? BorderSubtle
    Color? TextIconPrimary
    Color? TextIconSecondary
    Color? TextIconTertiary
    Color? SurfaceDefault
    Color? SurfaceSubtle
    Color? Bg
}

Color format: Unity Color struct.

Factory

static class CROSSxSDKFactory
{
    static CROSSxSDK Create(SDKConfig config)
}

Core API

  • bool IsInitialized { get; }true after InitializeAsync() completes
  • Task<AuthResult> InitializeAsync()
  • void ApplyTheme(ThemeMode? themeMode = null, ThemeTokens themeTokens = null)
  • void SetLocale(string locale) — change modal UI language at runtime
  • string GetLocale() — get current locale
  • void EnableSignConfirmation(VisualElement uiRoot, ThemeMode? theme = null, string appName = null)
  • Task<AuthResult> SignInAsync(SDKLoginProvider? provider = null)
  • Task<AuthResult> SignInAsync(string providerOrUrl)
  • Task<AuthResult> SignInAgainAsync()
  • Task<AuthResult> SignInWithCreateAsync(SDKLoginProvider? provider = null)
  • Task SignOutAsync()
  • bool IsLoggedIn()
  • Task<bool> EnsureLoggedInAsync()
  • Task<string> RefreshTokenAsync()
  • Task<SDKUserInfo> GetUserInfoAsync()

Behavior summary

  • InitializeAsync()AuthResult? (null if no stored session)
  • SignInAsync()AuthResult
  • SignInAgainAsync()AuthResult — Re-runs sign-in for an already-authenticated user (e.g. to re-validate the session after expiry) without going through the full OAuth provider selection.
  • SignInWithCreateAsync()AuthResult (sign in + wallet setup in one call)
  • SignOutAsync()Task (void)
  • IsLoggedIn()bool
  • EnsureLoggedInAsync()bool
  • RefreshTokenAsync()string (new access token)
  • GetUserInfoAsync()SDKUserInfo

Wallet password and biometrics

Wallet passwords are stored securely after confirmation UI and reused for later signing and sending.

  • bool CanUseBiometric() — whether biometric authentication is available on the device
  • bool IsBiometricEnabled() — whether biometric is currently enabled
  • Task SetBiometricEnabledAsync(bool enabled) — enable or disable biometric authentication

Address / Wallet

  • Task<CheckWalletResponse> CheckWalletAsync()
  • Task<SetupWalletResult> SetupWalletAsync(string sub = null)
  • Task<SetupWalletResult> CreateWalletAsync(bool migrateAutomatically = true)
  • Task<GetAddressResponse> GetAddressAsync(int index = 0)
  • Task<GetAddressesResponse> GetAddressesAsync()
  • Task<WalletSelectionResult> SelectWalletAsync(string selectedAddress = null)

CreateWalletAsync() branches

  • The SDK checks wallet state and handles exists / migration_required / not_found accordingly.
  • If migration_required and migrateAutomatically == false, throws CROSSxException with CROSSxErrorType.MigrationRequired.
  • PIN input and wallet found modals are managed internally by the SDK.

Return notes

  • CheckWalletAsync()CheckWalletResponse (Exists, MigrationRequired, NotFound)
  • SetupWalletAsync()SetupWalletResult (Status, Address, IsReady)
  • CreateWalletAsync()SetupWalletResult (Status, Address, IsReady)
  • GetAddressAsync()GetAddressResponse (address, index)
  • GetAddressesAsync()GetAddressesResponse (addresses[])
  • SelectWalletAsync()WalletSelectionResult (Address, Index) or null if cancelled

Signing / Sending (UI confirm flow)

All sign/send methods show the SDK confirmation modal. chainId is required. Use CAIP-2 eip155:<number> format for chainId (for example eip155:1, eip155:612044).

  • SignMessageAsync(string message, string chainId = null, string from = null, string dappName = null, string accountName = "Account")
  • SignTypedDataAsync(object typedData, string chainId, string from = null, string dappName = null, string accountName = "Account")
    • Use when typedData.domain.chainId is present (on-chain typed data)
  • SignTypedDataOffchainAsync(object typedData, string from = null, string dappName = null, string accountName = "Account")
    • Use when there is no domain.chainId (off-chain typed data)
  • SignTransactionAsync(...)
    • Variant: SDK model (WalletUnsignedTransaction walletTx) (Recommended) — chainId from tx
    • Variant: Raw payload (UnsignedTx unsignedTx, string chainId = null)
    • optional params: dappName, networkName, estimatedFee, amount
  • SendTransactionAsync(...)
    • Variant: SDK model (WalletUnsignedTransaction walletTx) (Recommended) — chainId from tx
    • Variant: Raw payload (UnsignedTx unsignedTx, string chainId = null)
    • optional params: dappName, networkName, estimatedFee, amount
  • SendTransactionWithWaitForReceiptAsync(...)
    • Variant: SDK model (WalletUnsignedTransaction walletTx) (Recommended)
    • Variant: Raw payload (UnsignedTx unsignedTx, string chainId = null)
    • optional params: dappName, networkName, estimatedFee, amount, timeoutMs, pollIntervalMs

Use WalletUnsignedTransaction by default. Use UnsignedTx only when you need low-level gateway payload control. For transaction sign/send flows, from must be provided (non-empty).

Return notes

  • SignMessageAsync()SignMessageResponse (Signature)
  • SignTypedDataAsync()SignTypedDataResponse (Signature)
  • SignTransactionAsync()SignTxResponse (SignedTx, optional TxHash)
  • SendTransactionAsync()SendTxResponse (TxHash)
  • SendTransactionWithWaitForReceiptAsync()TransactionReceipt

RPC / Helpers

  • Task<JsonRpcResponse> WalletRpcAsync(JsonRpcRequest request, string chainId)
  • Task<string> GetBalanceAsync(string address, string chainId, string blockTag = "latest")
  • Task<string> GetNonceAsync(string address, string chainId, string blockTag = "pending")
  • Task<TransactionReceipt> WaitForTxAndGetReceiptAsync(string txHash, string chainId, long timeoutMs = 30000, long pollIntervalMs = 1000)

WalletRpcAsync is for contract read/call only (for example eth_call). Transaction sign/send methods are not supported via this API. chainId is mandatory for WalletRpcAsync and all RPC helper methods. Use CAIP-2 eip155:<number> format (for example eip155:1).

Return notes

  • WalletRpcAsync()JsonRpcResponse (Id, Jsonrpc, Result, optional Error)
  • GetBalanceAsync()string (hex wei)
  • GetNonceAsync()string (hex nonce)
  • WaitForTxAndGetReceiptAsync()TransactionReceipt

Key Object Details

UnsignedTx

  • ChainId: string?
  • From: string (required for transaction sign/send flows)
  • To: string?
  • Value: string?
  • Data: string?
  • Nonce: string?
  • GasLimit: string?
  • GasPrice: string?
  • MaxFeePerGas: string?
  • MaxPriorityFeePerGas: string?

WalletUnsignedTransaction

Abstract base. Use the nested class directly:

var walletTx = new WalletUnsignedTransaction.EvmEip155("eip155:612044")
{
    From = "0xYourAddress",
    To   = "0xRecipient",
    Value = "0xde0b6b3a7640000",
    Data  = "0x"
};
  • EvmEip155(string chainId): EVM EIP-155 transaction
    • ChainId: string (required, set via constructor)
    • From: string (required for sign/send flows)
    • To, Value, Data, Nonce, GasLimit, GasPrice, MaxFeePerGas, MaxPriorityFeePerGas
  • Tron(string raw, string chainId = null): placeholder, not yet supported

Eip712TypedData

  • Types: Dictionary<string, List<Eip712Field>>
  • PrimaryType: string
  • Domain: JObject
  • Message: JObject

Eip712Field

  • Name: string
  • Type: string

TransactionReceipt

  • TransactionHash: string
  • BlockHash: string
  • BlockNumber: string
  • From: string
  • To: string
  • GasUsed: string
  • EffectiveGasPrice: string
  • Status: string
  • TransactionIndex: string
  • Type: string
  • Logs: JArray
  • RawJson: string

CheckWalletResponse

  • result: string — raw value: "exists" | "migration_required" | "not_found"
  • Exists: bool
  • MigrationRequired: bool
  • NotFound: bool

SetupWalletResult

  • Status: WalletSetupStatusVerified | Created | Migrated | Skipped
  • Address: string?
  • IsReady: booltrue when Status is Verified, Created, or Migrated

WalletSelectionResult

  • Address: string
  • Index: int

AuthResult

  • Success: bool
  • WalletAddress: string?
  • User: UserInfo?
  • NeedsMigration: bool?

SDKUserInfo

  • Id: string
  • Email: string?
  • LoginType: string?
  • Addresses: List<string>

SignRequestType (confirmation modal type)

  • PersonalSign
  • TypedData
  • Transaction

JsonRpcRequest

  • Id: string
  • Jsonrpc: string
  • Method: string
  • Params: JArray (JSON array)

Errors

CROSSxException

class CROSSxException : Exception
{
    CROSSxErrorType ErrorType { get; }
    int? ErrorCode { get; }
    PinLockInfo LockInfo { get; }
}

CROSSxErrorType

Common error variants (matching Android CROSSxError):

  • Auth: NotAuthenticated, AuthFailed, TokenExpired, SessionExpired, OAuthFailed, AccountMismatch
  • User cancel: UserRejected
  • Wallet: MigrationRequired, WalletPasswordRequired, WalletPasswordChanged, WalletInconsistentState, MigrationPinFailed, WalletPinFailed, InvalidPassword, PasswordLocked
  • Sign / send: SignFailed, TransactionFailed, Timeout
  • Other: NetworkError, InvalidConfig, Unknown

Notes:

  • SessionExpired — access token is unusable and refresh failed (e.g. refresh token expired). Requires sign-out or re-authentication via SignInAgainAsync().
  • AccountMismatch — user signed in with a different account than expected.
  • InvalidPassword — wrong wallet password entered.
  • PasswordLocked — too many wrong password attempts; check CROSSxException.LockInfo for lockout details.
  • MigrationRequired — thrown when CreateWalletAsync(migrateAutomatically: false) encounters a migration-required wallet.

SessionExpiredException

Thrown when both access and refresh tokens are expired. The SDK shows a session expired modal allowing the user to sign in again or sign out.

GatewayException

Thrown for wallet gateway API errors with ErrorCode and ErrorData.

Wallet gateway integrations may also surface:

  • -10040 — HMAC validation failed (for example a missing X-HMAC-Signature)
  • -10041 — HMAC validation failed (for example an invalid X-HMAC-Signature)

Port Interfaces

The SDK follows hexagonal architecture. All external dependencies are abstracted through ports:

PortResponsibility
ITransportPortHTTP requests, authorization headers, project headers
IOAuthPortBuild login URL, open browser, parse callback
IDeepLinkPortWait for deep link callback, simulate deep link
IStoragePortSave, load, delete persistent data
IAuthBackendPortExchange OAuth token for backend tokens
IEmbeddedWalletPortGateway API (create, migrate, sign, send, RPC)

© 2025 NEXUS Co., Ltd. All Rights Reserved.