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

# Using Anchor with Dynamic

> Learn how to connect Solana's Anchor framework to Dynamic's JavaScript SDK.

> [!NOTE]
>
> This recipe uses the Dynamic JavaScript SDK (`@dynamic-labs-sdk/client` + `@dynamic-labs-sdk/solana`). The React tab also uses `@dynamic-labs-sdk/react-hooks`. See the [Quickstart](https://docs.dynamic.xyz/docs/javascript/reference/quickstart.md) for the base setup.

## Prerequisites

* The Dynamic JS SDK initialized, with the Solana extension registered via `addSolanaExtension()`; see [Adding Solana Extensions](https://docs.dynamic.xyz/docs/javascript/reference/solana/adding-solana-extensions.md)
* Installed dependencies:
  * `@coral-xyz/anchor`
  * `@solana/web3.js`
  * `@dynamic-labs-sdk/client`
  * `@dynamic-labs-sdk/solana`
  * For the React tab: `@dynamic-labs-sdk/react-hooks` and `@tanstack/react-query` (`DynamicProvider` mounted at the root; see the [React Quickstart](https://docs.dynamic.xyz/docs/javascript/reference/react-quickstart.md))
* Your Anchor program's IDL and TypeScript types

***

## Step 1: Build the Anchor provider

Adapt the SDK's transaction-signing helpers to the `Wallet` interface Anchor expects.

> [tab] JavaScript
>
> Create a file (e.g., `anchor-provider.ts`) and add the following code:
>
> ```typescript theme={"system"}
> import { AnchorProvider, Program } from "@coral-xyz/anchor";
> import { getWalletAccounts, getActiveNetworkData } from "@dynamic-labs-sdk/client";
> import {
>   getSolanaConnection,
>   isSolanaWalletAccount,
>   signAllTransactions,
>   signTransaction,
> } from "@dynamic-labs-sdk/solana";
> import { PublicKey } from "@solana/web3.js";
>
> // Import your program's types and IDL
> import { YourProgram } from './path-to-your-program-types';
> import yourProgramIdl from './path-to-your-idl.json';
>
> export async function createAnchorProvider() {
>   const solanaAccount = getWalletAccounts().find(isSolanaWalletAccount);
>   if (!solanaAccount) throw new Error("No Solana wallet account connected");
>
>   const publicKey = new PublicKey(solanaAccount.address);
>
>   // Re-fetch this on every call so it reflects the wallet's current network
>   const { networkData } = await getActiveNetworkData({ walletAccount: solanaAccount });
>   const connection = getSolanaConnection({ networkData });
>
>   // Adapt the SDK's transaction-signing helpers to the Wallet interface Anchor expects
>   const provider = new AnchorProvider(
>     connection,
>     {
>       publicKey,
>       signTransaction: async (tx) => {
>         const { signedTransaction } = await signTransaction({
>           transaction: tx,
>           walletAccount: solanaAccount,
>         });
>         // Cast back to the transaction type Anchor passed in
>         return signedTransaction as typeof tx;
>       },
>       signAllTransactions: async (txs) => {
>         const { signedTransactions } = await signAllTransactions({
>           transactions: txs,
>           walletAccount: solanaAccount,
>         });
>         return signedTransactions as typeof txs;
>       },
>     },
>     {
>       commitment: "confirmed",
>       skipPreflight: true,
>     }
>   );
>
>   const program: Program<YourProgram> = new Program(yourProgramIdl, provider);
>
>   return { provider, program, publicKey, walletAccount: solanaAccount };
> }
> ```

> [tab] React
>
> Create a file (e.g., `AnchorProviderComponent.tsx`) and add the following code. This context derives the Anchor provider and program from the connected Dynamic wallet account.
>
> ```tsx theme={"system"}
> "use client";
>
> import { AnchorProvider, Program } from "@coral-xyz/anchor";
> import {
>   getSolanaConnection,
>   isSolanaWalletAccount,
>   signAllTransactions,
>   signTransaction,
> } from "@dynamic-labs-sdk/solana";
> import {
>   useGetActiveNetworkData,
>   useGetWalletAccounts,
>   useInitStatus,
> } from "@dynamic-labs-sdk/react-hooks";
> import { Connection, PublicKey } from "@solana/web3.js";
> import {
>   createContext,
>   ReactNode,
>   useContext,
>   useMemo,
> } from "react";
>
> // Import your program's types and IDL
> import { YourProgram } from './path-to-your-program-types';
> import yourProgramIdl from './path-to-your-idl.json';
>
> interface AnchorProviderContextValue {
>   program: Program<YourProgram> | null;
>   connection: Connection | null;
>   provider: AnchorProvider | null;
>   publicKey: PublicKey | null;
> }
>
> const AnchorProviderContext = createContext<AnchorProviderContextValue>({
>   program: null,
>   connection: null,
>   provider: null,
>   publicKey: null,
> });
>
> export function useAnchorProvider() {
>   return useContext(AnchorProviderContext);
> }
>
> interface AnchorProviderProps {
>   children: ReactNode;
> }
>
> export default function AnchorProviderComponent({ children }: AnchorProviderProps) {
>   const { data: initStatus } = useInitStatus();
>   const { data: walletAccounts = [] } = useGetWalletAccounts();
>   const solanaAccount = useMemo(
>     () => walletAccounts.find(isSolanaWalletAccount),
>     [walletAccounts],
>   );
>
>   // Re-fetches when the wallet account changes or the user switches networks
>   const { data: activeNetwork } = useGetActiveNetworkData({
>     walletAccount: solanaAccount!,
>     queryParams: { enabled: Boolean(solanaAccount) },
>   });
>
>   // Derive the public key from the connected wallet
>   const publicKey = useMemo(() => {
>     if (!solanaAccount?.address) return null;
>     try {
>       return new PublicKey(solanaAccount.address);
>     } catch (error) {
>       console.error("Invalid public key:", error);
>       return null;
>     }
>   }, [solanaAccount?.address]);
>
>   const connection = useMemo(
>     () =>
>       activeNetwork?.networkData
>         ? getSolanaConnection({ networkData: activeNetwork.networkData })
>         : null,
>     [activeNetwork],
>   );
>
>   const provider = useMemo(() => {
>     if (initStatus !== "finished" || !solanaAccount || !publicKey || !connection) {
>       return null;
>     }
>
>     // Adapt the SDK's transaction-signing helpers to the Wallet interface Anchor expects
>     return new AnchorProvider(
>       connection,
>       {
>         publicKey,
>         signTransaction: async (tx) => {
>           const { signedTransaction } = await signTransaction({
>             transaction: tx,
>             walletAccount: solanaAccount,
>           });
>           // Cast back to the transaction type Anchor passed in
>           return signedTransaction as typeof tx;
>         },
>         signAllTransactions: async (txs) => {
>           const { signedTransactions } = await signAllTransactions({
>             transactions: txs,
>             walletAccount: solanaAccount,
>           });
>           return signedTransactions as typeof txs;
>         },
>       },
>       {
>         commitment: "confirmed",
>         skipPreflight: true,
>       }
>     );
>   }, [initStatus, solanaAccount, publicKey, connection]);
>
>   const program = useMemo(
>     (): Program<YourProgram> | null =>
>       provider ? new Program(yourProgramIdl, provider) : null,
>     [provider],
>   );
>
>   const contextValue = useMemo(
>     () => ({
>       program,
>       connection,
>       provider,
>       publicKey,
>     }),
>     [program, connection, provider, publicKey]
>   );
>
>   return (
>     <AnchorProviderContext.Provider value={contextValue}>
>       {children}
>     </AnchorProviderContext.Provider>
>   );
> }
> ```

***

## Step 2: Wrap your app with the provider

If you're using the JavaScript tab from Step 1, skip this step and call `createAnchorProvider()` directly wherever you need the program.

For the React context, mount `AnchorProviderComponent` inside `DynamicProvider` so it can read the connected wallet from the JS SDK's hooks. `QueryClientProvider` must wrap `DynamicProvider`: every hook in `@dynamic-labs-sdk/react-hooks` is built on TanStack Query.

```tsx theme={"system"}
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { DynamicProvider } from "@dynamic-labs-sdk/react-hooks";
import { dynamicClient } from "./dynamicClient";
import AnchorProviderComponent from "./AnchorProviderComponent";

const queryClient = new QueryClient();

function App({ children }) {
  return (
    <QueryClientProvider client={queryClient}>
      <DynamicProvider client={dynamicClient}>
        <AnchorProviderComponent>
          {children}
        </AnchorProviderComponent>
      </DynamicProvider>
    </QueryClientProvider>
  );
}
```

***

## Step 3: Call a program method

Here's an example of calling a program method and sending a transaction using the connected Dynamic wallet.

> [tab] JavaScript
>
> ```typescript theme={"system"}
> import { createAnchorProvider } from './anchor-provider';
> import { signAndSendTransaction } from '@dynamic-labs-sdk/solana';
>
> async function callYourMethod() {
>   const { program, publicKey, walletAccount } = await createAnchorProvider();
>
>   // Build the transaction using Anchor
>   const tx = await program.methods
>     .yourMethodName()
>     .accounts({
>       user: publicKey,
>       // ... other accounts
>     })
>     .transaction();
>
>   // Sign and send via the Dynamic JS SDK
>   const { signature } = await signAndSendTransaction({
>     transaction: tx,
>     walletAccount,
>   });
>   console.log("Transaction sent:", signature);
> }
> ```

> [tab] React
>
> You can now access the Anchor context anywhere in your component tree:
>
> ```tsx theme={"system"}
> import { useAnchorProvider } from "./AnchorProviderComponent";
> import { useGetWalletAccounts } from "@dynamic-labs-sdk/react-hooks";
> import {
>   isSolanaWalletAccount,
>   signAndSendTransaction,
> } from "@dynamic-labs-sdk/solana";
>
> function MyComponent() {
>   const { program, publicKey } = useAnchorProvider();
>   const { data: walletAccounts = [] } = useGetWalletAccounts();
>   const walletAccount = walletAccounts.find(isSolanaWalletAccount);
>
>   async function callYourMethod() {
>     if (!program || !publicKey || !walletAccount) return;
>
>     // Build the transaction using Anchor
>     const tx = await program.methods
>       .yourMethodName()
>       .accounts({
>         user: publicKey,
>         // ... other accounts
>       })
>       .transaction();
>
>     // Sign and send via the Dynamic JS SDK
>     const { signature } = await signAndSendTransaction({
>       transaction: tx,
>       walletAccount,
>     });
>     console.log("Transaction sent:", signature);
>   }
>
>   return (
>     <div>
>       <p>Connected as: {publicKey?.toBase58() ?? 'Not connected'}</p>
>       <button onClick={callYourMethod} disabled={!program || !walletAccount}>
>         Call your method
>       </button>
>     </div>
>   );
> }
> ```

***

## Summary

By following this guide, you can connect your Solana Anchor programs to your app using Dynamic for wallet management. This setup enables seamless smart contract interactions and transaction signing, leveraging the strengths of both Anchor and Dynamic.

References:

* [Anchor Documentation](https://www.anchor-lang.com/docs)
* [Quickstart (JS SDK)](https://docs.dynamic.xyz/docs/javascript/reference/quickstart.md)
* [Signing and Sending Transactions with Solana](https://docs.dynamic.xyz/docs/javascript/reference/solana/signing-sending-transactions.md)
* [Solana Connection](https://docs.dynamic.xyz/docs/javascript/reference/solana/getting-solana-connection.md)
* [Checking Solana Wallet Account Type](https://docs.dynamic.xyz/docs/javascript/reference/solana/checking-solana-wallet-account-type.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.