We provide a lightweight viem extension to our client which introduces 2 simple methods to integrate with Viem: client.viem.createPublicClient() and client.viem.createWalletClient().
Since our client was built with a modular approach, this package comes as a standalone, so to reduce the client’s package size.

Installation

Simply run the following in your terminal:
npm i @dynamic-labs/viem-extension

Creating Viem clients

First, extend your client with our extension:
import { ViemExtension } from '@dynamic-labs/viem-extension'

export const dynamicClient = createClient({
  environmentId: 'YOUR-ENVIRONMENT-ID',
}).extend(ViemExtension())
Now you can easily leverage all the power of Viem by creating wallet and public clients:
import { mainnet } from 'viem/chains'

// Create a public client using one of viem's provided chains
const publicViemClient = dynamicClient.viem.createPublicClient({ chain: mainnet })

const lookupBalance = (address: `0x${string}`) =>
  publicViemClient.getBalance({ address })

// Create a wallet client
const walletViemClient = dynamicClient.viem.createWalletClient({
  wallet: dynamicClient.wallets.primary,
})

const signMessage = (message: string) =>
  walletViemClient.signMessage({ message })

Sending Transactions

Here’s a complete example of how to send a transaction using the viem extension:
import React, { useState } from 'react';
import { View, TextInput, Button, Text, Alert } from 'react-native';
import { parseEther } from 'viem';
import { mainnet } from 'viem/chains';

// Assuming you have your dynamicClient set up as shown above
import { dynamicClient } from './your-client-setup';

export const SendTransactionExample = () => {
  const [toAddress, setToAddress] = useState('');
  const [amount, setAmount] = useState('');
  const [txHash, setTxHash] = useState('');
  const [isLoading, setIsLoading] = useState(false);

  const sendTransaction = async () => {
    if (!toAddress || !amount) {
      Alert.alert('Error', 'Please fill in all fields');
      return;
    }

    if (!dynamicClient.wallets.primary) {
      Alert.alert('Error', 'No wallet connected');
      return;
    }

    setIsLoading(true);
    setTxHash('');

    try {
      // Create a wallet client using the viem extension
      const walletClient = dynamicClient.viem.createWalletClient({
        wallet: dynamicClient.wallets.primary,
      });

      // Send the transaction
      const hash = await walletClient.sendTransaction({
        to: toAddress as `0x${string}`,
        value: parseEther(amount),
      });

      setTxHash(hash);
      
      Alert.alert(
        'Success', 
        `Transaction sent! Hash: ${hash}`
      );
    } catch (error) {
      console.error('Transaction failed:', error);
      Alert.alert('Error', 'Transaction failed. Please try again.');
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <View style={{ padding: 20 }}>
      <Text style={{ fontSize: 18, marginBottom: 10 }}>Send Transaction</Text>
      
      <TextInput
        placeholder="Recipient Address (0x...)"
        value={toAddress}
        onChangeText={setToAddress}
        style={{ 
          borderWidth: 1, 
          borderColor: '#ccc', 
          padding: 10, 
          marginBottom: 10 
        }}
      />
      
      <TextInput
        placeholder="Amount in ETH (e.g., 0.01)"
        value={amount}
        onChangeText={setAmount}
        keyboardType="numeric"
        style={{ 
          borderWidth: 1, 
          borderColor: '#ccc', 
          padding: 10, 
          marginBottom: 10 
        }}
      />
      
      <Button
        title={isLoading ? "Sending..." : "Send Transaction"}
        onPress={sendTransaction}
        disabled={isLoading}
      />
      
      {txHash && (
        <Text style={{ marginTop: 10, fontSize: 12 }}>
          Transaction Hash: {txHash}
        </Text>
      )}
    </View>
  );
};
For more details on transaction options and methods, see the viem sendTransaction documentation. You can read more about our viem integration here.