From 13763af7d5fc37251057f9e90dea5205e5463f30 Mon Sep 17 00:00:00 2001 From: mfbz Date: Tue, 16 Dec 2025 09:45:04 +0100 Subject: [PATCH 1/2] Added react-native-sdk docs --- .../tools/react-native-sdk/components.md | 106 ++ docs/build/tools/react-native-sdk/hooks.md | 1465 +++++++++++++++++ docs/build/tools/react-native-sdk/index.mdx | 214 +++ 3 files changed, 1785 insertions(+) create mode 100644 docs/build/tools/react-native-sdk/components.md create mode 100644 docs/build/tools/react-native-sdk/hooks.md create mode 100644 docs/build/tools/react-native-sdk/index.mdx diff --git a/docs/build/tools/react-native-sdk/components.md b/docs/build/tools/react-native-sdk/components.md new file mode 100644 index 0000000000..49d9c8baaa --- /dev/null +++ b/docs/build/tools/react-native-sdk/components.md @@ -0,0 +1,106 @@ +--- +title: 'Components' +description: Reusable UI components for Flow interactions in React Native. +sidebar_position: 3 +--- + +## Connect + +A drop-in wallet connection component that handles the entire authentication flow. When disconnected, it displays a "Connect Wallet" button. When connected, it shows the user's address and opens a Profile modal on press. + +**Props:** + +- `onConnect?: () => void` – Callback triggered after successful authentication +- `onDisconnect?: () => void` – Callback triggered after logout +- `balanceType?: "cadence" | "evm" | "combined"` – Specifies which balance to display (default: `"cadence"`) + - `"cadence"`: Shows the token balance from the Cadence side + - `"evm"`: Shows the token balance from the Flow EVM side + - `"combined"`: Shows the total combined token balance from both sides +- `balanceTokens?: TokenConfig[]` – Optional array of token configurations to display in the balance selector +- `modalEnabled?: boolean` – Whether to show the profile modal on press when connected (default: `true`) + +**Basic Usage:** + +The simplest way to add wallet connection to your app: + +```tsx +import { View, Text } from "react-native"; +import { Connect } from "@onflow/react-native-sdk"; + +function WalletSection() { + return ( + + Connect Wallet + Connect your Flow wallet to interact with the blockchain. + + + ); +} +``` + +**With Callbacks:** + +```tsx +import { Connect } from "@onflow/react-native-sdk"; + + console.log("Wallet connected!")} + onDisconnect={() => console.log("Wallet disconnected")} +/> +``` + +**With Balance Display:** + +```tsx +import { Connect } from "@onflow/react-native-sdk"; + + +``` + +--- + +## Profile + +A standalone component for displaying wallet information including account address and balance. Use this when you want to show user details separately from the Connect button. + +**Props:** + +- `onDisconnect?: () => void` – Callback triggered when the user presses the disconnect button +- `balanceType?: "cadence" | "evm" | "combined"` – Specifies which balance to display (default: `"cadence"`) + - `"cadence"`: Shows the token balance from the Cadence side + - `"evm"`: Shows the token balance from the Flow EVM side + - `"combined"`: Shows the total combined token balance from both sides +- `balanceTokens?: TokenConfig[]` – Optional array of token configurations to display in the balance selector + +**Usage:** + +```tsx +import { View } from "react-native"; +import { Profile, useFlowCurrentUser } from "@onflow/react-native-sdk"; + +function UserProfile() { + const { user } = useFlowCurrentUser(); + + if (!user?.loggedIn) { + return null; + } + + return ( + + console.log("User disconnected")} + /> + + ); +} +``` diff --git a/docs/build/tools/react-native-sdk/hooks.md b/docs/build/tools/react-native-sdk/hooks.md new file mode 100644 index 0000000000..b76eda352d --- /dev/null +++ b/docs/build/tools/react-native-sdk/hooks.md @@ -0,0 +1,1465 @@ +--- +title: 'Hooks' +description: React hooks for interacting with the Flow blockchain in React Native. +sidebar_position: 2 +--- + +:::info + +Many of these hooks are built using [`@tanstack/react-query`](https://tanstack.com/query/latest), which provides powerful caching, revalidation, and background refetching features. As a result, you'll see return types like `UseQueryResult` and `UseMutationResult` throughout this section. Other types—such as `Account`, `Block`, and `CurrentUser`—are from the [Flow Client Library (FCL) TypeDefs](https://github.com/onflow/fcl-js/blob/master/packages/typedefs/src/index.ts). Refer to their respective documentation for full type definitions and usage patterns. + +::: + +## Cadence Hooks + +### `useFlowCurrentUser` + +```tsx +import { useFlowCurrentUser } from "@onflow/react-native-sdk" +``` + +#### Parameters + +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: + +- `user: CurrentUser` – The current user object from FCL +- `authenticate: () => Promise` – Triggers wallet authentication +- `unauthenticate: () => void` – Logs the user out + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function AuthComponent() { + const { user, authenticate, unauthenticate } = useFlowCurrentUser() + + return ( + + {user?.loggedIn ? ( + + Logged in as {user?.addr} + + Logout + + + ) : ( + + Login + + )} + + ) +} +``` + +--- + +### `useFlowAccount` + +```tsx +import { useFlowAccount } from "@onflow/react-native-sdk" +``` + +#### Parameters: + +- `address?: string` – Flow address (with or without `0x` prefix) +- `query?: UseQueryOptions` – Optional TanStackQuery options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseQueryResult` + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function AccountDetails() { + const { data: account, isLoading, error, refetch } = useFlowAccount({ + address: "0x1cf0e2f2f715450", + query: { staleTime: 5000 }, + }) + + if (isLoading) return Loading account... + if (error) return Error fetching account: {error.message} + if (!account) return No account data + + return ( + + Account: {account.address} + Balance: {account.balance} + refetch()}> + Refetch + + + ) +} +``` + +--- + +### `useFlowBlock` + +```tsx +import { useFlowBlock } from "@onflow/react-native-sdk" +``` + +#### Parameters: + +- `sealed?: boolean` – If `true`, fetch latest sealed block +- `id?: string` – Block by ID +- `height?: number` – Block by height +- `query?: UseQueryOptions` – Optional TanStackQuery options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +Only one of `sealed`, `id`, or `height` should be provided. + +#### Returns: `UseQueryResult` + +```tsx +import { View, Text } from 'react-native'; + +function LatestBlock() { + const { data: block, isLoading, error } = useFlowBlock({ query: { staleTime: 10000 } }) + + if (isLoading) return Loading... + if (error) return Error: {error.message} + if (!block) return No block data. + + return ( + + Block {block.height} + ID: {block.id} + + ) +} +``` + +--- + +### `useFlowChainId` + +```tsx +import { useFlowChainId } from "@onflow/react-native-sdk" +``` + +This hook retrieves the Flow chain ID, which is useful for identifying the current network. + +#### Parameters: + +- `query?: Omit, "queryKey" | "queryFn">` – Optional TanStack Query options like `staleTime`, `enabled`, etc. +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseQueryResult` + +Valid chain IDs include: `testnet` (Flow Testnet), `mainnet` (Flow Mainnet), and `emulator` (Flow Emulator). The `flow-` prefix will be stripped from the chain ID returned by the access node (e.g. `flow-testnet` will return `testnet`). + +```tsx +import { View, Text } from 'react-native'; + +function ChainIdExample() { + const { data: chainId, isLoading, error } = useFlowChainId({ + query: { staleTime: 10000 }, + }) + + if (isLoading) return Loading chain ID... + if (error) return Error fetching chain ID: {error.message} + + return Current Flow Chain ID: {chainId} +} +``` + +--- + +### `useFlowClient` + +This hook returns the `FlowClient` for the current `` context. + +#### Parameters: + +- `flowClient?: FlowClient` - Optional `FlowClient` instance to override the result + +--- + +### `useFlowConfig` + +```tsx +import { useFlowConfig } from "@onflow/react-native-sdk" +``` + +#### Returns: `FlowConfig` + +```tsx +import { View, Text } from 'react-native'; + +function MyComponent() { + const config = useFlowConfig() + + return ( + + Current network: {config.flowNetwork} + Current access node: {config.accessNodeUrl} + + ) +} +``` + +--- + +### `useFlowEvents` + +```tsx +import { useFlowEvents } from "@onflow/react-native-sdk" +``` + +#### Parameters: + +- `startBlockId?: string` – Optional ID of the block to start listening from +- `startHeight?: number` – Optional block height to start listening from +- `eventTypes?: string[]` – Array of event type strings (e.g., `A.0xDeaDBeef.Contract.EventName`) +- `addresses?: string[]` – Filter by Flow addresses +- `contracts?: string[]` – Filter by contract identifiers +- `opts?: { heartbeatInterval?: number }` – Options for subscription heartbeat +- `onEvent: (event: Event) => void` – Callback for each event received +- `onError?: (error: Error) => void` – Optional error handler +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Example: + +```tsx +import { View, Text } from 'react-native'; + +function EventListener() { + useFlowEvents({ + eventTypes: ["A.0xDeaDBeef.SomeContract.SomeEvent"], + onEvent: (event) => console.log("New event:", event), + onError: (error) => console.error("Error:", error), + }) + + return Listening for events... +} +``` + +--- + +### `useFlowQuery` + +```tsx +import { useFlowQuery } from "@onflow/react-native-sdk" +``` + +#### Parameters: + +- `cadence: string` – Cadence script to run +- `args?: (arg, t) => unknown[]` – Function returning FCL arguments +- `query?: UseQueryOptions` – Optional TanStackQuery options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseQueryResult` + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function QueryExample() { + const { data, isLoading, error, refetch } = useFlowQuery({ + cadence: ` + access(all) + fun main(a: Int, b: Int): Int { + return a + b + } + `, + args: (arg, t) => [arg(1, t.Int), arg(2, t.Int)], + query: { staleTime: 10000 }, + }) + + if (isLoading) return Loading query... + if (error) return Error: {error.message} + + return ( + + Result: {data} + refetch()}> + Refetch + + + ) +} +``` + +--- + +### `useFlowQueryRaw` + +```tsx +import { useFlowQueryRaw } from "@onflow/react-native-sdk" +``` + +This hook is identical to `useFlowQuery` but returns the raw, non-decoded response data from the Flow blockchain. This is useful when you need access to the original response structure or want to handle decoding manually. + +#### Parameters: + +- `cadence: string` – Cadence script to run +- `args?: (arg, t) => unknown[]` – Function returning FCL arguments +- `query?: UseQueryOptions` – Optional TanStackQuery options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseQueryResult` + +The returned data will be in its raw, non-decoded format as received from the Flow access node. + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function QueryRawExample() { + const { data: rawData, isLoading, error, refetch } = useFlowQueryRaw({ + cadence: ` + access(all) + fun main(a: Int, b: Int): Int { + return a + b + } + `, + args: (arg, t) => [arg(1, t.Int), arg(2, t.Int)], + query: { staleTime: 10000 }, + }) + + if (isLoading) return Loading query... + if (error) return Error: {error.message} + + return ( + + Raw Result: {JSON.stringify(rawData, null, 2)} + refetch()}> + Refetch + + + ) +} +``` + +--- + +### `useFlowMutate` + +```tsx +import { useFlowMutate } from "@onflow/react-native-sdk" +``` + +#### Parameters: + +- `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseMutationResult` + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; +import * as fcl from '@onflow/fcl'; + +function CreatePage() { + const { mutate, isPending, error, data: txId } = useFlowMutate({ + mutation: { + onSuccess: (txId) => console.log("TX ID:", txId), + }, + }) + + const sendTransaction = () => { + mutate({ + cadence: `transaction() { + prepare(acct: &Account) { + log(acct.address) + } + }`, + args: (arg, t) => [], + proposer: fcl.currentUser, + payer: fcl.currentUser, + authorizations: [], + limit: 100, + }) + } + + return ( + + + Send Transaction + + {isPending && Sending transaction...} + {error && Error: {error.message}} + {txId && Transaction ID: {txId}} + + ) +} +``` + +--- + +### `useFlowRevertibleRandom` + +```tsx +import { useFlowRevertibleRandom } from "@onflow/react-native-sdk" +``` + +#### Parameters: + +- `min?: string` – Minimum random value (inclusive), as a UInt256 decimal string. Defaults to `"0"`. +- `max: string` – Maximum random value (inclusive), as a UInt256 decimal string. **Required**. +- `count?: number` – Number of random values to fetch (must be at least 1). Defaults to `1`. +- `query?: Omit, "queryKey" | "queryFn">` – Optional TanStack Query settings like `staleTime`, `enabled`, `retry`, etc. +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseQueryResult` + +Each `RevertibleRandomResult` includes: + +- `blockHeight: string` — The block height from which the random value was generated. +- `value: string` — The random UInt256 value, returned as a decimal string. + +```tsx +import { View, Text, TouchableOpacity, FlatList } from 'react-native'; + +function RandomValues() { + const { data: randoms, isLoading, error, refetch } = useFlowRevertibleRandom({ + min: "0", + max: "1000000000000000000000000", + count: 3, + query: { staleTime: 10000 }, + }) + + if (isLoading) return Loading random numbers... + if (error) return Error fetching random numbers: {error.message} + if (!randoms) return No random values generated. + + return ( + + Generated Random Numbers + idx.toString()} + renderItem={({ item }) => ( + Block {item.blockHeight}: {item.value} + )} + /> + refetch()}> + Regenerate + + + ) +} +``` + +#### Notes: + +* Randomness is generated using the **onchain `revertibleRandom`** function on Flow, producing pseudorandom values tied to block and script execution. +* Values are **deterministic**: The values returned for identical calls within the same block will be identical. +* If `count` is larger than one, the returned values are distinct. +* This hook is designed for simple use cases that don't require unpredictability, such as randomized UIs. + Since the hook uses script executions on existing blocks, the random source is already public and the randoms are predictable. +* For **more advanced use cases** that **do** require onchain randomness logic via transactions, Flow provides built-in support using Cadence's `revertibleRandom` and [commit-reveal scheme]. + +[commit-reveal scheme]: ../../cadence/advanced-concepts/randomness#commit-reveal-scheme + +--- + +### `useFlowTransaction` + +```tsx +import { useFlowTransaction } from "@onflow/react-native-sdk" +``` + +Fetches a Flow transaction by ID and returns the decoded transaction object. + +#### Parameters: + +* `txId?: string` – The Flow transaction ID or scheduled transaction ID to fetch. +* `query?: Omit, "queryKey" | "queryFn">` – Optional TanStack Query options like `staleTime`, `enabled`, etc. +* `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseQueryResult` + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function TransactionDetails({ txId }: { txId: string }) { + const { data: transaction, isLoading, error, refetch } = useFlowTransaction({ + txId, + query: { staleTime: 10000 }, + }) + + if (isLoading) return Loading transaction... + if (error) return Error fetching transaction: {error.message} + if (!transaction) return No transaction data. + + return ( + + Transaction ID: {transaction.id} + Gas Limit: {transaction.gasLimit} + Arguments: {JSON.stringify(transaction.arguments, null, 2)} + refetch()}> + Refetch + + + ) +} +``` + +--- + +### `useFlowTransactionStatus` + +```tsx +import { useFlowTransactionStatus } from "@onflow/react-native-sdk" +``` + +#### Parameters: + +- `id: string` – Transaction ID or scheduled transaction ID to subscribe to +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: + +- `transactionStatus: TransactionStatus | null` +- `error: Error | null` + +```tsx +import { View, Text } from 'react-native'; + +function TransactionStatusComponent() { + const txId = "your-transaction-id-here" + const { transactionStatus, error } = useFlowTransactionStatus({ id: txId }) + + if (error) return Error: {error.message} + + return Status: {transactionStatus?.statusString} +} +``` + +--- + +### `useFlowNftMetadata` + +```tsx +import { useFlowNftMetadata } from "@onflow/react-native-sdk" +``` + +This hook fetches NFT metadata including display information, traits, rarity, and collection details. + +#### Parameters: + +- `accountAddress?: string` – Flow address of the account holding the NFT +- `tokenId?: string | number` – The NFT token ID +- `publicPathIdentifier?: string` – Public path identifier for the collection +- `query?: UseQueryOptions` – Optional TanStack Query options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseQueryResult` + +Where `NftViewResult` is defined as: + +```typescript +interface NftViewResult { + name: string + description: string + thumbnailUrl: string + externalUrl?: string + collectionName?: string + collectionExternalUrl?: string + tokenID: string + traits?: Record + rarity?: string + serialNumber?: string +} +``` + +```tsx +import { View, Text, Image, FlatList } from 'react-native'; + +function NftMetadataExample() { + const { data: nft, isLoading, error } = useFlowNftMetadata({ + accountAddress: "0x1cf0e2f2f715450", + tokenId: "123", + publicPathIdentifier: "exampleNFTCollection", + query: { staleTime: 60000 }, + }) + + if (isLoading) return Loading NFT metadata... + if (error) return Error: {error.message} + if (!nft) return NFT not found + + return ( + + {nft.name} + + {nft.description} + {nft.collectionName && Collection: {nft.collectionName}} + {nft.rarity && Rarity: {nft.rarity}} + {nft.traits && ( + + Traits: + {Object.entries(nft.traits).map(([key, value]) => ( + {key}: {value} + ))} + + )} + + ) +} +``` + +--- + +### `useFlowAuthz` + +```tsx +import { useFlowAuthz } from "@onflow/react-native-sdk" +``` + +A React hook that returns an authorization function for Flow transactions. If no custom authorization is provided, it returns the current user's wallet authorization. + +#### Parameters: + +- `authz?: AuthorizationFunction` – Optional custom authorization function +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +Where `AuthorizationFunction` is defined as: + +```typescript +type AuthorizationFunction = ( + account: Partial +) => Partial | Promise> +``` + +#### Returns: `AuthorizationFunction` + +The authorization function is compatible with Flow transactions' authorizations parameter. + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; +import * as fcl from '@onflow/fcl'; + +// Example 1: Using current user authorization +function CurrentUserAuthExample() { + const authorization = useFlowAuthz() + + const sendTransaction = async () => { + const txId = await fcl.mutate({ + cadence: ` + transaction { + prepare(signer: auth(Storage) &Account) { + log(signer.address) + } + } + `, + authorizations: [authorization], + limit: 100, + }) + console.log("Transaction ID:", txId) + } + + return ( + + Send Transaction + + ) +} +``` + +```tsx +// Example 2: Using custom authorization function +function CustomAuthExample() { + const customAuthz = (account) => ({ + ...account, + addr: "0xCUSTOMOADDRESS", + keyId: 0, + signingFunction: async (signable) => ({ + signature: "0x...", + }), + }) + + const authorization = useFlowAuthz({ authz: customAuthz }) + + const sendTransaction = async () => { + const txId = await fcl.mutate({ + cadence: ` + transaction { + prepare(signer: auth(Storage) &Account) { + log(signer.address) + } + } + `, + authorizations: [authorization], + limit: 100, + }) + console.log("Transaction ID:", txId) + } + + return ( + + Send Custom Auth Transaction + + ) +} +``` + +--- + +### `useFlowScheduledTransaction` + +```tsx +import { useFlowScheduledTransaction } from "@onflow/react-native-sdk" +``` + +Fetches a scheduled transaction by ID. + +#### Parameters: + +- `txId?: string` – Scheduled transaction ID +- `includeHandlerData?: boolean` – Include handler data (default: false) +- `query?: UseQueryOptions` – Optional TanStack Query options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseQueryResult` + +Where `ScheduledTransaction` is defined as: + +```typescript +interface ScheduledTransaction { + id: string + priority: ScheduledTransactionPriority // 0 = Low, 1 = Medium, 2 = High + executionEffort: bigint + status: ScheduledTransactionStatus // 0 = Pending, 1 = Processing, 2 = Completed, 3 = Failed, 4 = Cancelled + fees: { + value: bigint + formatted: string + } + scheduledTimestamp: number + handlerTypeIdentifier: string + handlerAddress: string + handlerUUID?: string // Only included if includeHandlerData is true + handlerResolvedViews?: {[viewType: string]: any} // Only included if includeHandlerData is true +} +``` + +```tsx +import { View, Text } from 'react-native'; + +function ScheduledTransactionDetails({ txId }: { txId: string }) { + const { data: transaction, isLoading, error } = useFlowScheduledTransaction({ + txId, + query: { staleTime: 10000 }, + }) + + if (isLoading) return Loading scheduled transaction... + if (error) return Error: {error.message} + if (!transaction) return Transaction not found + + return ( + + Scheduled Transaction #{transaction.id} + Status: {transaction.status} + Priority: {transaction.priority} + Fees: {transaction.fees.formatted} FLOW + Handler: {transaction.handlerTypeIdentifier} + + ) +} +``` + +--- + +### `useFlowScheduledTransactionList` + +```tsx +import { useFlowScheduledTransactionList } from "@onflow/react-native-sdk" +``` + +Lists all scheduled transactions for an account. + +#### Parameters: + +- `account?: string` – Flow address to query +- `includeHandlerData?: boolean` – Include handler data (default: false) +- `query?: UseQueryOptions` – Optional TanStack Query options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseQueryResult` + +```tsx +import { View, Text, TouchableOpacity, FlatList } from 'react-native'; + +function ScheduledTransactionsList({ account }: { account: string }) { + const { data: transactions, isLoading, error, refetch } = useFlowScheduledTransactionList({ + account, + query: { staleTime: 10000 }, + }) + + if (isLoading) return Loading scheduled transactions... + if (error) return Error: {error.message} + if (!transactions || transactions.length === 0) return No scheduled transactions + + return ( + + Scheduled Transactions for {account} + refetch()}> + Refresh + + tx.id} + renderItem={({ item: tx }) => ( + + Transaction #{tx.id} - Status: {tx.status} - Fees: {tx.fees.formatted} FLOW + + )} + /> + + ) +} +``` + +--- + +### `useFlowScheduledTransactionCancel` + +```tsx +import { useFlowScheduledTransactionCancel } from "@onflow/react-native-sdk" +``` + +Cancels a scheduled transaction and refunds fees. + +#### Parameters: + +- `mutation?: UseMutationOptions` – Optional TanStack Query mutation options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseFlowScheduledTransactionCancelResult` + +Where `UseFlowScheduledTransactionCancelResult` is defined as: + +```typescript +interface UseFlowScheduledTransactionCancelResult extends Omit< + UseMutationResult, + "mutate" | "mutateAsync" +> { + cancelTransaction: (txId: string) => void + cancelTransactionAsync: (txId: string) => Promise +} +``` + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function CancelScheduledTransaction() { + const { cancelTransactionAsync, isPending, error, data: txId } = useFlowScheduledTransactionCancel({ + mutation: { + onSuccess: (txId) => console.log("Cancel transaction ID:", txId), + }, + }) + + const handleCancel = async (scheduledTxId: string) => { + try { + const resultTxId = await cancelTransactionAsync(scheduledTxId) + console.log("Successfully canceled scheduled transaction:", resultTxId) + } catch (error) { + console.error("Failed to cancel:", error) + } + } + + return ( + + handleCancel("42")} disabled={isPending}> + Cancel Scheduled Transaction #42 + + {isPending && Canceling transaction...} + {error && Error: {error.message}} + {txId && Cancel Transaction ID: {txId}} + + ) +} +``` + +--- + +### `useFlowScheduledTransactionSetup` + +```tsx +import { useFlowScheduledTransactionSetup } from "@onflow/react-native-sdk" +``` + +Sets up the Transaction Scheduler Manager resource. + +#### Parameters: + +- `mutation?: UseMutationOptions` – Optional TanStack Query mutation options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseFlowScheduledTransactionSetupResult` + +Where `UseFlowScheduledTransactionSetupResult` is defined as: + +```typescript +interface UseFlowScheduledTransactionSetupResult extends Omit< + UseMutationResult, + "mutate" | "mutateAsync" +> { + setup: () => void + setupAsync: () => Promise +} +``` + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function SchedulerSetup() { + const { setupAsync, isPending, error, data: txId } = useFlowScheduledTransactionSetup({ + mutation: { + onSuccess: (txId) => console.log("Setup transaction ID:", txId), + }, + }) + + const handleSetup = async () => { + try { + const resultTxId = await setupAsync() + console.log("Scheduler setup successful:", resultTxId) + } catch (error) { + console.error("Setup failed:", error) + } + } + + return ( + + + Setup Transaction Scheduler + + {isPending && Setting up scheduler...} + {error && Error: {error.message}} + {txId && Setup Transaction ID: {txId}} + + ) +} +``` + +--- + +## Cross-VM Hooks + +### `useCrossVmBatchTransaction` + +```tsx +import { useCrossVmBatchTransaction } from "@onflow/react-native-sdk" +``` + +This hook allows you to execute multiple EVM transactions in a single atomic Cadence transaction. It is useful for batch processing EVM calls while ensuring they are executed together, either all succeeding or allowing for some to fail without affecting the others. + +#### Parameters: + +- `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseCrossVmBatchTransactionResult` + +Where `UseCrossVmBatchTransactionResult` is defined as: + +```typescript +interface UseCrossVmBatchTransactionResult extends Omit< + UseMutationResult, + "mutate" | "mutateAsync" +> { + mutate: (calls: UseCrossVmBatchTransactionMutateArgs) => void + mutateAsync: (calls: UseCrossVmBatchTransactionMutateArgs) => Promise +} +``` + +Where `UseCrossVmBatchTransactionMutateArgs` is defined as: + +```typescript +interface UseCrossVmBatchTransactionMutateArgs { + calls: EvmBatchCall[] + mustPass?: boolean +} +``` + +Where `EvmBatchCall` is defined as: + +```typescript +interface EvmBatchCall { + // The target EVM contract address (as a string) + address: string + // The contract ABI fragment + abi: Abi + // The name of the function to call + functionName: string + // The function arguments + args?: readonly unknown[] + // The gas limit for the call + gasLimit?: bigint + // The value to send with the call + value?: bigint +} +``` + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function CrossVmBatchTransactionExample() { + const { sendBatchTransaction, isPending, error, data: txId } = useCrossVmBatchTransaction({ + mutation: { + onSuccess: (txId) => console.log("TX ID:", txId), + }, + }) + + const sendTransaction = () => { + const calls = [ + { + address: "0x1234567890abcdef", + abi: { + // ABI definition for the contract + }, + functionName: "transfer", + args: ["0xabcdef1234567890", 100n], + gasLimit: 21000n, + }, + ] + + sendBatchTransaction({calls}) + } + + return ( + + + Send Cross-VM Transaction + + {isPending && Sending transaction...} + {error && Error: {error.message}} + {txId && Transaction ID: {txId}} + + ) +} +``` + +--- + +### `useCrossVmTokenBalance` + +```tsx +import { useCrossVmTokenBalance } from "@onflow/react-native-sdk" +``` + +Fetch the balance of a token balance for a given user across both Cadence and EVM environments. + +#### Parameters: + +- `owner: string` – Cadence address of the account whose token balances you want. +- `vaultIdentifier?: string` – Optional Cadence resource identifier (e.g. "0x1cf0e2f2f715450.FlowToken.Vault") for onchain balance +- `erc20AddressHexArg?: string` – Optional bridged ERC-20 contract address (hex) for EVM/COA balance +- `query?: Omit, "queryKey" | "queryFn">` – Optional TanStack Query config (e.g. staleTime, enabled) +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +> **Note:** You must pass `owner`, and one of `vaultIdentifier` or `erc20AddressHexArg`. + +#### Returns: `UseQueryResult` + +Where `UseCrossVmTokenBalanceData` is defined as: + +```typescript +interface UseCrossVmTokenBalanceData { + cadence: TokenBalance // Token balance of Cadence vault + evm: TokenBalance // Token balance of EVM (COA stored in /storage/coa) + combined: TokenBalance // Combined balance of both Cadence and EVM +} +``` + +Where `TokenBalance` is defined as: + +```typescript +interface TokenBalance { + value: bigint // Balance value in smallest unit + formatted: string // Formatted balance string (e.g. "123.45") + precision: number // Number of decimal places for the token +} +``` + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function UseCrossVmTokenBalanceExample() { + const { data, isLoading, error, refetch } = useCrossVmTokenBalance({ + owner: '0x1e4aa0b87d10b141', + vaultIdentifier: 'A.1654653399040a61.FlowToken.Vault', + query: { staleTime: 10000 }, + }); + + if (isLoading) return Loading token balance... + if (error) return Error fetching token balance: {error.message} + + return ( + + Token Balances + Cadence Balance: {data.cadence.formatted} (Value: {data.cadence.value.toString()}) + EVM Balance: {data.evm.formatted} (Value: {data.evm.value.toString()}) + Combined Balance: {data.combined.formatted} (Value: {data.combined.value.toString()}) + refetch()}> + Refetch + + + ) +} +``` + +--- + +### `useCrossVmTransactionStatus` + +```tsx +import { useCrossVmTransactionStatus } from "@onflow/react-native-sdk" +``` + +Subscribes to status updates for a given Cross-VM Flow transaction ID that executes EVM calls. This hook monitors the transaction status and extracts EVM call results if available. + +#### Parameters: + +- `id?: string` – Optional Flow transaction ID to monitor +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseCrossVmTransactionStatusResult` + +Where `UseCrossVmTransactionStatusResult` is defined as: + +```typescript +interface UseCrossVmTransactionStatusResult { + transactionStatus: TransactionStatus | null // Latest transaction status, or null before any update + evmResults?: CallOutcome[] // EVM transaction results, if available + error: Error | null // Any error encountered during status updates +} +``` + +Where `CallOutcome` is defined as: + +```typescript +interface CallOutcome { + status: "passed" | "failed" | "skipped" // Status of the EVM call + hash?: string // EVM transaction hash if available + errorMessage?: string // Error message if the call failed +} +``` + +```tsx +import { View, Text, FlatList } from 'react-native'; + +function CrossVmTransactionStatusComponent() { + const txId = "your-cross-vm-transaction-id-here" + const { transactionStatus, evmResults, error } = useCrossVmTransactionStatus({ id: txId }) + + if (error) return Error: {error.message} + + return ( + + Flow Status: {transactionStatus?.statusString} + {evmResults && evmResults.length > 0 && ( + + EVM Call Results: + idx.toString()} + renderItem={({ item, index }) => ( + + Call {index}: {item.status} + {item.hash && Hash: {item.hash}} + {item.errorMessage && Error: {item.errorMessage}} + + )} + /> + + )} + + ) +} +``` + +--- + +### `useCrossVmBridgeNftFromEvm` + +```tsx +import { useCrossVmBridgeNftFromEvm } from "@onflow/react-native-sdk" +``` + +This hook bridges NFTs from Flow EVM to Cadence. It withdraws an NFT from the signer's COA (Cadence Owned Account) in EVM and deposits it into their Cadence collection. + +#### Parameters: + +- `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseCrossVmBridgeNftFromEvmTxResult` + +Where `UseCrossVmBridgeNftFromEvmTxResult` is defined as: + +```typescript +interface UseCrossVmBridgeNftFromEvmTxResult extends Omit< + UseMutationResult, + "mutate" | "mutateAsync" +> { + crossVmBridgeNftFromEvm: (args: UseCrossVmBridgeNftFromEvmTxMutateArgs) => void + crossVmBridgeNftFromEvmAsync: (args: UseCrossVmBridgeNftFromEvmTxMutateArgs) => Promise +} +``` + +Where `UseCrossVmBridgeNftFromEvmTxMutateArgs` is defined as: + +```typescript +interface UseCrossVmBridgeNftFromEvmTxMutateArgs { + nftIdentifier: string // Cadence type identifier (e.g., "A.0x123.MyNFT.NFT") + nftId: string // EVM NFT ID as string representation of UInt256 +} +``` + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function BridgeNftFromEvmExample() { + const { crossVmBridgeNftFromEvm, isPending, error, data: txId } = useCrossVmBridgeNftFromEvm({ + mutation: { + onSuccess: (txId) => console.log("Transaction ID:", txId), + }, + }) + + const handleBridge = () => { + crossVmBridgeNftFromEvm({ + nftIdentifier: "A.0x1cf0e2f2f715450.ExampleNFT.NFT", + nftId: "123", + }) + } + + return ( + + + Bridge NFT from EVM + + {isPending && Bridging NFT...} + {error && Error: {error.message}} + {txId && Transaction ID: {txId}} + + ) +} +``` + +--- + +### `useCrossVmBridgeNftToEvm` + +```tsx +import { useCrossVmBridgeNftToEvm } from "@onflow/react-native-sdk" +``` + +This hook bridges NFTs from Cadence to Flow EVM and executes arbitrary EVM transactions atomically. It withdraws NFTs from the signer's Cadence collection and deposits them into their COA in EVM, then executes the provided EVM calls. + +#### Parameters: + +- `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseCrossVmBridgeNftToEvmTxResult` + +Where `UseCrossVmBridgeNftToEvmTxResult` is defined as: + +```typescript +interface UseCrossVmBridgeNftToEvmTxResult extends Omit< + UseMutationResult, + "mutate" | "mutateAsync" +> { + crossVmBridgeNftToEvm: (args: UseCrossVmBridgeNftToEvmTxMutateArgs) => void + crossVmBridgeNftToEvmAsync: (args: UseCrossVmBridgeNftToEvmTxMutateArgs) => Promise +} +``` + +Where `UseCrossVmBridgeNftToEvmTxMutateArgs` is defined as: + +```typescript +interface UseCrossVmBridgeNftToEvmTxMutateArgs { + nftIdentifier: string // Cadence NFT type identifier + nftIds: string[] // Array of NFT IDs to bridge + calls: EvmBatchCall[] // Array of EVM calls to execute after bridging +} +``` + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function BridgeNftToEvmExample() { + const { crossVmBridgeNftToEvm, isPending, error, data: txId } = useCrossVmBridgeNftToEvm({ + mutation: { + onSuccess: (txId) => console.log("Transaction ID:", txId), + }, + }) + + const handleBridge = () => { + crossVmBridgeNftToEvm({ + nftIdentifier: "A.0x1cf0e2f2f715450.ExampleNFT.NFT", + nftIds: ["1", "2", "3"], + calls: [ + { + address: "0x1234567890abcdef1234567890abcdef12345678", + abi: myContractAbi, + functionName: "transferNFT", + args: ["0xRecipient", 1n], + gasLimit: 100000n, + }, + ], + }) + } + + return ( + + + Bridge NFTs to EVM + + {isPending && Bridging NFTs...} + {error && Error: {error.message}} + {txId && Transaction ID: {txId}} + + ) +} +``` + +--- + +### `useCrossVmBridgeTokenFromEvm` + +```tsx +import { useCrossVmBridgeTokenFromEvm } from "@onflow/react-native-sdk" +``` + +This hook bridges fungible tokens from Flow EVM to Cadence. It withdraws tokens from the signer's COA in EVM and deposits them into their Cadence vault. + +#### Parameters: + +- `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseCrossVmBridgeTokenFromEvmResult` + +Where `UseCrossVmBridgeTokenFromEvmResult` is defined as: + +```typescript +interface UseCrossVmBridgeTokenFromEvmResult extends Omit< + UseMutationResult, + "mutate" | "mutateAsync" +> { + crossVmBridgeTokenFromEvm: (args: UseCrossVmBridgeTokenFromEvmMutateArgs) => void + crossVmBridgeTokenFromEvmAsync: (args: UseCrossVmBridgeTokenFromEvmMutateArgs) => Promise +} +``` + +Where `UseCrossVmBridgeTokenFromEvmMutateArgs` is defined as: + +```typescript +interface UseCrossVmBridgeTokenFromEvmMutateArgs { + vaultIdentifier: string // Cadence vault type identifier (e.g., "A.0x123.FlowToken.Vault") + amount: string // Amount as UInt256 string representation +} +``` + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function BridgeTokenFromEvmExample() { + const { crossVmBridgeTokenFromEvm, isPending, error, data: txId } = useCrossVmBridgeTokenFromEvm({ + mutation: { + onSuccess: (txId) => console.log("Transaction ID:", txId), + }, + }) + + const handleBridge = () => { + crossVmBridgeTokenFromEvm({ + vaultIdentifier: "A.0x1654653399040a61.FlowToken.Vault", + amount: "1000000000", // Amount in smallest unit + }) + } + + return ( + + + Bridge Tokens from EVM + + {isPending && Bridging tokens...} + {error && Error: {error.message}} + {txId && Transaction ID: {txId}} + + ) +} +``` + +--- + +### `useCrossVmBridgeTokenToEvm` + +```tsx +import { useCrossVmBridgeTokenToEvm } from "@onflow/react-native-sdk" +``` + +This hook bridges fungible tokens from Cadence to Flow EVM and executes arbitrary EVM transactions atomically. It withdraws tokens from the signer's Cadence vault and deposits them into their COA in EVM, then executes the provided EVM calls. + +#### Parameters: + +- `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseCrossVmBridgeTokenToEvmResult` + +Where `UseCrossVmBridgeTokenToEvmResult` is defined as: + +```typescript +interface UseCrossVmBridgeTokenToEvmResult extends Omit< + UseMutationResult, + "mutate" | "mutateAsync" +> { + crossVmBridgeTokenToEvm: (args: UseCrossVmBridgeTokenToEvmMutateArgs) => void + crossVmBridgeTokenToEvmAsync: (args: UseCrossVmBridgeTokenToEvmMutateArgs) => Promise +} +``` + +Where `UseCrossVmBridgeTokenToEvmMutateArgs` is defined as: + +```typescript +interface UseCrossVmBridgeTokenToEvmMutateArgs { + vaultIdentifier: string // Cadence vault type identifier + amount: string // Amount as decimal string (e.g., "1.5") + calls: EvmBatchCall[] // Array of EVM calls to execute after bridging +} +``` + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function BridgeTokenToEvmExample() { + const { crossVmBridgeTokenToEvm, isPending, error, data: txId } = useCrossVmBridgeTokenToEvm({ + mutation: { + onSuccess: (txId) => console.log("Transaction ID:", txId), + }, + }) + + const handleBridge = () => { + crossVmBridgeTokenToEvm({ + vaultIdentifier: "A.0x1654653399040a61.FlowToken.Vault", + amount: "10.5", + calls: [ + { + address: "0x1234567890abcdef1234567890abcdef12345678", + abi: erc20Abi, + functionName: "transfer", + args: ["0xRecipient", 1000000n], + gasLimit: 100000n, + }, + ], + }) + } + + return ( + + + Bridge Tokens to EVM + + {isPending && Bridging tokens...} + {error && Error: {error.message}} + {txId && Transaction ID: {txId}} + + ) +} +``` diff --git a/docs/build/tools/react-native-sdk/index.mdx b/docs/build/tools/react-native-sdk/index.mdx new file mode 100644 index 0000000000..748a864b6a --- /dev/null +++ b/docs/build/tools/react-native-sdk/index.mdx @@ -0,0 +1,214 @@ +--- +title: 'Flow React Native SDK' +description: React Native hooks and components for interacting with the Flow blockchain. +sidebar_position: 1 +--- + +# Flow React Native SDK + +**The easiest way to build React Native apps on Flow.** A lightweight, TypeScript-first library that makes Flow blockchain interactions feel native to React Native development. + +## Quick Start + +### 1. Install + +```bash +npm install @onflow/react-native-sdk +``` + +### 2. Wrap Your App + +Create a provider wrapper component: + +```tsx title="components/flow-provider-wrapper.tsx" +import { FlowProvider } from "@onflow/react-native-sdk"; +import flowJSON from "../flow.json"; + +export function FlowProviderWrapper({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ); +} +``` + +Then wrap your app in the root layout: + +```tsx title="app/_layout.tsx" +import { FlowProviderWrapper } from "@/components/flow-provider-wrapper"; +import { Stack } from "expo-router"; +import { StatusBar } from "expo-status-bar"; +import { View } from "react-native"; + +export default function RootLayout() { + return ( + + + + + + + ); +} +``` + +### 3. Start Building + +```tsx +import { View, Text, Pressable } from "react-native"; +import { Connect, useFlowCurrentUser, useFlowQuery } from "@onflow/react-native-sdk"; + +function MyApp() { + const { user } = useFlowCurrentUser(); + + const { data: balance, isLoading, refetch } = useFlowQuery({ + cadence: ` + import FlowToken from 0x7e60df042a9c0868 + + access(all) fun main(address: Address): UFix64 { + let account = getAccount(address) + let vaultRef = account.capabilities + .get<&FlowToken.Vault>(/public/flowTokenBalance) + .borrow() + ?? panic("Could not borrow Balance reference") + return vaultRef.balance + } + `, + args: (arg, t) => [arg(user?.addr, t.Address)], + query: { enabled: !!user?.addr }, + }); + + return ( + + + {user?.loggedIn && ( + + Welcome, {user.addr}! + {isLoading ? ( + Loading balance... + ) : ( + Balance: {balance ? String(balance) : "0.00"} FLOW + )} + refetch()}> + Refresh + + + )} + + ); +} +``` + +:::info Starter Template +Get started quickly with the [flow-react-native-sdk-starter](https://github.com/onflow/flow-react-native-sdk-starter) template which includes a pre-configured Expo project with wallet connection, balance queries, and transaction examples. +::: + +--- + +## Configuration Options + +The `FlowProvider` accepts the following configuration: + +| Property | Description | +|----------|-------------| +| `accessNodeUrl` | REST endpoint for blockchain access (e.g., `https://rest-testnet.onflow.org`) | +| `discoveryWallet` | URL for wallet discovery/selection UI | +| `discoveryAuthnEndpoint` | API endpoint for authentication | +| `flowNetwork` | Network selection: `"testnet"` or `"mainnet"` | +| `appDetailTitle` | App name displayed in wallet | +| `appDetailUrl` | App URL displayed in wallet | +| `appDetailIcon` | App icon URL displayed in wallet | +| `appDetailDescription` | App description displayed in wallet | +| `walletconnectProjectId` | WalletConnect Cloud project ID | + +**Mainnet Configuration:** + +```tsx +config={{ + accessNodeUrl: "https://rest-mainnet.onflow.org", + discoveryWallet: "https://fcl-discovery.onflow.org/authn", + discoveryAuthnEndpoint: "https://fcl-discovery.onflow.org/api/authn", + flowNetwork: "mainnet", + // ... other options +}} +``` + +--- + +## [Hooks](./hooks.md) + +**Cadence Hooks** for native Flow interactions: + +- Authentication & user management +- Account details & balances +- Block & transaction queries +- Real-time event subscriptions +- Script execution & mutations + +**Cross-VM Hooks** for bridging Cadence ↔ Flow EVM: + +- Atomic batch transactions +- Token & NFT bridging +- Cross-chain balance queries + +[→ View all hooks](./hooks.md) + +--- + +## [Components](./components.md) + +Native UI components for React Native: + +- `` – Wallet authentication with balance display +- `` – Standalone wallet information display + +[→ View all components](./components.md) + +--- + +## Why Choose React Native SDK? + +**Developer Experience First** + +- TypeScript-native with full type safety +- Familiar React Native patterns and conventions +- Comprehensive error handling and loading states + +**Production Ready** + +- Built on battle-tested libraries (TanStack Query) +- Automatic retries, caching, and background updates +- Cross-VM support for hybrid Cadence/EVM applications + +**Mobile Native** + +- Native mobile wallet integrations via WalletConnect +- React Native components that feel native +- Expo and bare React Native support + +--- + +## Need Help? + +- **[Hooks Documentation](./hooks.md)** – Detailed API reference for all hooks +- **[Components Documentation](./components.md)** – UI components guide +- **[Configuration Guide](../flow-cli/flow.json/configuration.md)** – Learn about configuring `flow.json` From e85ebeabf9a70188ba5121d18f03a3179b223327 Mon Sep 17 00:00:00 2001 From: mfbz Date: Wed, 17 Dec 2025 20:14:26 +0100 Subject: [PATCH 2/2] Implemented comments --- docs/build/tools/react-native-sdk/index.mdx | 85 ++++++++++++--------- 1 file changed, 51 insertions(+), 34 deletions(-) diff --git a/docs/build/tools/react-native-sdk/index.mdx b/docs/build/tools/react-native-sdk/index.mdx index 748a864b6a..028f3c8379 100644 --- a/docs/build/tools/react-native-sdk/index.mdx +++ b/docs/build/tools/react-native-sdk/index.mdx @@ -6,7 +6,11 @@ sidebar_position: 1 # Flow React Native SDK -**The easiest way to build React Native apps on Flow.** A lightweight, TypeScript-first library that makes Flow blockchain interactions feel native to React Native development. +**The easiest way to build React Native apps on Flow.** A lightweight, TypeScript-first library for seamless Flow blockchain integration in your React Native apps. + +:::note +This SDK shares the same hooks as the [Flow React SDK](../react-sdk/index.mdx), so if you're familiar with the web version, you'll feel right at home. The main differences are the React Native-specific components (`Connect`, `Profile`) and mobile wallet integrations. +::: ## Quick Start @@ -21,27 +25,32 @@ npm install @onflow/react-native-sdk Create a provider wrapper component: ```tsx title="components/flow-provider-wrapper.tsx" -import { FlowProvider } from "@onflow/react-native-sdk"; -import flowJSON from "../flow.json"; - -export function FlowProviderWrapper({ children }: { children: React.ReactNode }) { +import { FlowProvider } from '@onflow/react-native-sdk'; +import flowJSON from '../flow.json'; + +export function FlowProviderWrapper({ + children, +}: { + children: React.ReactNode; +}) { return ( @@ -54,15 +63,15 @@ export function FlowProviderWrapper({ children }: { children: React.ReactNode }) Then wrap your app in the root layout: ```tsx title="app/_layout.tsx" -import { FlowProviderWrapper } from "@/components/flow-provider-wrapper"; -import { Stack } from "expo-router"; -import { StatusBar } from "expo-status-bar"; -import { View } from "react-native"; +import { FlowProviderWrapper } from '@/components/flow-provider-wrapper'; +import { Stack } from 'expo-router'; +import { StatusBar } from 'expo-status-bar'; +import { View } from 'react-native'; export default function RootLayout() { return ( - + @@ -74,13 +83,21 @@ export default function RootLayout() { ### 3. Start Building ```tsx -import { View, Text, Pressable } from "react-native"; -import { Connect, useFlowCurrentUser, useFlowQuery } from "@onflow/react-native-sdk"; +import { View, Text, Pressable } from 'react-native'; +import { + Connect, + useFlowCurrentUser, + useFlowQuery, +} from '@onflow/react-native-sdk'; function MyApp() { const { user } = useFlowCurrentUser(); - const { data: balance, isLoading, refetch } = useFlowQuery({ + const { + data: balance, + isLoading, + refetch, + } = useFlowQuery({ cadence: ` import FlowToken from 0x7e60df042a9c0868 @@ -106,7 +123,7 @@ function MyApp() { {isLoading ? ( Loading balance... ) : ( - Balance: {balance ? String(balance) : "0.00"} FLOW + Balance: {balance ? String(balance) : '0.00'} FLOW )} refetch()}> Refresh @@ -128,17 +145,17 @@ Get started quickly with the [flow-react-native-sdk-starter](https://github.com/ The `FlowProvider` accepts the following configuration: -| Property | Description | -|----------|-------------| -| `accessNodeUrl` | REST endpoint for blockchain access (e.g., `https://rest-testnet.onflow.org`) | -| `discoveryWallet` | URL for wallet discovery/selection UI | -| `discoveryAuthnEndpoint` | API endpoint for authentication | -| `flowNetwork` | Network selection: `"testnet"` or `"mainnet"` | -| `appDetailTitle` | App name displayed in wallet | -| `appDetailUrl` | App URL displayed in wallet | -| `appDetailIcon` | App icon URL displayed in wallet | -| `appDetailDescription` | App description displayed in wallet | -| `walletconnectProjectId` | WalletConnect Cloud project ID | +| Property | Description | +| ------------------------ | ----------------------------------------------------------------------------- | +| `accessNodeUrl` | REST endpoint for blockchain access (e.g., `https://rest-testnet.onflow.org`) | +| `discoveryWallet` | URL for wallet discovery/selection UI | +| `discoveryAuthnEndpoint` | API endpoint for authentication | +| `flowNetwork` | Network selection: `"testnet"` or `"mainnet"` | +| `appDetailTitle` | App name displayed in wallet | +| `appDetailUrl` | App URL displayed in wallet | +| `appDetailIcon` | App icon URL displayed in wallet | +| `appDetailDescription` | App description displayed in wallet | +| `walletconnectProjectId` | WalletConnect Cloud project ID | **Mainnet Configuration:**