Skip to main content

Standard Integration

For standard wallet connections (e.g., MetaMask, WalletConnect), use the simple adapter to pass the Dynamic authentication token.
import { SunbreakProvider } from "@tdfc/sunbreak-react";
import { useDynamicContext, getAuthToken } from "@dynamic-labs/sdk-react-core";

export function DynamicExample() {
  const { user, primaryWallet } = useDynamicContext();
  const address = primaryWallet?.address?.toLowerCase();

  const adapter = {
    name: "dynamic" as const,
    envId: process.env.NEXT_PUBLIC_DYNAMIC_ENV_ID!,
    getToken: async () => getAuthToken(),
  };

  return (
    <SunbreakProvider
      base={process.env.NEXT_PUBLIC_SUNBREAK_BASE!}
      clientId={process.env.NEXT_PUBLIC_SUNBREAK_CLIENT_ID!}
      wallet={address}
      providerAdapter={adapter}
      refreshDeps={[address, user]}
    >
      {/* App */}
    </SunbreakProvider>
  );
}

Embedded Wallets

If you use Dynamic Embedded Wallets, Dynamic may issue an initial authentication token (containing only an email) before the embedded wallet is fully generated. To prevent Sunbreak from verifying a token that lacks a wallet binding, use this robust adapter. It inspects the JWT to ensure a blockchain credential exists before returning it.
import React, { useMemo } from "react";
import { SunbreakProvider, ProviderAdapter } from "@tdfc/sunbreak-react";
import { useDynamicContext, getAuthToken } from "@dynamic-labs/sdk-react-core";

export function DynamicEmbeddedExample() {
  const { user, primaryWallet } = useDynamicContext();
  const address = primaryWallet?.address?.toLowerCase();

  const adapter: ProviderAdapter = useMemo(
    () => ({
      name: "dynamic",
      envId: process.env.NEXT_PUBLIC_DYNAMIC_ENV_ID!,
      getToken: async () => {
        const token = getAuthToken();
        if (!token) return null;

        try {
          // Dynamic may initially issue an email-only token while the embedded
          // wallet is being generated. We parse the token to ensure it contains
          // a blockchain credential before sending it to Sunbreak.
          const [, payload] = token.split(".");
          const decoded = JSON.parse(atob(payload));

          const hasWallet = decoded.verified_credentials?.some(
            (vc: { format: string }) => vc.format === "blockchain"
          );

          return hasWallet ? token : null;
        } catch {
          return null;
        }
      },
    }),
    [user, user?.verifiedCredentials]
  );

  return (
    <SunbreakProvider
      base={process.env.NEXT_PUBLIC_SUNBREAK_BASE!}
      clientId={process.env.NEXT_PUBLIC_SUNBREAK_CLIENT_ID!}
      wallet={address}
      providerAdapter={adapter}
      // Essential: Re-run the adapter when verified credentials update
      refreshDeps={[address, user, user?.verifiedCredentials]}
    >
      {/* App */}
    </SunbreakProvider>
  );
}
Notes
  • refreshDeps: When using Embedded Wallets, you must include user?.verifiedCredentials in refreshDeps. This ensures the SDK attempts verification again once the wallet is successfully added to the user’s profile.
  • Environment: Ensure envId matches your Dynamic environment ID.