diff --git a/packages/react/lib/context.tsx b/packages/react/lib/context.tsx index 2edc6d1..4c858a7 100644 --- a/packages/react/lib/context.tsx +++ b/packages/react/lib/context.tsx @@ -1,5 +1,5 @@ import {createContext, ReactNode, useEffect, useState} from "react"; -import {type FetchOptions, Sprinter} from "@chainsafe/sprinter-sdk"; +import {Sprinter} from "@chainsafe/sprinter-sdk"; import {useTokens} from "./internal/useTokens.ts"; import {useChains} from "./internal/useChains.ts"; import {useBalances} from "./internal/useBalances.ts"; @@ -10,12 +10,39 @@ type SprinterContext = ReturnType & ReturnType(null); interface SprinterContextProps { - children?: ReactNode | undefined; - fetchOptions?: Omit; + children?: ReactNode; + baseUrl?: string; } -export function SprinterContext({ children, fetchOptions }: SprinterContextProps) { - const [sprinter] = useState(new Sprinter(fetchOptions)); +/** + * SprinterContext is a context provider component that initializes a Sprinter instance + * and provides various functionalities for interacting with tokens, chains, balances, + * and bridging solutions through React Context. + * + * It fetches and provides tokens, chains, user balances, and bridging solutions to any + * component that consumes this context. + * + * @param {SprinterContextProps} props - The props for the component: + * - `children` (ReactNode): The child components that will have access to the context. + * - `baseUrl` (string, optional): The base URL to be used for all fetch requests in the Sprinter SDK. + * + * @returns {JSX.Element} A context provider that supplies tokens, chains, balances, and bridging solutions to its children. + * + * @example + * ```ts + * import { SprinterContext, Environment } from '@chainsafe/sprinter-react'; + * + * function App() { + * return ( + * + * + * + * ); + * } + * ``` + */ +export function SprinterContext({ children, baseUrl }: SprinterContextProps) { + const [sprinter] = useState(new Sprinter({baseUrl})); /** Balances */ const { balances, getUserBalances } = useBalances(sprinter); @@ -27,7 +54,7 @@ export function SprinterContext({ children, fetchOptions }: SprinterContextProps const { chains, getAvailableChains } = useChains(sprinter); /** Solutions */ - const { solution, getBridgeAndCall, getBridgeBalance, getBridgeAggregateBalance, getBridgeAggregateBalanceAndCall } = useBridge(sprinter); + const { solution, getBridgeAndCall, getBridge, getBridgeAggregateBalance, getBridgeAggregateBalanceAndCall } = useBridge(sprinter); /** Initialization */ useEffect(() => { @@ -39,6 +66,6 @@ export function SprinterContext({ children, fetchOptions }: SprinterContextProps balances, getUserBalances, tokens, getAvailableTokens, chains, getAvailableChains, - solution, getBridgeAndCall, getBridgeBalance, getBridgeAggregateBalance, getBridgeAggregateBalanceAndCall, + solution, getBridgeAndCall, getBridge, getBridgeAggregateBalance, getBridgeAggregateBalanceAndCall, }}>{children}; } diff --git a/packages/react/lib/hooks.ts b/packages/react/lib/hooks.ts index b728a74..ec9b66e 100644 --- a/packages/react/lib/hooks.ts +++ b/packages/react/lib/hooks.ts @@ -3,7 +3,20 @@ import {Context} from "./context.tsx"; import {Address} from "@chainsafe/sprinter-sdk"; import {BalancesEntry} from "./internal/useBalances.ts"; -/** Everything from context */ +/** + * A hook to access the full Sprinter context, including balances, tokens, chains, and bridge solutions. + * + * @returns {SprinterContext} The current context value with Sprinter functionalities. + * + * @throws {Error} If the context is not available. + * + * @example + * ```ts + * import { useSprinter } from '@chainsafe/sprinter-react'; + * + * const { balances, tokens, chains, solution } = useSprinter(); + * ``` + */ export function useSprinter() { const context = useContext(Context); @@ -18,7 +31,51 @@ const balancesEmptyState = { loading: false, error: null, }; - +/** + * A hook to retrieve the user's token balances and a function to fetch them. + * + * @param {Address} account - The user's wallet address. + * + * @returns {{ + * balances: AsyncRequestState, + * getUserBalances: () => void + * }} + * - `balances`: The state of the user's token balances for the specified account, including: + * - `data`: The token balances, or `null` if not yet fetched. + * - `loading`: A boolean indicating if the request is in progress. + * - `error`: An error message, or `null` if there is no error. + * - `getUserBalances`: A function to fetch the user's balances for the specified account. + * + * @example + * ```ts + * import React, { useEffect } from 'react'; + * import { useSprinterBalances } from '@chainsafe/sprinter-react'; + * + * function BalancesComponent() { + * const { balances, getUserBalances } = useSprinterBalances("0xYourAddress"); + * + * useEffect(() => { + * getUserBalances(); + * }, [getUserBalances]); + * + * if (balances.loading) { + * return
Loading...
; + * } + * + * if (balances.error) { + * return
Error: {balances.error}
; + * } + * + * return ( + *
    + * {Object.entries(balances.data || {}).map(([symbol, balanceEntry]) => ( + *
  • {symbol}: {balanceEntry.total}
  • + * ))} + *
+ * ); + * } + * ``` + */ export function useSprinterBalances(account: Address) { const { balances: _balances, getUserBalances: _getUserBalances } = useSprinter(); @@ -28,20 +85,154 @@ export function useSprinterBalances(account: Address) { return { balances, getUserBalances }; } -/** Tokens */ +/** + * A hook to retrieve available tokens and a function to fetch them. + * + * @returns {{ + * tokens: AsyncRequestState, + * getAvailableTokens: () => void + * }} + * - `tokens`: The state of available tokens, including: + * - `data`: The list of available tokens, or `null` if not yet fetched. + * - `loading`: A boolean indicating if the request is in progress. + * - `error`: An error message, or `null` if there is no error. + * - `getAvailableTokens`: A function to fetch the available tokens. + * + * @example + * ```ts + * import React, { useEffect } from 'react'; + * import { useSprinterTokens } from '@chainsafe/sprinter-react'; + * + * function TokensComponent() { + * const { tokens, getAvailableTokens } = useSprinterTokens(); + * + * useEffect(() => { + * getAvailableTokens(); + * }, [getAvailableTokens]); + * + * if (tokens.loading) { + * return
Loading...
; + * } + * + * if (tokens.error) { + * return
Error: {tokens.error}
; + * } + * + * return ( + *
    + * {tokens.data?.map(token => ( + *
  • {token.name}
  • + * ))} + *
+ * ); + * } + * ``` + */ export function useSprinterTokens() { const { tokens, getAvailableTokens } = useSprinter(); return { tokens, getAvailableTokens }; } -/** Chains */ +/** + * A hook to retrieve available chains and a function to fetch them. + * + * @returns {{ + * chains: AsyncRequestState, + * getAvailableChains: () => void + * }} + * - `chains`: The state of available chains, including: + * - `data`: The list of available chains, or `null` if not yet fetched. + * - `loading`: A boolean indicating if the request is in progress. + * - `error`: An error message, or `null` if there is no error. + * - `getAvailableChains`: A function to fetch the available chains. + * + * @example + * ```ts + * import React, { useEffect } from 'react'; + * import { useSprinterChains } from '@chainsafe/sprinter-react'; + * + * function ChainsComponent() { + * const { chains, getAvailableChains } = useSprinterChains(); + * + * useEffect(() => { + * getAvailableChains(); + * }, [getAvailableChains]); + * + * if (chains.loading) { + * return
Loading...
; + * } + * + * if (chains.error) { + * return
Error: {chains.error}
; + * } + * + * return ( + *
    + * {chains.data?.map(chain => ( + *
  • {chain.name}
  • + * ))} + *
+ * ); + * } + * ``` + */ export function useSprinterChains() { const { chains, getAvailableChains } = useSprinter(); return { chains, getAvailableChains }; } -/** Solutions */ +/** + * A hook to retrieve bridge solutions and functions to interact with the Sprinter. + * + * @returns {{ + * solution: AsyncRequestState, + * getBridgeAggregateBalance: (request: { + * account: string, + * destinationChain: number, + * token: string, + * amount: string + * }) => void + * }} + * - `solution`: The state of the bridge solution, including: + * - `data`: The bridge solution, or `null` if not yet fetched. + * - `loading`: A boolean indicating if the request is in progress. + * - `error`: An error message, or `null` if there is no error. + * - `getBridgeAggregateBalance`: A function to get the aggregate bridge balance based on the provided request. + * + * @example + * ```ts + * import React, { useEffect } from 'react'; + * import { useSprinterBridge } from '@chainsafe/sprinter-react'; + * + * function BridgeComponent() { + * const { solution, getBridgeAggregateBalance } = useSprinterBridge(); + * + * useEffect(() => { + * getBridgeAggregateBalance({ + * account: "0x3e101ec02e7a48d16dade204c96bff842e7e2519", + * destinationChain: 11155111, + * token: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", + * amount: "100000000", + * }); + * }, [getBridgeAggregateBalance]); + * + * if (solution.loading) { + * return
Loading...
; + * } + * + * if (solution.error) { + * return
Error: {solution.error}
; + * } + * + * return ( + *
+ *
{JSON.stringify(solution.data, null, 2)}
+ *
+ * ); + * } + * ``` + */ export function useSprinterBridge() { - const { solution, getBridgeAndCall, getBridgeBalance, getBridgeAggregateBalance, getBridgeAggregateBalanceAndCall } = useSprinter(); - return { solution, getBridgeAndCall, getBridgeBalance, getBridgeAggregateBalance, getBridgeAggregateBalanceAndCall }; + const { solution, getBridgeAndCall, getBridge, getBridgeAggregateBalance, getBridgeAggregateBalanceAndCall } = useSprinter(); + return { solution, getBridgeAndCall, getBridge, getBridgeAggregateBalance, getBridgeAggregateBalanceAndCall }; } diff --git a/packages/react/lib/internal/useBridge.ts b/packages/react/lib/internal/useBridge.ts index 729d988..20ab01b 100644 --- a/packages/react/lib/internal/useBridge.ts +++ b/packages/react/lib/internal/useBridge.ts @@ -22,7 +22,7 @@ export function useBridge(sprinter: Sprinter) { makeRequest(sprinter.bridgeAggregateBalanceAndCall(settings)); }, [sprinter, makeRequest]); - const getBridgeBalance = useCallback((settings: Infer) => { + const getBridge = useCallback((settings: Infer) => { makeRequest(sprinter.bridge(settings)); }, [sprinter, makeRequest]); @@ -30,5 +30,5 @@ export function useBridge(sprinter: Sprinter) { makeRequest(sprinter.bridgeAndCall(settings)); }, [sprinter, makeRequest]); - return { solution, getBridgeBalance, getBridgeAndCall, getBridgeAggregateBalance, getBridgeAggregateBalanceAndCall }; + return { solution, getBridge, getBridgeAndCall, getBridgeAggregateBalance, getBridgeAggregateBalanceAndCall }; } diff --git a/packages/react/lib/main.ts b/packages/react/lib/main.ts index 5289107..1de8689 100644 --- a/packages/react/lib/main.ts +++ b/packages/react/lib/main.ts @@ -3,7 +3,6 @@ export { useSprinterBalances, useSprinter, useSprinterChains, - useSprinterSolution, - useSprinterCallSolution, - useSprinterTokens + useSprinterTokens, + useSprinterBridge, } from "./hooks";