V3 is still under development more breaking changes are going to be added here until we cut the first stable version [3.0.0]

Wallet and WalletConnectors

No undesired prompting

No more undesired prompting to reconnect or switch wallets when not required!

Now a wallet can be made primary at any time without extra prompting, even if the wallet is not connected or unlocked.

Users will only be prompted to connect/unlock when sending/signing a transaction if the wallet is not connected or unlocked already.

Wallet object has changed

wallet.authenticated changed to wallet.isAuthenticated wallet.connected is now an async method wallet.isConnected()

The Wallet object has changed and now contains some methods that were previously on the WalletConnector object. Each chain specific wallet has its own methods. The methods specific to the main chains on the wallet object are:

  • EthereumWallet

    • getWalletClient
    • getPublicClient
  • SolanaWallet

    • getConnection
    • getSigner
  • BitcoinWallet

    • signPsbt
    • signPsbts
    • sendRawTransaction
    • sendBitcoin

Note that you should always use our utilities to check that you’re dealing with the correct wallet type before calling these methods:

import { isEthereumWallet } from '@dynamic-labs/ethereum-core';
import { isSolanaWallet } from '@dynamic-labs/solana-core';
import { isBitcoinWallet } from '@dynamic-labs/bitcoin-core';

const { primaryWallet } = useDynamicContext();

if (isEthereumWallet(primaryWallet)) {
 console.log('call any ethereum wallet method')
}

if (isSolanaWallet(primaryWallet)) {
  console.log('call any solana wallet method')
 }

 if (isBitcoinWallet(primaryWallet)) {
  console.log('call any bitcoin wallet method')
 }

Learn more in the Wallet Interactions section.

Wallet connector object has changed

Since we have moved some methods from the connector to the wallet object, the wallet connector object is now slimmed down, you can find the methods and props available on both the connector and the wallet object in the Wallet Interactions section.

As with the wallet object, each chain specific wallet connector has its own methods so we recommend checking out the appropriate section for the chain you are working with.

Example

import { useDynamicContext } from '@dynamic-labs/sdk-react-core'
const { primaryWallet } = useDynamicContext()

const fetchBalance = async () => {
  const balance = await primaryWallet?.connector.getBalance()
}

Smart Wallet connector updates

  • getEOAConnector has been removed

The getEOAConnector method is no longer available, you can use the useSmartWallets hook to get the EOA wallet.

Utils packages renamed

Solana Utils

@dynamic-labs/solana-utils has been renamed to @dynamic-labs/solana-core

Viem Utils

@dynamic-labs/viem-utils has been renamed to @dynamic-labs/ethereum-core

Ethers support refactored

Instead of using the EthersExtension on the Context Provider, you now need to use the ethers-v6 package directly, which exports all of the Ethers specific methods.

// App.tsx
import { EthersExtension } from '@dynamic-labs/ethers-v6'

<DynamicContextProvider
  settings={{
    environmentId: 'XXXXX',
    walletConnectorExtensions: [EthersExtension],
  }}
>
</DynamicContextProvider>

// Main.tsx
import { useDynamicContext } from '@dynamic-labs/sdk-react-core'

const { primaryWallet } = useDynamicContext()
const signer = primaryWallet?.connector.ethers?.getSigner();

UserProfile

Removed props that should be retrieved from the primaryWallet: chain, ens, wallet Remove isAuthenticatedWithAWallet as a prop and added it as a helper method. See isAuthenticatedWithAWallet

Removed props from useDynamicContext

hideEmbeddedWalletTransactionUIs has been removed from useDynamicContext. This is now a toggle in the dashboard.

setPrimaryWallet has been removed. You should use useSwitchWallet instead.

isAuthenticated has been removed. Please refer to this page for other ways to check the login state.

walletConnector has been removed. You can get access to it by getting the primary wallet prop and doing primaryWallet?.connector.

walletConnectorOptions has been removed. You can get access to the available wallet options from the useWalletOptions hook.

walletConnector has been removed. You can get access to it by getting the primary wallet prop and doing primaryWallet?.connector.

Replaced props

  • setDefaultTabIndex replaced with setSelectedTabIndex in useDynamicContext

This function is used to create wallet list views.

Package restructuring

  • ethers-v5 no longer available

We no longer support ethers v5. If you are using ethers v5 and wish to keep using ethers with Dynamic, please upgrade to ethers v6 by following this guide, and then switch to using our ethers-v6 package. They have the same usability.

  • createWalletClientFromWallet has been removed

The createWalletClientFromWallet function is no longer available, you can use the getWalletClient method on the wallet object instead.

  • rpcProviders no longer available in the sdk-react-core package

The type DynamicRPCProviders that used to be exported from @dynamic-labs/sdk-react-core is no longer available and has been replaced with individual packages i.e. @dynamic-labs/ethereum-core & @dynamic-labs/solana-core:

  • ITurnkeySolanaSigner renamed to IEmbeddedWalletSolanaSigner and import path changed

Events arguments

  • onAuthSuccess doesn’t return an authToken anymore

  • onEmbeddedWalletCreated returns the user instead of the authToken

You can call getAuthToken to access the authToken at any time!

Other

  • Polyfill for Solana Embedded Wallet users

You may need to polyfill the ‘crypto’ module.

webpack.config.js:

config.resolve.fallback = {
  ...config.resolve.fallback,
  crypto: require.resolve('crypto-browserify'),
}

vite.config.ts

import { nodePolyfills } from 'vite-plugin-node-polyfills';

plugins: [
      nodePolyfills({
        globals: {
          global: true,
        },
        include: [],
      }),
    ],

Renamed Hooks

useSelectWalletOption has been renamed to useWalletOptions

New Hooks

  • Re-initialize the SDK (useReinitialize)
import {
  DynamicContextProvider,
  useReinitialize,
} from '@dynamic-labs/sdk-react-core';

const ReInitButton = () => {
  const reinitialize = useReinitialize();

  return (
    <button onClick={reinitialize}>Reinitialize</button>
  );
}

const App = () => {
  return (
    <DynamicContextProvider>
      <ReInitButton />
    </DynamicContextProvider>
  )
}
  • Trigger state refresh (useRefreshUser)
import {
  DynamicContextProvider,
  useRefreshUser,
} from '@dynamic-labs/sdk-react-core';

const RefreshButton = () => {
  const refresh = useRefreshUser();

  return (
    <button onClick={refresh}>Reinitialize</button>
  );
}

const App = () => {
  return (
    <DynamicContextProvider>
      <RefreshButton />
    </DynamicContextProvider>
  )
}