@kryptos_connect/web-sdk
v1.0.22
Published
Kryptos simplifies Web3 finance for users globally with a comprehensive suite of solutions that include accounting, portfolio management, and tax reporting. Supporting over 2000+ DeFi protocols, 100+ exchanges and wallets, and 50+ blockchains, Kryptos is
Readme
Kryptos Connect
A modern React component library for seamless Kryptos integration with built-in authentication, theme support, and wallet connectivity. Connect your users to the complete Web3 finance ecosystem with support for 5000+ DeFi protocols, 200+ exchanges and wallets, and 100+ blockchains.
Installation
npm install @kryptos_connect/web-sdkPrerequisites
Before using this package, you'll need:
- Client ID: Obtain from Kryptos Developer Portal
- WalletConnect Project ID: Get from WalletConnect Cloud
Quick Start
1. Import Styles
Import the package styles in your main app file:
import "@kryptos_connect/web-sdk/dist/styles/index.css";2. Wrap Your App with Provider
Wrap your application with KryptosConnectProvider:
import { KryptosConnectProvider } from "@kryptos_connect/web-sdk";
import "@kryptos_connect/web-sdk/dist/styles/index.css";
function App() {
return (
<KryptosConnectProvider
config={{
appName: "My DeFi App",
appLogo: "https://yourapp.com/logo.png",
clientId: "your-kryptos-client-id",
theme: "light", // or "dark"
walletConnectProjectId: "your-walletconnect-project-id",
}}
>
{/* Your app components */}
</KryptosConnectProvider>
);
}Configuration Options
| Property | Type | Required | Description |
| ------------------------ | --------------------------- | -------- | --------------------------------------------------- |
| appName | string | Yes | Your application name |
| appLogo | React.ReactNode \| string | No | Your app logo (URL string or React component) |
| clientId | string | Yes | Your Kryptos client ID |
| theme | "light" \| "dark" | No | Default theme mode (defaults to "light" if not set) |
| walletConnectProjectId | string | Yes | Your WalletConnect project ID |
API Reference
KryptosConnectButton
The main button component that triggers the Kryptos connection flow. It handles the full authentication and wallet connection process.
Basic Usage
import { KryptosConnectButton } from "@kryptos_connect/web-sdk";
function MyComponent() {
return (
<KryptosConnectButton
generateLinkToken={async () => {
// Call your backend API to generate a link token
const response = await fetch("/api/kryptos/create-link-token", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
// Optional: Include access_token for authenticated users
// access_token: userAccessToken
}),
});
const data = await response.json();
// Return link_token and isAuthorized flag
return {
link_token: data.link_token,
isAuthorized: data.isAuthorized, // Pass true if access_token was provided
};
}}
onSuccess={(userConsent) => {
console.log("Connection successful:", userConsent);
// For new users, exchange the public token for an access token
// For authorized users, userConsent might be null
if (userConsent?.public_token) {
exchangePublicToken(userConsent.public_token);
}
}}
onError={(error) => {
console.error("Connection failed:", error);
}}
>
Connect to Kryptos
</KryptosConnectButton>
);
}User Flow Variations
The SDK automatically handles two different user flows based on the isAuthorized flag returned from generateLinkToken:
Flow 1: New User (isAuthorized: false or undefined)
INIT → Connect → INTEGRATION → STATUS- User connects; an account is created for them on the backend
- User selects integrations to connect
- Returns
public_tokeninonSuccesscallback
Flow 2: Authenticated User (isAuthorized: true)
INIT → INTEGRATION → STATUS- Skips Connect (an account already exists for the user on the backend)
- User directly selects integrations
- Returns
nullinonSuccesscallback (no new token needed)
Implementation Example:
generateLinkToken={async () => {
const user = getCurrentUser(); // Your auth logic
const response = await fetch("/api/kryptos/create-link-token", {
method: "POST",
body: JSON.stringify({
// Include access_token if user is logged in
access_token: user?.kryptosAccessToken || undefined,
}),
});
const data = await response.json();
return {
link_token: data.link_token,
// isAuthorized will be true if access_token was valid
isAuthorized: !!user?.kryptosAccessToken,
};
}}Direct Integration Flow
You can use the integrationName prop to direct users to a specific integration, bypassing the general integration selection page. This is useful when you want to provide dedicated buttons for specific exchanges or wallets.
Getting Supported Integration IDs:
Fetch available integration IDs from the public Kryptos API endpoint:
GET {BASE_URL}/integrations/public/listUsage Example:
// Direct connection to a specific integration (e.g., Binance)
<KryptosConnectButton
generateLinkToken={generateLinkToken}
integrationName="binance"
onSuccess={(userConsent) => {
console.log("Binance connected:", userConsent);
}}
>
Connect Binance Account
</KryptosConnectButton>
// Or without children (uses default button with custom text)
<KryptosConnectButton
generateLinkToken={generateLinkToken}
integrationName="metamask"
onSuccess={(userConsent) => {
console.log("MetaMask connected:", userConsent);
}}
// Button will display: "Connect Metamask Account"
/>Use Cases:
Dedicated Integration Buttons: Create separate buttons for popular integrations
<KryptosConnectButton integrationName="binance"> Connect Binance </KryptosConnectButton> <KryptosConnectButton integrationName="coinbase"> Connect Coinbase </KryptosConnectButton> <KryptosConnectButton integrationName="metamask"> Connect MetaMask </KryptosConnectButton>Contextual Integration: Direct users to relevant integrations based on their context
// In an exchange-focused feature <KryptosConnectButton integrationName="kraken"> Add Kraken Account </KryptosConnectButton>Onboarding Flows: Guide users to connect specific integrations during onboarding
// Step 1: Connect wallet <KryptosConnectButton integrationName="metamask"> Connect Your Wallet </KryptosConnectButton> // Step 2: Connect exchange <KryptosConnectButton integrationName="binance"> Connect Your Exchange </KryptosConnectButton>
Note: The integrationName value must match an integration ID from the supported providers list. An invalid ID will result in an error.
Custom Styling Example
<KryptosConnectButton
generateLinkToken={createLinkToken}
onSuccess={(userConsent) => {
console.log("Success:", userConsent);
exchangePublicToken(userConsent?.public_token);
}}
onError={(error) => console.error("Error:", error)}
className="my-custom-class"
style={{
width: "100%",
padding: "12px 24px",
fontSize: "16px",
}}
>
🔐 Connect Your Wallet
</KryptosConnectButton>Props
| Property | Type | Required | Description |
| ------------------- | --------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| generateLinkToken | () => Promise<{ link_token: string; isAuthorized?: boolean }> | Yes | Function that returns link token and authorization status. isAuthorized: true skips Connect for authenticated users (account already exists for them on the backend) |
| onSuccess | (data: UserConsent \| null) => void | No | Callback invoked when connection succeeds. Receives public_token for new users, null for authorized users |
| onError | (error: Error) => void | No | Callback invoked when connection fails |
| integrationName | string | No | Integration ID from the supported providers list. When provided, skips the integration list and goes directly to the specific integration |
| children | React.ReactNode | No | Button text or content. Defaults to "Connect with Kryptos", or "Connect using {integrationName}" when integrationName is set |
| className | string | No | Custom CSS class name |
| style | React.CSSProperties | No | Inline styles |
TypeScript Types
interface KryptosConnectButtonProps {
generateLinkToken: () => Promise<{
link_token: string;
isAuthorized?: boolean;
}>;
onSuccess?: (data: UserConsent | null) => void;
onError?: (error: Error) => void;
integrationName?: string; // Integration ID from the supported providers list
children?: React.ReactNode;
className?: string;
style?: React.CSSProperties;
}
interface UserConsent {
public_token: string;
// Additional consent data
}
// Note: onSuccess receives:
// - UserConsent with public_token for new users (isAuthorized: false)
// - null for authenticated users (isAuthorized: true)Backend Integration
You need to implement two backend endpoints.
Base URLs
| Environment | URL |
| -------------- | -------------------------------- |
| Production | https://connect-api.kryptos.io |
1. Create Link Token
A link token can be created in two ways: to authenticate an existing user or to create a new session.
| Approach | When to use | Jump to |
| ------------------------- | -------------------------------- | ---------------------------------------- |
| Option A | New user, no access token | Create link token without access_token |
| Option B | Returning user, has access token | Create link token with access_token |
Option A: Without Access Token (New User)
Use this approach for new users or when you want an account to be created for the user on the backend:
// Example: Node.js/Express
app.post("/api/kryptos/create-link-token", async (req, res) => {
try {
const response = await fetch(`${KRYPTOS_BASE_URL}/link-token`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Client-Id": YOUR_CLIENT_ID,
"X-Client-Secret": YOUR_CLIENT_SECRET,
},
body: JSON.stringify({
scopes:
"openid profile offline_access email portfolios:read transactions:read integrations:read tax:read accounting:read reports:read workspace:read users:read",
}),
});
const data = await response.json();
res.json({
link_token: data.link_token,
isAuthorized: false, // No access token provided
});
} catch (error) {
res.status(500).json({ error: "Failed to create link token" });
}
});User Experience Flow:
- User clicks "Connect to Kryptos"
- User connects; an account is created for them on the backend
- User selects integrations
onSuccessreceivespublic_tokento exchange
Option B: With Access Token (Authenticated User)
Use this approach for existing authenticated users (an account already exists for them on the backend):
// Example: Node.js/Express
app.post("/api/kryptos/create-link-token", async (req, res) => {
try {
// Get the user's stored access token from your database
const userAccessToken = await getUserAccessToken(req.user.id);
const response = await fetch(`${KRYPTOS_BASE_URL}/link-token`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Client-Id": YOUR_CLIENT_ID,
"X-Client-Secret": YOUR_CLIENT_SECRET,
},
body: JSON.stringify({
scopes:
"openid profile offline_access integrations:read integrations:write",
access_token: userAccessToken, // Pass the user's access token
}),
});
const data = await response.json();
res.json({
link_token: data.link_token,
isAuthorized: true, // Access token provided, user is authenticated
});
} catch (error) {
res.status(500).json({ error: "Failed to create link token" });
}
});User Experience Flow:
- User clicks "Connect to Kryptos"
- Integration selection is shown directly (account already exists for the user on the backend)
- User selects integrations
onSuccessreceivesnull(no new token needed)
Choosing the Right Approach
Implementation: Option A (new user, no token) · Option B (authenticated user, with token)
| Scenario | Use Option | isAuthorized | User Flow (UI) | Returns public_token |
| ------------------------------------------ | ---------------------------------- | ------------ | ----------------------------------------------------------- | -------------------- |
| First-time user connecting to Kryptos | A (Without Token) | false | Connect → INTEGRATION (account created for user on backend) | ✅ Yes |
| User doesn't have an access token yet | A (Without Token) | false | Connect → INTEGRATION (account created for user on backend) | ✅ Yes |
| Returning user with stored access token | B (With Token) | true | INTEGRATION only (account already exists for user) | ❌ No |
| Adding more integrations for existing user | B (With Token) | true | INTEGRATION only (account already exists for user) | ❌ No |
Important Notes:
- After the first successful connection (Option A), store the
access_tokenyou receive from the token exchange - Use the stored
access_tokenfor subsequent connections (Option B) to provide a seamless experience - For authorized users (
isAuthorized: true), theonSuccesscallback receivesnullinstead of apublic_token - Authorized users go directly to integration selection (an account already exists for them on the backend)
2. Exchange Public Token
After a successful connection, exchange the public_token for an access_token. Important: Store this access_token securely in your database. You will use it to create link tokens for authenticated users (Option B above).
// Example: Node.js/Express
app.post("/api/kryptos/exchange-token", async (req, res) => {
try {
const { public_token } = req.body;
const response = await fetch(`${KRYPTOS_BASE_URL}/token/exchange`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Client-Id": YOUR_CLIENT_ID,
"X-Client-Secret": YOUR_CLIENT_SECRET,
},
body: JSON.stringify({
public_token,
}),
});
const data = await response.json();
// IMPORTANT: Store the access_token securely in your database
// You'll need this token to:
// 1. Create authenticated link tokens (account already exists for user on backend)
// 2. Make API calls on behalf of the user
await saveUserAccessToken(req.user.id, data.access_token);
res.json({ success: true });
} catch (error) {
res.status(500).json({ error: "Failed to exchange token" });
}
});Complete Integration Flow:
First Connection (New User -
isAuthorized: false):Frontend → generateLinkToken() [returns { link_token, isAuthorized: false }] → SDK Flow: INIT → Connect → INTEGRATION → STATUS → User connects; an account is created for them on the backend → User connects integrations → onSuccess receives { public_token: "..." } → Backend exchanges public_token for access_token → Store access_token in database ← IMPORTANTSubsequent Connections (Returning User -
isAuthorized: true):Frontend → generateLinkToken() [returns { link_token, isAuthorized: true }] → SDK Flow: INIT → INTEGRATION → STATUS (skip Connect) → User directly sees integrations (account already exists for them on the backend) → User connects more integrations → onSuccess receives null (no new token needed) → Integrations are added to user's existing account
Customization
The library uses CSS variables and unique kc- prefixed classes for easy customization without conflicts.
See CUSTOMIZATION_GUIDE.md for detailed CSS customization options.
Quick Theme Customization
Override CSS variables to customize the look and feel:
/* custom-theme.css */
:root {
--kc-primary: #8b5cf6;
--kc-primary-hover: #7c3aed;
--kc-bg-primary: #ffffff;
--kc-text-primary: #000000;
--kc-border: #e5e7eb;
--kc-border-radius: 8px;
}
[data-kc-theme="dark"] {
--kc-bg-primary: #1a1a1a;
--kc-text-primary: #ffffff;
--kc-border: #404040;
}Import your custom styles after the package styles:
import "@kryptos_connect/web-sdk/dist/styles/index.css";
import "./custom-theme.css";Custom Component Styling
<KryptosConnectButton
className="my-custom-button"
style={{
background: "linear-gradient(to right, #667eea, #764ba2)",
borderRadius: "12px",
}}
>
Connect Wallet
</KryptosConnectButton>Framework Support
Next.js
Works with both Pages Router and App Router:
// app/layout.tsx (App Router)
import { KryptosConnectProvider } from "@kryptos_connect/web-sdk";
import "@kryptos_connect/web-sdk/dist/styles/index.css";
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
<KryptosConnectProvider config={config}>
{children}
</KryptosConnectProvider>
</body>
</html>
);
}React
// main.tsx or index.tsx
import React from "react";
import ReactDOM from "react-dom/client";
import { KryptosConnectProvider } from "@kryptos_connect/web-sdk";
import "@kryptos_connect/web-sdk/dist/styles/index.css";
import App from "./App";
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<KryptosConnectProvider config={config}>
<App />
</KryptosConnectProvider>
</React.StrictMode>,
);TypeScript Support
This package provides full TypeScript support with type definitions.
import type {
KryptosConnectButtonProps,
KryptosConnectProviderProps,
UserConsent,
} from "@kryptos_connect/web-sdk";Browser Support
- Chrome/Edge (latest)
- Firefox (latest)
- Safari (latest)
- Mobile browsers (iOS Safari, Chrome Mobile)
Support
- 📧 Email: [email protected]
- 📚 Documentation: https://docs.kryptos.io
- 💬 Discord: Join our community
- 🐛 Issues: GitHub Issues
Contributing
Contributions are welcome! Please read our Contributing Guide for details on our code of conduct and the process for submitting pull requests.
License
MIT © Kryptos
Made with ❤️ by the Kryptos team
