npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kryptos_connect/mobile-sdk

v1.0.6

Published

Kryptos Connect Mobile SDK for React Native - Simplifies Web3 finance for mobile apps with support for 5000+ DeFi protocols, 200+ exchanges and wallets, and 100+ blockchains. Works with both Expo and React Native CLI.

Readme

@kryptos_connect/mobile-sdk

Kryptos Connect Mobile SDK for React Native – works with Expo and React Native CLI. 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

Using npm

npm install @kryptos_connect/mobile-sdk react-native-svg

Using yarn

yarn add @kryptos_connect/mobile-sdk react-native-svg

For Expo

npx expo install @kryptos_connect/mobile-sdk react-native-svg

iOS (React Native CLI only)

cd ios && pod install

Prerequisites

Before using this package, you'll need:

  1. Client ID: Obtain from Kryptos Developer Portal
  2. WalletConnect Project ID: Get from WalletConnect Cloud (optional, for wallet connectivity)

Core library (all-in-one)

For Expo or bare React Native, install the core WalletConnect/AppKit deps together:

npx expo install @reown/appkit-react-native @react-native-async-storage/async-storage react-native-get-random-values react-native-svg @react-native-community/netinfo @walletconnect/react-native-compat react-native-safe-area-context expo-application

Platform Setup

Expo (managed or prebuild)

  • Install the required peer deps (AppKit + WalletConnect) in one go:

    npx expo install @kryptos_connect/mobile-sdk react-native-svg @react-native-async-storage/async-storage @react-native-community/netinfo react-native-get-random-values @walletconnect/react-native-compat @reown/appkit-react-native @reown/appkit-ethers-react-native expo-application
  • Expo SDK 53+: add babel.config.js to enable unstable_transformImportMeta for valtio:

    // babel.config.js
    module.exports = function (api) {
      api.cache(true);
      return {
        presets: [["babel-preset-expo", { unstable_transformImportMeta: true }]],
      };
    };

React Native CLI

  • Install peer deps:
    npm install @kryptos_connect/mobile-sdk react-native-svg @react-native-async-storage/async-storage @react-native-community/netinfo react-native-get-random-values @walletconnect/react-native-compat @reown/appkit-react-native @reown/appkit-ethers-react-native viem
  • iOS: cd ios && pod install.

Quick Start

1. Wrap your app with the Provider

import { KryptosConnectProvider } from "@kryptos_connect/mobile-sdk";

const config = {
  appName: "Your App Name",
  appLogo: "https://your-logo-url.com/logo.png", // or require('./logo.png')
  clientId: "your-client-id",
  theme: "light", // or 'dark'
  walletConnectProjectId: "your-walletconnect-project-id",
};

export default function App() {
  return (
    <KryptosConnectProvider config={config}>
      <YourApp />
    </KryptosConnectProvider>
  );
}

Configuration Options

| Property | Type | Required | Description | | ------------------------ | ------------------------------------------ | -------- | --------------------------------------------------------------------------- | | appName | string | Yes | Your application name | | appLogo | React.ReactNode \| string \| ImageSource | No | Your app logo (URL, require(), or React Native image source) | | clientId | string | Yes | Your Kryptos client ID | | theme | "light" \| "dark" | No | Default theme mode (defaults to "light" if not set) | | walletConnectProjectId | string | No | Your WalletConnect project ID (enables built-in AppKit / wallet connection) |

2. Add the Connect Button

import { KryptosConnectButton } from "@kryptos_connect/mobile-sdk";

function YourComponent() {
  const generateLinkToken = async () => {
    // Call your backend API to generate a link token
    const response = await fetch("https://your-api.com/generate-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
    };
  };

  const handleSuccess = (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);
    }
  };

  const handleError = (error) => {
    console.error("Connection failed:", error);
  };

  return (
    <KryptosConnectButton
      generateLinkToken={generateLinkToken}
      onSuccess={handleSuccess}
      onError={handleError}
    />
  );
}

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
  • INIT (Connect): Fetches link token and initializes the session & an account is created for them on the backend
  • INTEGRATION: User selects and connects integrations (wallets, exchanges, blockchains)
  • STATUS: Success or error result; returns public_token in onSuccess when consent is given, or null when user was already authorized

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 null in onSuccess callback (no new token needed)

Implementation Example

const generateLinkToken = async () => {
  const user = getCurrentUser(); // Your auth logic

  const response = await fetch("/api/kryptos/create-link-token", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    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,
  };
};

WalletConnect / Reown AppKit configuration

Passing a walletConnectProjectId to KryptosConnectProvider enables the built-in AppKit (WalletConnect v2) flow used by the WalletConnectComponent:

import "@walletconnect/react-native-compat";
import "react-native-get-random-values";
import { KryptosConnectProvider } from "@kryptos_connect/mobile-sdk";

const config = {
  appName: "Your App",
  appLogo: "https://your-logo.png",
  clientId: "<kryptos-client-id>",
  walletConnectProjectId: "<walletconnect-cloud-project-id>",
};

export default function App() {
  return (
    <KryptosConnectProvider config={config}>
      <YourApp />
    </KryptosConnectProvider>
  );
}

Behind the scenes the SDK creates an AppKit instance (see src/wallet-connect/AppKitConfig.ts) with Ethers adapter, common EVM chains, and persistent storage. If you need to customize chains, metadata, or features, copy that file into your app and adjust it following the Reown AppKit guide: https://docs.reown.com/appkit/overview

Environment Configuration

You can configure different environments (dev/prod) by passing the baseUrl option:

import { KryptosConnectProvider } from "@kryptos_connect/mobile-sdk";

// Development Environment
const devConfig = {
  appName: "Your App",
  clientId: "your-client-id",
  theme: "light",
  walletConnectProjectId: "your-project-id",
};

// Production Environment
const prodConfig = {
  appName: "Your App",
  clientId: "your-client-id",
  theme: "light",
  walletConnectProjectId: "your-project-id",
};

export default function App() {
  const config = __DEV__ ? devConfig : prodConfig;

  return (
    <KryptosConnectProvider config={config}>
      <YourApp />
    </KryptosConnectProvider>
  );
}

3. Custom Button (Optional)

You can also use a custom button:

import { KryptosConnectButton } from "@kryptos_connect/mobile-sdk";
import { Text, View, StyleSheet } from "react-native";

function CustomButton() {
  return (
    <KryptosConnectButton
      generateLinkToken={generateLinkToken}
      onSuccess={handleSuccess}
      onError={handleError}
    >
      <View style={styles.customButton}>
        <Text style={styles.customText}>🔐 Connect Your Wallet</Text>
      </View>
    </KryptosConnectButton>
  );
}

const styles = StyleSheet.create({
  customButton: {
    backgroundColor: "#00C693",
    paddingVertical: 12,
    paddingHorizontal: 24,
    borderRadius: 8,
    alignItems: "center",
  },
  customText: {
    color: "#FFFFFF",
    fontSize: 16,
    fontWeight: "600",
  },
});

Direct Integration Flow

You can use the integrationName prop to direct users to a specific integration, bypassing the general integration selection. Useful for dedicated buttons for specific exchanges or wallets.

Getting supported integration IDs: Fetch from the public Kryptos API:

GET {BASE_URL}/integrations/public/list

Usage 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>

// Default button text when integrationName is set: "Connect {Integration} Account"
<KryptosConnectButton
  generateLinkToken={generateLinkToken}
  integrationName="metamask"
  onSuccess={(userConsent) => console.log("MetaMask connected:", userConsent)}
/>

Use cases: Dedicated integration buttons, contextual integration (e.g. exchange-focused screens), onboarding steps (e.g. connect wallet then exchange). The integrationName value must match an integration ID from the supported providers list.

API Reference

KryptosConnectProvider

The provider component that wraps your app and provides the Kryptos context.

Props

| Prop | Type | Required | Description | | ---------- | --------------- | -------- | -------------------- | | config | KryptosConfig | Yes | Configuration object | | children | ReactNode | Yes | Child components |

KryptosConfig

type KryptosConfig = {
  appName: string; // Your app name
  appLogo?: ReactNode | string | ImageSourcePropType; // Logo URL, React Native Image source, or require()
  theme?: "light" | "dark"; // Theme mode (default: 'light')
  clientId: string; // Your Kryptos client ID
  walletConnectProjectId?: string; // Optional WalletConnect project ID
};

KryptosConnectButton

The main button component that triggers the connection flow.

Props

| Prop | Type | Required | Description | | ------------------- | --------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | generateLinkToken | () => Promise<{ link_token: string; isAuthorized?: boolean }> | Yes | Function that returns link token and authorization status. isAuthorized: true indicates the user is already authorized (consent API may be skipped; onSuccess receives null) | | 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 that integration | | children | ReactNode | No | Custom button content. Defaults to "Connect With Kryptos", or "Connect {Integration} Account" when integrationName is set | | style | ViewStyle | No | Custom button container style | | textStyle | TextStyle | No | Custom button text style |

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?: ReactNode;
  style?: ViewStyle;
  textStyle?: TextStyle;
}

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)

TypeScript

The package includes type definitions. You can import types from the package:

import type {
  KryptosConnectButtonProps,
  KryptosConfig,
  UserConsent,
} from "@kryptos_connect/mobile-sdk";

Backend Integration

You need to implement two backend endpoints. The same API is used for web and mobile.

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 | | -------- | -------------------------------- | | Option A | New user, no access token | | Option B | Returning user, has access token |

Option A: Without Access Token (New/Anonymous User)

Use this approach for new users (no access token):

// 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:

  1. User taps "Connect to Kryptos"
  2. Connect (INIT) screen initializes, then integration selection is shown
  3. User selects and connects integrations
  4. onSuccess receives public_token to exchange

Option B: With Access Token (Authenticated User)

Use this approach for existing authenticated users:

// 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:

  1. User taps "Connect to Kryptos"
  2. Connect (INIT) then integration selection is shown
  3. User selects integrations; onSuccess receives null (no new token needed)

Choosing the Right Approach

| Scenario | Use Option | isAuthorized | User Flow (mobile) | Returns public_token | | ------------------------------------------ | ----------------- | ------------ | -------------------------------------------------------------------------- | -------------------- | | First-time user connecting to Kryptos | A (Without Token) | false | INIT → Connect(account created for user on backend) → INTEGRATION → STATUS | ✅ Yes | | User doesn't have an access token yet | A (Without Token) | false | INIT → Connect(account created for user on backend) → INTEGRATION → STATUS | ✅ Yes | | Returning user with stored access token | B (With Token) | true | INIT → INTEGRATION → STATUS | ❌ No | | Adding more integrations for existing user | B (With Token) | true | INIT → INTEGRATION → STATUS | ❌ No |

Important notes:

  • After the first successful connection (Option A), store the access_token from the token exchange.
  • Use the stored access_token for subsequent connections (Option B).
  • For authorized users (isAuthorized: true), onSuccess receives null.

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 (Option B)
    // 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:

  1. First connection (new user – isAuthorized: false):

    App → generateLinkToken() [returns { link_token, isAuthorized: false }]
    → SDK: INIT → Connect → INTEGRATION → STATUS
    → User selects and connects integrations
    → onSuccess receives { public_token }
    → Backend exchanges public_token for access_token
    → Store access_token in database ← IMPORTANT
  2. Subsequent connections (returning user – isAuthorized: true):

    App → generateLinkToken() [returns { link_token, isAuthorized: true }]
    → SDK: INIT → INTEGRATION → STATUS
    → User sees integrations directly → connects more
    → onSuccess receives null
    → Integrations added to existing account

Supported Platforms

  • ✅ iOS 12.0+
  • ✅ Android 5.0+ (API 21+)
  • ✅ Expo SDK 48+
  • ✅ React Native 0.60+

Peer Dependencies

{
  "react": ">=16.8.0",
  "react-native": ">=0.60.0",
  "react-native-svg": ">=12.0.0"
}

Support

License

MIT © Kryptos


Made with ❤️ by the Kryptos team