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

# React Native Quickstart

> Initialize a mobile wallet and prepare an RGB transfer using @utexo/rgb-sdk-rn.

<Info>
  This guide covers iOS and Android applications. For Node.js, see the [Node.js guide](/getting-started/quickstart/node-js). For browser applications, see the [Web guide](/getting-started/quickstart/web).
</Info>

## Prerequisites

* React Native with a working iOS or Android native build environment
* Node.js for the development toolchain
* A persistent, writable application directory
* Bitcoin test funds for transaction fees
* A separately initialized sender wallet that already holds the RGB asset for an end-to-end transfer

<Warning>
  This guide uses the `utexo` network profile for Utexo's hosted signet infrastructure. Never use mainnet keys or real funds while following this guide.
</Warning>

## Step 1: Install the SDK

```bash theme={null}
npm install @utexo/rgb-sdk-rn react-native-fs
```

For iOS, install the native dependencies after adding the package:

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

The package includes native bindings and is not interchangeable with the Node.js or Web packages.

## Step 2: Generate Wallet Keys

```javascript theme={null}
import { generateKeys } from '@utexo/rgb-sdk-rn';


const keys = await generateKeys('utexo');
```

Store the mnemonic in platform-backed secure storage. Do not log it in production or persist it in AsyncStorage.

## Step 3: Initialize and Unlock the Wallet

The React Native constructor requires node parameters and a signer. Create the storage directory before initializing the wallet.

```javascript theme={null}
import {
  PasswordRLNSigner,
  UTEXOWallet,
} from '@utexo/rgb-sdk-rn';
import RNFS from 'react-native-fs';


const storageDirPath = `${RNFS.DocumentDirectoryPath}/utexo-wallet`;
await RNFS.mkdir(storageDirPath);


const password = await getPasswordFromSecureInput();
const wallet = new UTEXOWallet(
  {
    storageDirPath,
    daemonListeningPort: 21250,
    ldkPeerListeningPort: 21251,
    network: 'utexo',
    enableVirtualChannelsV0: false,
  },
  new PasswordRLNSigner(password, keys.mnemonic)
);


await wallet.init();
await wallet.unlock({});
```

`getPasswordFromSecureInput()` represents an application-owned secure prompt. The empty unlock object allows the SDK to resolve the indexer and RGB proxy from the `utexo` network defaults.

Use unused listening ports. If two wallet instances run in the same app process, give each instance different ports and a different storage directory.

<Warning>
  The older `new UTEXOWallet(mnemonic, { network, dataDir })` form does not match the current React Native implementation. The mnemonic and password belong in the signer, and startup requires both `init()` and `unlock()`.
</Warning>

## Step 4: Fund the Wallet

```javascript theme={null}
const address = await wallet.getAddress();
console.log('Deposit address:', address);
```

Send signet BTC to the address and wait for the required confirmation before creating RGB UTXOs.

## Step 5: Create RGB UTXOs

```javascript theme={null}
await wallet.createUtxos({ num: 5, size: 1000 });
await wallet.refreshWallet();
```

`size` is denominated in satoshis.

## Step 6: Resolve the Asset From the Sender

`listAssets()` returns arrays grouped by schema. NIA assets are in `nia` and use `assetId`.

```javascript theme={null}
const { nia } = await senderWallet.listAssets();
const usdt = nia.find((asset) => asset.ticker === 'USDT');


if (!usdt) {
  throw new Error('The sender wallet does not hold the requested NIA asset');
}


const usdtAssetId = usdt.assetId;
const amount = 10 ** usdt.precision; // one displayed unit in base units
```

A new receiver wallet will not list an asset it has never received. Resolve the ID and precision from the funded sender or an authoritative asset registry.

## Step 7: Create a Receive Invoice

Run this on the receiver wallet initialized above:

```javascript theme={null}
const receiveData = await wallet.blindReceive({
  assetId: usdtAssetId,
  amount,
  minConfirmations: 1,
  durationSeconds: 3600,
});


console.log('RGB invoice:', receiveData.invoice);
```

The `amount` is an integer in asset base units. One displayed unit equals `10 ** precision` base units.

## Step 8: Send From the Funded Wallet

The current React Native API uses `onchainSend()`, not `send()`.

```javascript theme={null}
const sendResult = await senderWallet.onchainSend({
  invoice: receiveData.invoice,
  assetId: usdtAssetId,
  amount,
  donation: false,
  feeRate: 7,
  minConfirmations: 1,
});


console.log('Transfer transaction:', sendResult.txid);
```

The sender wallet must be a separately initialized `UTEXOWallet` with its own storage directory and ports, sufficient signet BTC, and a spendable asset balance.

## Step 9: Refresh and Verify

```javascript theme={null}
await senderWallet.refreshWallet();
await wallet.refreshWallet();


const receiverAssets = await wallet.listAssets();
const receivedAsset = receiverAssets.nia.find(
  (asset) => asset.assetId === usdtAssetId
);


console.log('Receiver asset balance:', receivedAsset?.balance);
```

A transfer can remain pending while its consignment is delivered and its Bitcoin anchor reaches the required confirmation state.

## Lightning Payments

Lightning requires usable peer and channel state. Wallet initialization does not open or fund a channel. For a BTC-only invoice, omit the `asset` field.

```javascript theme={null}
const invoice = await wallet.createLightningInvoice({
  amountSats: 3000,
  expirySeconds: 900,
});


const payment = await senderWallet.payLightningInvoice({
  lnInvoice: invoice.lnInvoice,
});


const status = await senderWallet.getLightningSendStatus(payment.txid);
console.log('Lightning payment status:', status);
```

For an RGB-asset invoice, pass `asset: { assetId, amount }` when creating the invoice. Do not pass an empty asset object for BTC-only payments.

## React Native-Specific Notes

* Store the wallet database in a persistent application document directory, not a cache directory.
* Keep the mnemonic and password in platform-backed secure storage.
* Give concurrent node instances distinct storage directories and listening ports.
* Plan for application lifecycle changes. Shut down or dispose of the wallet according to the SDK lifecycle before replacing an instance.
* Network access is required for indexer, RGB transport, and Lightning operations.

## Troubleshooting

| Issue                 | Likely cause                                   | Check                                                        |
| --------------------- | ---------------------------------------------- | ------------------------------------------------------------ |
| Native build fails    | Missing platform dependencies                  | Reinstall pods or rebuild the Android native project         |
| `init()` fails        | Storage, port, or signer problem               | Confirm the directory exists and ports are unused            |
| `unlock()` fails      | Endpoint or credential problem                 | Check network defaults and signer credentials                |
| Asset cannot be found | Wrong response shape or unfunded sender        | Read `listAssets().nia` and use `assetId`                    |
| `onchainSend()` fails | Invoice, amount, balance, or transport problem | Confirm the invoice is unexpired and amount is in base units |

## Implementation References

* [React Native wallet implementation](https://github.com/UTEXO-Protocol/rgb-sdk-rn/blob/dev/src/wallet/utexo-wallet.ts)
* [React Native network defaults](https://github.com/UTEXO-Protocol/rgb-sdk-rn/blob/dev/src/wallet/network-defaults.ts)
* [React Native signer implementations](https://github.com/UTEXO-Protocol/rgb-sdk-rn/blob/dev/src/wallet/rln-signers.ts)
* [Maintained React Native lifecycle harness](https://github.com/UTEXO-Protocol/rgb-sdk-rn-sandbox/blob/main/e2e/harness.ts)
* [Shared wallet models](https://github.com/UTEXO-Protocol/rgb-sdk-core/blob/dev/src/types/wallet-model.ts)

## Next Steps

* [SDK Reference](/product-suite/sdk)
* [Architecture](/getting-started/architecture)
* [Glossary](/getting-started/glossary)
