> ## Documentation Index
> Fetch the complete documentation index at: https://docs.spark.money/llms.txt
> Use this file to discover all available pages before exploring further.

# React Native SDK

React Native SDK for iOS and Android wallet apps. Requires Xcode/iOS Simulator or Android Studio.

<Frame className="chill">
  <img src="https://mintcdn.com/lightspark/tx4TRJSdzgUfv6x3/images/wallets/rn-spark.png?fit=max&auto=format&n=tx4TRJSdzgUfv6x3&q=85&s=adb59c4bdda8bb09cc72a82823e4ddcc" alt="React Native SDK" width="1920" height="1080" data-path="images/wallets/rn-spark.png" />
</Frame>

**Requirements:** React `>=18.2.0`, React Native `>=0.71.0`, iOS `>=12.0`

<Card title="Example App" icon="github" href="https://github.com/lightsparkdev/spark/tree/main/sdks/js/examples/spark-react-native-app">
  Complete React Native example with wallet, transfers, and Lightning
</Card>

## Getting Started

To get started, follow the steps below.

<Steps>
  <Step title="Install SDK">
    Install the Spark SDK packages using your package manager of choice.

    <CodeGroup>
      ```bash npm theme={null}
      npm install @buildonspark/spark-sdk
      ```

      ```bash yarn theme={null}
      yarn add @buildonspark/spark-sdk
      ```

      ```bash pnpm theme={null}
      pnpm add @buildonspark/spark-sdk
      ```
    </CodeGroup>
  </Step>

  <Step title="Add Required Polyfills">
    Install the required polyfills for React Native compatibility.

    <CodeGroup>
      ```bash npm theme={null}
      npm install react-native-get-random-values @azure/core-asynciterator-polyfill buffer text-encoding
      ```

      ```bash yarn theme={null}
      yarn add react-native-get-random-values @azure/core-asynciterator-polyfill buffer text-encoding
      ```

      ```bash pnpm theme={null}
      pnpm add react-native-get-random-values @azure/core-asynciterator-polyfill buffer text-encoding
      ```
    </CodeGroup>
  </Step>

  <Step title="Import Polyfills at App Entry">
    <Warning>
      **Critical:** Import polyfills at the very top of your `index.js` file, BEFORE importing your app or any other modules. The crypto module will fail to load if this order is wrong.
    </Warning>

    ```js index.js theme={null}
    // These MUST be the first imports in your app entry point
    import 'react-native-get-random-values';
    import '@azure/core-asynciterator-polyfill';
    import { Buffer } from 'buffer';
    global.Buffer = Buffer;

    // Now import your app
    import { AppRegistry } from 'react-native';
    import App from './App';
    import { name as appName } from './app.json';

    AppRegistry.registerComponent(appName, () => App);
    ```
  </Step>

  <Step title="Install Native Modules (iOS)">
    For iOS, you must install the native module dependencies. This step is required for bare React Native apps.

    ```bash theme={null}
    cd ios && pod install && cd ..
    ```

    <Note>
      If you skip this step, you'll see errors like `Cannot read property 'decryptEcies' of null` when initializing the wallet.
    </Note>
  </Step>

  <Step title="Setup Wallet">
    Create a wallet instance that will be used to interact with the Spark network.

    ```tsx wallet.jsx theme={null}
    import { SparkWallet } from "@buildonspark/spark-sdk";

    export const initializeWallet = async () => {
          const { wallet, mnemonic } = await SparkWallet.initialize({
            mnemonicOrSeed: "optional-mnemonic-or-seed",
            accountNumber: 0, // optional
            options: {
              network: "REGTEST" // or "MAINNET"
            }
          });

      console.log("Wallet initialized successfully:", mnemonic);
      return wallet;
    };
    ```
  </Step>

  <Step title="Start Building">
    You're ready to start building.

    ```tsx App.jsx theme={null}
    import { useState, useEffect } from "react";
    import { View, Text, Button } from "react-native";
    import { SparkWallet } from "@buildonspark/spark-sdk";

    export function WalletInfo() {
      const [wallet, setWallet] = useState(null);
      const [loading, setLoading] = useState(false);

      const createWallet = async () => {
        setLoading(true);
        try {
          const { wallet, mnemonic } = await SparkWallet.initialize({
            options: { network: "REGTEST" }
          });
          setWallet(wallet);
          console.log("Mnemonic:", mnemonic);
        } catch (error) {
          console.error("Failed to create wallet:", error);
        } finally {
          setLoading(false);
        }
      };

      // Note: getSparkAddress() and getBalance() are async
      const [address, setAddress] = useState("");
      const [balance, setBalance] = useState(0n);

      useEffect(() => {
        if (wallet) {
          wallet.getSparkAddress().then(setAddress);
          wallet.getBalance().then(b => setBalance(b.balance));
        }
      }, [wallet]);

      return (
        <View>
          <Text>Wallet Information</Text>
          {loading ? (
            <Text>Loading...</Text>
          ) : wallet ? (
            <View>
              <Text>Address: {address}</Text>
              <Text>Balance: {balance.toString()} sats</Text>
            </View>
          ) : (
            <Button title="Create Wallet" onPress={createWallet} />
          )}
        </View>
      );
    }
    ```
  </Step>
</Steps>

### Initialize a Wallet

A wallet requires either a mnemonic or raw seed for initialization. The `initialize()` function accepts both. If no input is given, it will auto-generate a mnemonic and return it.

```tsx theme={null}
// Initialize a new wallet instance
	const { wallet, mnemonic } = await SparkWallet.initialize({
	  mnemonicOrSeed: "optional-mnemonic-or-seed",
	  accountNumber: 0, // optional
	  options: {
	    network: "REGTEST" // or "MAINNET"
	  }
	});

console.log("Wallet initialized successfully:", mnemonic);
```

### Mnemonic Phrases

A mnemonic is a human-readable encoding of your wallet's seed. It's a 12- or 24-word phrase from the BIP-39 wordlist, used to derive the cryptographic keys that control your wallet.

## Troubleshooting

### `Cannot read property 'decryptEcies' of null`

This error occurs when native crypto modules aren't loaded properly. Fix it by:

1. **Ensure polyfills are imported first** in your `index.js` - they must come before any other imports
2. **Run `pod install`** in your `ios/` directory for iOS builds
3. **Rebuild your app** completely (not just a hot reload)

```bash theme={null}
# iOS
cd ios && pod install && cd ..
npx react-native run-ios

# Android
npx react-native run-android
```

### Wallet initialization fails silently

Make sure you're awaiting the `initialize()` call and handling errors:

```tsx theme={null}
try {
  const { wallet, mnemonic } = await SparkWallet.initialize({
    options: { network: "MAINNET" }
  });
} catch (error) {
  console.error("Wallet init failed:", error);
}
```
