diff --git a/docs/blockchain-development-tutorials/cadence/getting-started/building-a-frontend-app.md b/docs/blockchain-development-tutorials/cadence/getting-started/building-a-frontend-app.md index df3c6ec4ef..8b9e3cf6a4 100644 --- a/docs/blockchain-development-tutorials/cadence/getting-started/building-a-frontend-app.md +++ b/docs/blockchain-development-tutorials/cadence/getting-started/building-a-frontend-app.md @@ -459,7 +459,7 @@ For additional details and advanced usage, refer to the [@onflow/react-sdk docum [`useFlowQuery`]: ../../../build/tools/react-sdk#useflowquery [`useFlowMutate`]: ../../../build/tools/react-sdk#useflowmutate [Dev Wallet]: ../../../build/tools/flow-dev-wallet -[@onflow/react-sdk documentation]: ../../../build/tools/react-sdk/index.md -[**@onflow/react-sdk**]: ../../../build/tools/react-sdk/index.md +[@onflow/react-sdk documentation]: ../../../build/tools/react-sdk +[**@onflow/react-sdk**]: ../../../build/tools/react-sdk [Flow CLI]: ../../../build/tools/flow-cli/install.md [Cadence VSCode extension]: ../../../build/tools/vscode-extension diff --git a/docs/blockchain-development-tutorials/cross-vm-apps/add-to-wagmi.md b/docs/blockchain-development-tutorials/cross-vm-apps/add-to-wagmi.md index d0ca0f9911..afde67b943 100644 --- a/docs/blockchain-development-tutorials/cross-vm-apps/add-to-wagmi.md +++ b/docs/blockchain-development-tutorials/cross-vm-apps/add-to-wagmi.md @@ -517,4 +517,4 @@ For a complete reference implementation, check out the [FCL + RainbowKit + wagmi [Testnet Cadence Flowscan]: https://testnet.flowscan.io [Cadence Owned Accounts]: ../../build/cadence/basics/accounts.md [Testnet EVM Flowscan]: https://evm-testnet.flowscan.io -[pre-built utility from the `@onflow/react-sdk`]: ../../build/tools/react-sdk/index.md#usecrossvmbatchtransaction +[pre-built utility from the `@onflow/react-sdk`]: ../../build/tools/react-sdk#usecrossvmbatchtransaction diff --git a/docs/build/tools/react-sdk/components.md b/docs/build/tools/react-sdk/components.md index 8e6930e31d..7ebc3eef97 100644 --- a/docs/build/tools/react-sdk/components.md +++ b/docs/build/tools/react-sdk/components.md @@ -1,5 +1,5 @@ --- -title: 'Flow React SDK Components' +title: 'Components' description: Reusable UI components for Flow interactions. sidebar_position: 3 --- @@ -8,6 +8,7 @@ import { Connect, TransactionDialog, TransactionLink, TransactionButton } from " import { FlowProvider } from "@onflow/react-sdk" import FlowProviderDemo from '@site/src/components/FlowProviderDemo'; import TransactionDialogDemo from '@site/src/components/TransactionDialogDemo'; +import PlaygroundButton from '@site/src/components/PlaygroundButton'; # React SDK Components @@ -94,6 +95,8 @@ function MyComponent() { A drop-in wallet connection component with UI for copy address, logout, and balance display. +
+ **Props:** - `variant?: ButtonProps["variant"]` – Optional button style variant (default: `"primary"`) @@ -128,6 +131,8 @@ import { Connect } from "@onflow/react-sdk" Button component for executing Flow transactions with built-in loading states and global transaction management. +
+ **Props:** - `transaction: Parameters[0]` – Flow transaction object to execute when clicked @@ -180,6 +185,8 @@ const myTransaction = { Dialog component for real-time transaction status updates. +
+ **Props:** - `open: boolean` – Whether the dialog is open @@ -216,6 +223,8 @@ import { TransactionDialog } from "@onflow/react-sdk" Link to the block explorer with the appropriate network scoped to transaction ID. +
+ **Props:** - `txId: string` – The transaction ID to link to diff --git a/docs/build/tools/react-sdk/hooks.md b/docs/build/tools/react-sdk/hooks.md index 47761b1323..2ce8623497 100644 --- a/docs/build/tools/react-sdk/hooks.md +++ b/docs/build/tools/react-sdk/hooks.md @@ -1,9 +1,11 @@ --- -title: 'Flow React SDK Hooks' +title: 'Hooks' description: React hooks for interacting with the Flow blockchain. sidebar_position: 2 --- +import PlaygroundButton from '@site/src/components/PlaygroundButton'; + # React SDK Hooks :::info @@ -16,6 +18,8 @@ Many of these hooks are built using [`@tanstack/react-query`](https://tanstack.c ### `useFlowCurrentUser` + + ```tsx import { useFlowCurrentUser } from "@onflow/react-sdk" ``` @@ -53,6 +57,8 @@ function AuthComponent() { ### `useFlowAccount` + + ```tsx import { useFlowAccount } from "@onflow/react-sdk" ``` @@ -91,6 +97,8 @@ function AccountDetails() { ### `useFlowBlock` + + ```tsx import { useFlowBlock } from "@onflow/react-sdk" ``` @@ -128,6 +136,8 @@ function LatestBlock() { ### `useFlowChainId` + + ```tsx import { useFlowChainId } from "@onflow/react-sdk" ``` @@ -160,6 +170,8 @@ function ChainIdExample() { ### `useFlowClient` + + This hook returns the `FlowClient` for the current `` context. #### Parameters: @@ -170,6 +182,8 @@ This hook returns the `FlowClient` for the current `` context. ### `useFlowConfig` + + ```tsx import { useFlowConfig } from "@onflow/react-sdk" ``` @@ -193,6 +207,8 @@ function MyComponent() { ### `useFlowEvents` + + ```tsx import { useFlowEvents } from "@onflow/react-sdk" ``` @@ -227,6 +243,8 @@ function EventListener() { ### `useFlowQuery` + + ```tsx import { useFlowQuery } from "@onflow/react-sdk" ``` @@ -269,6 +287,8 @@ function QueryExample() { ### `useFlowQueryRaw` + + ```tsx import { useFlowQueryRaw } from "@onflow/react-sdk" ``` @@ -315,6 +335,8 @@ function QueryRawExample() { ### `useFlowMutate` + + ```tsx import { useFlowMutate } from "@onflow/react-sdk" ``` @@ -366,6 +388,8 @@ function CreatePage() { ### `useFlowRevertibleRandom` + + ```tsx import { useFlowRevertibleRandom } from "@onflow/react-sdk" ``` @@ -427,6 +451,8 @@ function RandomValues() { ### `useFlowTransaction` + + ```tsx import { useFlowTransaction } from "@onflow/react-sdk" ``` @@ -467,6 +493,8 @@ function TransactionDetails({ txId }: { txId: string }) { ### `useFlowTransactionStatus` + + ```tsx import { useFlowTransactionStatus } from "@onflow/react-sdk" ``` @@ -496,6 +524,8 @@ function TransactionStatusComponent() { ### `useDarkMode` + + ```tsx import { useDarkMode } from "@onflow/react-sdk" ``` @@ -525,6 +555,8 @@ function ThemeAwareComponent() { ### `useCrossVmBatchTransaction` + + ```tsx import { useCrossVmBatchTransaction } from "@onflow/react-sdk" ``` @@ -620,6 +652,8 @@ function CrossVmBatchTransactionExample() { ### `useCrossVmTokenBalance` + + ```tsx import { useCrossVmTokenBalance } from "@onflow/react-sdk" ``` @@ -684,6 +718,8 @@ function UseCrossVmTokenBalanceExample() { ### `useCrossVmSpendNft` + + ```tsx import { useCrossVmSpendNft } from "@onflow/react-sdk" ``` @@ -757,6 +793,8 @@ function CrossVmSpendNftExample() { ### `useCrossVmSpendToken` + + ```tsx import { useCrossVmSpendToken } from "@onflow/react-sdk" ``` @@ -830,6 +868,8 @@ function CrossVmSpendTokenExample() { ### `useCrossVmTransactionStatus` + + ```tsx import { useCrossVmTransactionStatus } from "@onflow/react-sdk" ``` diff --git a/docs/build/tools/react-sdk/index.md b/docs/build/tools/react-sdk/index.md deleted file mode 100644 index 8680be31ad..0000000000 --- a/docs/build/tools/react-sdk/index.md +++ /dev/null @@ -1,149 +0,0 @@ ---- -title: '@onflow/react-sdk' -description: React hooks for interacting with the Flow blockchain. -sidebar_position: 1 ---- - -import { Connect, TransactionDialog, TransactionLink, TransactionButton } from "@onflow/react-sdk" -import { FlowProvider } from "@onflow/react-sdk" -import FlowProviderDemo from '@site/src/components/FlowProviderDemo'; - -# @onflow/react-sdk - -**The easiest way to build React apps on Flow.** A lightweight, TypeScript-first library that makes Flow blockchain interactions feel native to React development. - -🚀 **Quick to setup** – One provider, minimal configuration -⚡ **Built for performance** – Powered by TanStack Query for optimal caching -🎨 **Styled beautifully** – Tailwind-based components that match your design -🔗 **Cross-VM ready** – Seamlessly bridge between Cadence and Flow EVM - -## Quick Start - -### 1. Install - -```bash -npm install @onflow/react-sdk -``` - -### 2. Wrap Your App - -```tsx -import React from "react" -import App from "./App" -import { FlowProvider } from "@onflow/react-sdk" -import flowJSON from "../flow.json" - -function Root() { - return ( - - - - ) -} - -export default Root -``` - -:::tip Next.js Users -Place the `FlowProvider` inside your `layout.tsx`. Since React hooks must run on the client, you may need to wrap the provider in a separate file that begins with `'use client'` to avoid issues with server-side rendering. -::: - -### 3. Start Building - -```tsx -import { useFlowCurrentUser, Connect, useFlowQuery } from "@onflow/react-sdk" - -function MyApp() { - const { user } = useFlowCurrentUser() - - const { data: greeting } = useFlowQuery({ - cadence: `access(all) fun main(): String { return "Hello, Flow!" }`, - args: (arg, t) => [], - }) - - return ( -
- - {user?.loggedIn &&

Welcome, {user.addr}!

} -

{greeting}

-
- ) -} -``` - -### Live Demo - - - console.log("Connected!")} - onDisconnect={() => console.log("Disconnected!")} - /> - - ---- - -## What's Included - -### 🎣 [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) - -Beautiful, accessible UI components: -- `` – Wallet authentication with balance display -- `` – Smart transaction execution -- `` – Real-time transaction tracking -- `` – Network-aware block explorer links - -[→ View all components](./components.md) - ---- - -## Why Choose React SDK? - -**Developer Experience First** -- TypeScript-native with full type safety -- Familiar React patterns and conventions -- Comprehensive error handling and loading states - -**Production Ready** -- Built on battle-tested libraries (TanStack Query, Tailwind CSS) -- Automatic retries, caching, and background updates -- Cross-VM support for hybrid Cadence/EVM applications - -**Customizable** -- Theme system for brand consistency -- Composable hooks for custom UI -- Dark mode support out of the box - ---- - -## Need Help? - -- 📖 **[Hooks Documentation](./hooks.md)** – Detailed API reference for all hooks -- 🎨 **[Components Documentation](./components.md)** – UI components and theming guide -- 🔗 **[Configuration Guide](../flow-cli/flow.json/configuration.md)** – Learn about configuring `flow.json` \ No newline at end of file diff --git a/docs/build/tools/react-sdk/index.mdx b/docs/build/tools/react-sdk/index.mdx new file mode 100644 index 0000000000..8484ab97df --- /dev/null +++ b/docs/build/tools/react-sdk/index.mdx @@ -0,0 +1,185 @@ +--- +title: 'Flow React SDK' +description: React hooks and components for interacting with the Flow blockchain. +sidebar_position: 1 +--- + +import ReactSDKOverview from '@site/src/components/ReactSDKOverview'; +import FlowProviderDemo from '@site/src/components/FlowProviderDemo'; +import { Connect } from '@onflow/react-sdk'; + +# Flow React SDK + +**The easiest way to build React apps on Flow.** A lightweight, TypeScript-first library that makes Flow blockchain interactions feel native to React development. + + + +## Quick Start + +### 1. Install + +```bash +npm install @onflow/react-sdk +``` + +### 2. Wrap Your App + +```tsx +import React from 'react'; +import App from './App'; +import { FlowProvider } from '@onflow/react-sdk'; +import flowJSON from '../flow.json'; + +function Root() { + return ( + + + + ); +} + +export default Root; +``` + +:::tip Next.js Users +Create a client component wrapper for the `FlowProvider`: + +```tsx title="components/FlowProviderWrapper.tsx" +'use client'; + +import { FlowProvider } from '@onflow/react-sdk'; +import flowJSON from '../flow.json'; + +export default function FlowProviderWrapper({ children }) { + return ( + + {children} + + ); +} +``` + +Then use it in your `layout.tsx`: + +```tsx title="app/layout.tsx" +import FlowProviderWrapper from '@/components/FlowProviderWrapper'; + +export default function RootLayout({ children }) { + return ( + + + {children} + + + ); +} +``` + +::: + +### 3. Start Building + +```tsx +import { useFlowCurrentUser, Connect, useFlowQuery } from '@onflow/react-sdk'; + +function MyApp() { + const { user } = useFlowCurrentUser(); + + const { data: greeting } = useFlowQuery({ + cadence: `access(all) fun main(): String { return "Hello, Flow!" }`, + args: (arg, t) => [], + }); + + return ( +
+ + {user?.loggedIn &&

Welcome, {user.addr}!

} +

{greeting}

+
+ ); +} +``` + +--- + +## 🎣 [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) + +Beautiful, accessible UI components: + +- `` – Wallet authentication with balance display +- `` – Smart transaction execution +- `` – Real-time transaction tracking +- `` – Network-aware block explorer links + +[→ View all components](./components.md) + +--- + +## Why Choose React SDK? + +**Developer Experience First** + +- TypeScript-native with full type safety +- Familiar React patterns and conventions +- Comprehensive error handling and loading states + +**Production Ready** + +- Built on battle-tested libraries (TanStack Query, Tailwind CSS) +- Automatic retries, caching, and background updates +- Cross-VM support for hybrid Cadence/EVM applications + +**Customizable** + +- Theme system for brand consistency +- Composable hooks for custom UI +- Dark mode support out of the box + +--- + +## Need Help? + +- 📖 **[Hooks Documentation](./hooks.md)** – Detailed API reference for all hooks +- 🎨 **[Components Documentation](./components.md)** – UI components and theming guide +- 🔗 **[Configuration Guide](../flow-cli/flow.json/configuration.md)** – Learn about configuring `flow.json` diff --git a/src/components/PlaygroundButton.tsx b/src/components/PlaygroundButton.tsx new file mode 100644 index 0000000000..4f95b31927 --- /dev/null +++ b/src/components/PlaygroundButton.tsx @@ -0,0 +1,31 @@ +import React from 'react'; + +interface PlaygroundButtonProps { + href: string; + text?: string; +} + +export default function PlaygroundButton({ + href, + text = 'Open in Playground', +}: PlaygroundButtonProps): React.ReactElement { + return ( + + {text} → + + ); +} diff --git a/src/components/ReactSDKOverview.tsx b/src/components/ReactSDKOverview.tsx new file mode 100644 index 0000000000..0cbb01b482 --- /dev/null +++ b/src/components/ReactSDKOverview.tsx @@ -0,0 +1,805 @@ +import React, { useState } from 'react'; +import useIsBrowser from '@docusaurus/useIsBrowser'; +import { useColorMode } from '@docusaurus/theme-common'; +import { + FlowProvider, + Connect, + TransactionButton, + TransactionLink, + TransactionDialog, + useFlowBlock, + useFlowAccount, + useFlowCurrentUser, + useFlowChainId, + useFlowRevertibleRandom, +} from '@onflow/react-sdk'; +import { flowClient } from '@site/src/config/fcl'; + +function MasonryGrid({ children }: { children: React.ReactNode }) { + return ( +
+ {children} +
+ ); +} + +// Enhanced Card Wrapper +function EnhancedCard({ + title, + description, + darkMode, + children, + accent = '#00ef8b', +}: { + title: string; + description: string; + darkMode: boolean; + children: React.ReactNode; + accent?: string; +}) { + return ( +
+
+

+ {title} +

+

+ {description} +

+
+ {children} +
+ ); +} + +// Component Cards +function ConnectCardMini({ darkMode }: { darkMode: boolean }) { + return ( + +
+ +
+
+ ); +} + +function TransactionButtonCardMini({ darkMode }: { darkMode: boolean }) { + const GREETING_TRANSACTION = ` + transaction(greeting: String) { + prepare(signer: &Account) { + log(greeting) + } + } + `; + + return ( + +
+ [arg('Hello!', t.String)], + limit: 999, + }} + /> +
+
+ ); +} + +function TransactionLinkCardMini({ darkMode }: { darkMode: boolean }) { + const [txId, setTxId] = useState(undefined); + + const GREETING_TRANSACTION = ` + transaction(greeting: String) { + prepare(signer: &Account) { + log(greeting) + } + } + `; + + return ( + +
+
+ [arg('Hello!', t.String)], + limit: 999, + }} + mutation={{ + onSuccess: (data) => setTxId(data), + }} + /> +
+ {txId && ( +
+ +
+ )} +
+
+ ); +} + +function TransactionDialogCardMini({ darkMode }: { darkMode: boolean }) { + const [open, setOpen] = useState(false); + const [txId, setTxId] = useState(undefined); + + const GREETING_TRANSACTION = ` + transaction(greeting: String) { + prepare(signer: &Account) { + log(greeting) + } + } + `; + + return ( + +
+ [arg('Hello!', t.String)], + limit: 999, + }} + mutation={{ + onSuccess: (data) => { + setTxId(data); + setOpen(true); + }, + }} + /> +
+ +
+ ); +} + +// Hook Cards +function UseFlowCurrentUserCardMini({ darkMode }: { darkMode: boolean }) { + const { user } = useFlowCurrentUser(); + + return ( + +
+
+ + Status + + + {user?.loggedIn ? '● Connected' : '○ Not Connected'} + +
+ {user?.loggedIn && ( +
+ {user.addr} +
+ )} +
+
+ ); +} + +function UseFlowChainIdCardMini({ darkMode }: { darkMode: boolean }) { + const { + data: chainId, + refetch, + isLoading, + } = useFlowChainId({ + query: { enabled: false }, + }); + + return ( + +
+ + {chainId && ( +
+
+ Network +
+
+ {chainId} +
+
+ )} +
+
+ ); +} + +function UseFlowBlockCardMini({ darkMode }: { darkMode: boolean }) { + const { + data: block, + isLoading, + refetch, + } = useFlowBlock({ + query: { enabled: true }, + }); + + return ( + +
+ + {block && ( +
+
+ Height +
+
+ {block.height} +
+
+ )} +
+
+ ); +} + +function UseFlowAccountCardMini({ darkMode }: { darkMode: boolean }) { + const [address, setAddress] = useState('0x7e60df042a9c0868'); + const { + data: account, + isLoading, + refetch, + } = useFlowAccount({ + address, + query: { enabled: false }, + }); + + return ( + +
+ setAddress(e.target.value)} + placeholder="Enter address..." + style={{ + width: '100%', + padding: '0.75rem', + background: darkMode ? 'rgba(17, 24, 39, 0.6)' : '#ffffff', + color: darkMode ? '#fff' : '#000', + border: darkMode + ? '1px solid rgba(255, 255, 255, 0.1)' + : '1px solid rgba(0, 0, 0, 0.1)', + borderRadius: '8px', + fontSize: '0.75rem', + fontFamily: 'monospace', + outline: 'none', + }} + /> + + {account && ( +
+
+ Balance +
+
+ {(Number(account.balance) / 1e8).toFixed(4)} FLOW +
+
+ )} +
+
+ ); +} + +function UseFlowRevertibleRandomCardMini({ darkMode }: { darkMode: boolean }) { + const { + data: randomResults, + isLoading, + refetch, + } = useFlowRevertibleRandom({ + max: '1000000000', + count: 1, + }); + + return ( + +
+ + {randomResults && randomResults.length > 0 && ( +
+
+ Random Value +
+
+ {randomResults[0].value} +
+
+ )} +
+
+ ); +} + +// Inner component with all the cards +function ReactSDKOverviewContent({ darkMode }: { darkMode: boolean }) { + return ( +
+
+ + + + + + + + + + + + + +

+ Try components and hooks live +

+

+ Explore all React SDK features in our interactive playground with live + examples and documentation +

+ + Open Playground → + +
+ + + + + + + + + + + + +
+ ); +} + +// Main Overview Component wrapped with FlowProvider +export default function ReactSDKOverview(): React.ReactElement | null { + const isBrowser = useIsBrowser(); + const { colorMode } = useColorMode(); + const darkMode = colorMode === 'dark'; + + if (!isBrowser) return null; + + return ( + + + + ); +}