Mobile SDK
The Kryptos Connect Mobile SDK provides React Native components for iOS and Android applications. It works with both Expo and React Native CLI.
Make sure you have completed the prerequisites in the overview and set up your backend server.
Installation
- npm
- yarn
- Expo
npm install @kryptos_connect/mobile-sdk react-native-webview
yarn add @kryptos_connect/mobile-sdk react-native-webview
npx expo install @kryptos_connect/mobile-sdk react-native-webview
iOS (React Native CLI only):
cd ios && pod install
Prerequisites
- Client ID from the Kryptos Developer Portal
- WalletConnect Project ID from WalletConnect Cloud (optional)
Quick Start
import { KryptosConnect, KryptosConnectButton } from "@kryptos_connect/mobile-sdk";
// 1. Initialize once (or on every render to keep config in sync)
KryptosConnect.init({
clientId: "your-client-id",
appName: "My App",
appLogo: "https://yourapp.com/logo.png",
theme: "light", // "light" | "dark" | "auto"
language: "en",
authMethods: ["email", "anonymous"],
});
// 2. Drop in the button
<KryptosConnectButton
generateLinkToken={generateLinkToken}
onConnectSuccess={(consent) => console.log(consent.public_token)}
onConnectError={(err) => console.error(err)}
buttonLabel="Connect Kryptos"
buttonHeight={52}
/>;
Full Example
import { KryptosConnect, KryptosConnectButton } from "@kryptos_connect/mobile-sdk";
import { useState } from "react";
const BASE_URL = "https://connect-api.kryptos.io";
const CLIENT_ID = "your-client-id";
const CLIENT_SECRET = "your-client-secret"; // keep server-side in production
const SCOPES = "openid profile offline_access email portfolios:read integrations:read";
export default function App() {
const [accessToken, setAccessToken] = useState(null);
KryptosConnect.init({
clientId: CLIENT_ID,
appName: "My App",
theme: "light",
language: "en",
authMethods: ["email", "anonymous"],
});
async function generateLinkToken(existingAccessToken?: string | null) {
const body: Record<string, unknown> = { scopes: SCOPES };
if (existingAccessToken) body.access_token = existingAccessToken;
const res = await fetch(`${BASE_URL}/link-token`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Client-Id": CLIENT_ID,
"X-Client-Secret": CLIENT_SECRET,
},
body: JSON.stringify(body),
});
const data = await res.json();
return { link_token: data.data.link_token, isAuthorized: !!existingAccessToken };
}
async function handleSuccess(consent) {
if (!consent) return; // re-auth — no new token
const res = await fetch(`${BASE_URL}/token/exchange`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
public_token: consent.public_token,
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
}),
});
const data = await res.json();
setAccessToken(data.data.access_token);
}
return (
<>
{/* Default button */}
<KryptosConnectButton
generateLinkToken={() => generateLinkToken()}
onConnectSuccess={handleSuccess}
onConnectError={(err) => console.error(err)}
buttonLabel="Link Kryptos Account"
buttonHeight={52}
/>
{/* Pre-select a specific integration with custom style */}
<KryptosConnectButton
generateLinkToken={() => generateLinkToken()}
onConnectSuccess={handleSuccess}
onConnectError={(err) => console.error(err)}
integrationName="coinbase"
buttonLabel="Connect Coinbase"
buttonHeight={48}
style={{ borderRadius: 10, backgroundColor: "#0052FF" }}
/>
{/* Re-authorize with stored access token */}
{accessToken && (
<KryptosConnectButton
generateLinkToken={() => generateLinkToken(accessToken)}
onConnectSuccess={handleSuccess}
onConnectError={(err) => console.error(err)}
buttonLabel="Continue with Access Token"
buttonHeight={52}
/>
)}
</>
);
}
User Flow Variations
The SDK handles two flows based on the isAuthorized flag returned from generateLinkToken:
Flow 1: New User (isAuthorized: false or undefined)
press → AUTH → INTEGRATION → onConnectSuccess({ public_token })
Exchange public_token server-side for a long-lived access_token.
Flow 2: Returning User (isAuthorized: true)
press → INTEGRATION → onConnectSuccess(null)
Pass stored access_token in the link-token request body and return isAuthorized: true. No new token is issued.
KryptosConnect.init Config
| Key | Type | Required | Description |
|---|---|---|---|
clientId | string | Yes | Your Kryptos client ID. |
appName | string | Yes | Displayed in the connect UI header. |
appLogo | string | No | URI to your app logo shown in the connect UI. |
walletConnectProjectId | string | No | Required if using WalletConnect. |
theme | "light" | "dark" | "auto" | No | UI theme. Default "light". |
language | string | No | UI language. Supported: en fr de pt sv es pl it. |
authMethods | ("email" | "anonymous")[] | No | Auth methods shown. Default: both. |
cssVars | Record<string, string> | No | Override --kc-* CSS variables in the connect UI. --kc-primary and --kc-primary-text also apply to the native button. |
Restricting Auth Methods
// Email only
KryptosConnect.init({
clientId: "your-client-id",
appName: "My App",
authMethods: ["email"],
});
// Anonymous only
KryptosConnect.init({
clientId: "your-client-id",
appName: "My App",
authMethods: ["anonymous"],
});
Setting the Language
| Code | Language |
|---|---|
"en" | English |
"fr" | French |
"de" | German |
"pt" | Portuguese |
"sv" | Swedish |
"es" | Spanish |
"pl" | Polish |
"it" | Italian |
KryptosConnectButton Props
| Prop | Type | Required | Description |
|---|---|---|---|
generateLinkToken | () => Promise<{ link_token: string; isAuthorized?: boolean }> | Yes | Called on press. Return isAuthorized: true to skip auth for existing users. |
onConnectSuccess | (data: UserConsent | null) => void | Yes | Called on success. data is null when isAuthorized was true. |
onConnectError | (error: Error) => void | Yes | Called on error or dismissal. |
integrationName | string | No | Skip the integration list and open a specific integration directly. |
buttonLabel | string | No | Button text. |
buttonHeight | number | No | Button height in dp. Default 56. |
extraConfig | Record<string, unknown> | No | Per-button config overrides merged onto the global config. Pass prefill here to pre-populate integration form fields. |
style | StyleProp<ViewStyle> | No | Style for the button. backgroundColor overrides --kc-primary for that button. |
Pre-filling Integration Forms
Pass a prefill object inside extraConfig to pre-populate the integration form when the user reaches the connection step. All fields are optional — pass only the ones you have.
| Field | Type | Description |
|---|---|---|
prefill.address | string | Wallet or blockchain address. Triggers chain auto-detect for EVM wallets. |
prefill.apiKey | string | API key for exchange or API-based integrations. |
prefill.secretKey | string | Secret key for integrations that require one. |
prefill.password | string | Password for integrations that require one. |
prefill.accountName | string | Account name for account-based integrations. |
// Pre-fill a wallet address — chains are auto-detected
<KryptosConnectButton
generateLinkToken={generateLinkToken}
onConnectSuccess={handleSuccess}
onConnectError={(err) => console.error(err)}
integrationName="ethereum"
buttonLabel="Connect Wallet"
extraConfig={{ prefill: { address: "0x1234567890123456789012345678901234567890" } }}
/>
// Pre-fill API credentials for an exchange
<KryptosConnectButton
generateLinkToken={generateLinkToken}
onConnectSuccess={handleSuccess}
onConnectError={(err) => console.error(err)}
integrationName="binance"
buttonLabel="Connect Binance"
extraConfig={{ prefill: { apiKey: "user-api-key", secretKey: "user-secret-key" } }}
/>
Prefilled values populate the form as editable defaults — the user can still change them before submitting. For EVM wallets, providing an address automatically triggers chain detection and pre-selects all detected chains.
Theming & Customization
Theme the connect UI by passing cssVars to KryptosConnect.init. The connect UI runs inside a WebView, so global stylesheet overrides have no effect. --kc-primary and --kc-primary-text also apply to the native button's background and label.
KryptosConnect.init({
clientId: "your-client-id",
appName: "My App",
cssVars: {
"--kc-primary": "#6366f1",
"--kc-primary-hover": "#4f46e5",
"--kc-primary-text": "#ffffff",
"--kc-border-focus": "#6366f1",
},
});
For per-button overrides, use the style prop. backgroundColor takes precedence over --kc-primary for that button only:
<KryptosConnectButton
generateLinkToken={generateLinkToken}
onConnectSuccess={handleSuccess}
onConnectError={(err) => console.error(err)}
buttonLabel="Connect Coinbase"
buttonHeight={48}
style={{ backgroundColor: "#0052FF", borderRadius: 10 }}
/>
For the complete variable reference, see Theming & Customization.
Direct Integration Flow
The integrationName prop directs users to a specific integration, bypassing the integration selection page.
Fetch available integration IDs from the public Kryptos API (see Public Endpoints - Integrations).
<KryptosConnectButton
generateLinkToken={generateLinkToken}
onConnectSuccess={handleSuccess}
onConnectError={(err) => console.error(err)}
integrationName="binance"
buttonLabel="Connect Binance"
/>
The integrationName value must match an integration ID from the supported providers list.
Platform Requirements
| Platform | Minimum Version |
|---|---|
| iOS | 12.0+ |
| Android | API 21+ (Android 5.0+) |
| React Native | 0.60+ |
| Expo SDK | 48+ |
Features
- Cross-Platform: Single codebase for iOS and Android
- Expo Support: Works with Expo and React Native CLI
- WalletConnect v2: Built-in WalletConnect integration
- Theming: Light, dark, and auto theme support with CSS variable customization
- TypeScript: Full TypeScript support
Next steps
- Backend Implementation — set up your server-side integration
- Examples — complete integration examples
- Web SDK — integrate Kryptos Connect in web applications