API Reference
Unity SDK API Reference
This page documents the public API surface of CROSSxSDK for Unity.
Configuration Types
SDKConfig
SDKConfigclass 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:ProjectIdX-App-Id:AppId(defaults toApplication.identifier)X-App-Type:android/ios/windows(per build target)
enum SDKLoginProvider { All, Google, Apple }
Allshows the login provider selector modal.Applego directly to that provider. Default isAll.
Theme
enum ThemeMode { Light, Dark, System }
class ThemeTokens
{
ThemeColorOverrides Light { get; set; }
ThemeColorOverrides Dark { get; set; }
}ThemeColorOverrides
ThemeColorOverridesclass 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
Colorstruct.
Factory
static class CROSSxSDKFactory
{
static CROSSxSDK Create(SDKConfig config)
}Core API
bool IsInitialized { get; }—trueafterInitializeAsync()completesTask<AuthResult> InitializeAsync()void ApplyTheme(ThemeMode? themeMode = null, ThemeTokens themeTokens = null)void SetLocale(string locale)— change modal UI language at runtimestring GetLocale()— get current localevoid 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()→AuthResultSignInAgainAsync()→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()→boolEnsureLoggedInAsync()→boolRefreshTokenAsync()→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 devicebool IsBiometricEnabled()— whether biometric is currently enabledTask 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_foundaccordingly. - If
migration_requiredandmigrateAutomatically == false, throwsCROSSxExceptionwithCROSSxErrorType.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) ornullif 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.chainIdis present (on-chain typed data)
- Use when
SignTypedDataOffchainAsync(object typedData, string from = null, string dappName = null, string accountName = "Account")- Use when there is no
domain.chainId(off-chain typed data)
- Use when there is no
SignTransactionAsync(...)- Variant: SDK model (
WalletUnsignedTransaction walletTx) (Recommended) — chainId from tx - Variant: Raw payload (
UnsignedTx unsignedTx, string chainId = null) - optional params:
dappName,networkName,estimatedFee,amount
- Variant: SDK model (
SendTransactionAsync(...)- Variant: SDK model (
WalletUnsignedTransaction walletTx) (Recommended) — chainId from tx - Variant: Raw payload (
UnsignedTx unsignedTx, string chainId = null) - optional params:
dappName,networkName,estimatedFee,amount
- Variant: SDK model (
SendTransactionWithWaitForReceiptAsync(...)- Variant: SDK model (
WalletUnsignedTransaction walletTx) (Recommended) - Variant: Raw payload (
UnsignedTx unsignedTx, string chainId = null) - optional params:
dappName,networkName,estimatedFee,amount,timeoutMs,pollIntervalMs
- Variant: SDK model (
Use
WalletUnsignedTransactionby default. UseUnsignedTxonly when you need low-level gateway payload control. For transaction sign/send flows,frommust be provided (non-empty).
Return notes
SignMessageAsync()→SignMessageResponse(Signature)SignTypedDataAsync()→SignTypedDataResponse(Signature)SignTransactionAsync()→SignTxResponse(SignedTx, optionalTxHash)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)
WalletRpcAsyncis for contract read/call only (for exampleeth_call). Transaction sign/send methods are not supported via this API.chainIdis mandatory forWalletRpcAsyncand all RPC helper methods. Use CAIP-2eip155:<number>format (for exampleeip155:1).
Return notes
WalletRpcAsync()→JsonRpcResponse(Id,Jsonrpc,Result, optionalError)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 transactionChainId: 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: stringDomain: JObjectMessage: JObject
Eip712Field
Name: stringType: string
TransactionReceipt
TransactionHash: stringBlockHash: stringBlockNumber: stringFrom: stringTo: stringGasUsed: stringEffectiveGasPrice: stringStatus: stringTransactionIndex: stringType: stringLogs: JArrayRawJson: string
CheckWalletResponse
result: string— raw value:"exists"|"migration_required"|"not_found"Exists: boolMigrationRequired: boolNotFound: bool
SetupWalletResult
Status: WalletSetupStatus—Verified|Created|Migrated|SkippedAddress: string?IsReady: bool—truewhenStatusisVerified,Created, orMigrated
WalletSelectionResult
Address: stringIndex: int
AuthResult
Success: boolWalletAddress: string?User: UserInfo?NeedsMigration: bool?
SDKUserInfo
Id: stringEmail: string?LoginType: string?Addresses: List<string>
SignRequestType (confirmation modal type)
PersonalSignTypedDataTransaction
JsonRpcRequest
Id: stringJsonrpc: stringMethod: stringParams: JArray(JSON array)
Errors
CROSSxException
CROSSxExceptionclass CROSSxException : Exception
{
CROSSxErrorType ErrorType { get; }
int? ErrorCode { get; }
PinLockInfo LockInfo { get; }
}CROSSxErrorType
CROSSxErrorTypeCommon 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 viaSignInAgainAsync().AccountMismatch— user signed in with a different account than expected.InvalidPassword— wrong wallet password entered.PasswordLocked— too many wrong password attempts; checkCROSSxException.LockInfofor lockout details.MigrationRequired— thrown whenCreateWalletAsync(migrateAutomatically: false)encounters a migration-required wallet.
SessionExpiredException
SessionExpiredExceptionThrown 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
GatewayExceptionThrown for wallet gateway API errors with ErrorCode and ErrorData.
Wallet gateway integrations may also surface:
-10040— HMAC validation failed (for example a missingX-HMAC-Signature)-10041— HMAC validation failed (for example an invalidX-HMAC-Signature)
Port Interfaces
The SDK follows hexagonal architecture. All external dependencies are abstracted through ports:
| Port | Responsibility |
|---|---|
ITransportPort | HTTP requests, authorization headers, project headers |
IOAuthPort | Build login URL, open browser, parse callback |
IDeepLinkPort | Wait for deep link callback, simulate deep link |
IStoragePort | Save, load, delete persistent data |
IAuthBackendPort | Exchange OAuth token for backend tokens |
IEmbeddedWalletPort | Gateway API (create, migrate, sign, send, RPC) |
Updated about 18 hours ago