Introducing account abstraction for zkSync enabled chains. This guide will walk you through the setup of zkSync account abstraction (with or without global wallets).

Initial setup

1

Enable the zkSync chain in the Dynamic Dashboard

In the EVM section of your Dynamic Dashboard, toggle on a zkSync enabled chain and click Save.

When using zkSync and global wallets, make sure that the zkSync enabled chain is the only one selected.

Now, go to the Account Abstraction section, enter the optional factoryAddress and paymasterAddress (if you have one). Save the settings and then enable the toggle next to the ZkSync section.

2

Choose who gets a SCW

On the same configuration page as the step above, you’ll see there are two different types of configuration for issuing smart contract wallets (SCWs) in Dynamic - the wallet level and the user level.

  • Wallet level

Choose whether to issue SCWs to all wallets, or only to embedded wallets. Note that for the former, you will need to handle the UI and frontend yourself.

  • User level

Choose whether to issues SCWs to all your users (existing included next time they log in), or just new users.

3

Choose if your users see both the signer and smart wallet

On the same configuration page as the 2 steps above, you’ll see there is a setting for how the Dynamic SDK treats the signer and the smart wallet - only the smart wallet or both the smart wallet and signer.

  • Show Smart Wallet Only

Only allows you to interact with the smart wallet directly.

  • Show Smart Wallet & Signer

Treats the smart wallet and signer as separate wallets which you can switch between.

4

Use the wallet connector

Install the following packages:

  • @dynamic-labs/sdk-react-core
  • @dynamic-labs/ethereum
  • @dynamic-labs/ethereum-aa-zksync
  import { DynamicContextProvider, DynamicWidget } from "@dynamic-labs/sdk-react-core";
  import { EthereumWalletConnectors } from "@dynamic-labs/ethereum";
  import { ZkSyncSmartWalletConnectors } from "@dynamic-labs/ethereum-aa-zksync";

  const App = () => (
    <DynamicContextProvider
      settings={{
        environmentId: "YOUR_ENVIRONMENT_ID",
        walletConnectors: [
          EthereumWalletConnectors,
          ZkSyncSmartWalletConnectors
        ],
      }}
    >
      <DynamicWidget />
    </DynamicContextProvider>
  )

  export default App;
5

Send a transaction

    import { isZkSyncConnector } from '@dynamic-labs/ethereum-aa-zksync';

    ...

    const sendTransaction = async (toAddress, amount) => {
        if (!primaryWallet?.connector || !isZkSyncConnector(primaryWallet.connector)) {
            return;
        }

        // get the wallet client which is the zksync-sso ecdsa client
        const walletClient = primaryWallet.getWalletClient();

        if (!walletClient) {
            return;
        }

        const transactionHash = await walletClient.sendTransaction({
            amount,
            toAddress,
            data: '0x' // required input until zksync fixes in their SDK
        });
    }