Skip to Content

Setup

The starter requires a few pieces of infrastructure before the SDK hooks can run: polyfills for React Native’s missing Web APIs, a WatermelonDB database, and a Privy authentication provider.

Polyfills

React Native doesn’t ship Web Streams or TextDecoderStream, both of which the SDK needs for SSE streaming. The app’s entrypoint installs these before anything else loads.

// Import required polyfills first // IMPORTANT: These polyfills must be installed in this order import "react-native-get-random-values"; import "@ethersproject/shims"; import { Buffer } from "buffer"; import { LogBox } from "react-native"; global.Buffer = Buffer; // Suppress Privy embedded wallet timeout error (non-blocking SDK issue) LogBox.ignoreLogs(["Ping reached timeout"]); // Web Streams polyfill for SSE streaming (TextDecoderStream, TransformStream, etc.) import { ReadableStream, TransformStream } from "web-streams-polyfill"; if (typeof globalThis.ReadableStream === "undefined") { globalThis.ReadableStream = ReadableStream; } if (typeof globalThis.TransformStream === "undefined") { globalThis.TransformStream = TransformStream; } // SDK polyfills (TextDecoderStream, etc.) import "@anuma/sdk/polyfills";

Order matters — react-native-get-random-values and @ethersproject/shims must come first, then the Web Streams polyfill, then @anuma/sdk/polyfills which provides TextDecoderStream.

Database

The SDK persists conversations and messages in WatermelonDB. Create a single database instance using the schema, migrations, and model classes exported from @anuma/sdk/expo.

const adapter = new SQLiteAdapter({ schema: sdkSchema, migrations: sdkMigrations, dbName: "anuma_chat", jsi: true, onSetUpError: (error) => { console.error("Database setup error:", error); }, }); export const database = new Database({ adapter, modelClasses: sdkModelClasses, });

The jsi: true flag enables the JSI SQLite adapter for native performance. The database is named anuma_chat and is shared across the app via a direct import.

Authentication

Privy handles authentication and provides an identity token that the SDK uses for API requests. Wrap your app in PrivyProvider with your app and client IDs from the Expo config.

export default function RootLayout() { return ( <GestureHandlerRootView style={{ flex: 1 }}> <PrivyProvider appId={Constants.expoConfig?.extra?.privyAppId} clientId={Constants.expoConfig?.extra?.privyClientId} config={{ embedded: { ethereum: { createOnLogin: "users-without-wallets", }, solana: { createOnLogin: "off", }, }, }} > <ErrorBoundary> <AppContent /> </ErrorBoundary> </PrivyProvider> </GestureHandlerRootView> ); }

The useIdentityToken hook from Privy returns a getIdentityToken function that the SDK’s useChatStorage and useModels hooks accept as getToken.

Last updated on