viem

repository·main·Indexed 11 days ago

https://github.com/wevm/viem

A lightweight, high-performance TypeScript interface for Ethereum providing JSON-RPC abstractions and first-class support for smart contract interactions. Features include full type safety via ABI inference, native BigInt support, and comprehensive tools for Account Abstraction, including Smart Account signing (signMessage, signTypedData, signUserOperation) and Coinbase Smart Account integration via toCoinbaseSmartAccount.

Tokens
360.1K
Snippets
1.2K
Records
1.6K
Agent score
85%

What's inside viem

  1. Overview of viem features

    main

    viem is a lightweight, high-performance TypeScript interface for Ethereum. Key features include:

    • JSON-RPC Abstractions: Simplifies interacting with the Ethereum JSON-RPC API.
    • Smart Contract Support: First-class APIs for contract interactions.
    • Type Safety: Full TypeScript support with the ability to infer types directly from ABIs and EIP-712 Typed Data.
    • Native BigInt: Uses browser-native BigInt instead of heavy BigNumber libraries.
    • Wallet Integration: Supports Browser Extensions, WalletConnect, and Private Key Wallets.
    • ABI Utilities: Tools for encoding, decoding, and inspecting ABIs.
    • Developer Tooling Support: Native support for Anvil, Hardhat, and Ganache.
    • Testing: Test suites designed to run against forked Ethereum networks.
  2. Overview of Tempo Earn vaults

    main

    Tempo Earn vaults allow users to deposit assets into yield venues. In exchange, the vault issues Earn shares (TIP-20 tokens) that represent a proportional claim on the vault's assets. The value of these shares fluctuates as the underlying venue earns yield and the vault accrues fees.

    Key terminology:

    • Assets: The TIP-20 tokens accepted by a vault for deposit.
    • Earn shares: TIP-20 tokens representing a claim on the vault's assets.
    • Venue shares: Positions held by the vault within its underlying yield venue.
  3. Overview of MetaMask Smart Account implementations

    main

    MetaMask Smart Accounts offers three distinct implementation types depending on your use case:

    1. Hybrid smart account: Combines different account features.
    2. Multisig smart account: Uses multi-signature logic for security.
    3. Stateless 7702 smart account: Utilizes EIP-7702 for stateless account capabilities.

    To implement these in your application, use the toMetaMaskSmartAccount function provided by the @metamask/smart-accounts-kit library.

  4. Overview of TIP-20 channel vouchers

    main

    A voucher is a signed, off-chain promise from a payer indicating that a channel has paid a specific cumulative amount.

    Key characteristics:

    • Workflow: The payer signs a new voucher for each payment with an increasing cumulative amount. The payee can then settle the most recent voucher on-chain at their discretion.
    • Benefits: Because vouchers are processed off-chain, payments are instant and incur no gas fees until the final settlement occurs on-chain.
    • Use Case: This mechanism is used for TIP-20 payment channels to enable 'pay-as-you-go' machine payments.
  5. Configure factory and factoryData for undeployed Smart Accounts

    main

    When working with a Smart Account that has not yet been deployed, you must provide the factory and factoryData parameters to getPaymasterStubData.

    • factory: The Address of the Account Factory.
    • factoryData: The Hex call data used to execute the deployment on the Account Factory.

    Warning: These properties should only be populated when the Smart Account has not been deployed yet.

    const paymasterArgs = await paymasterClient.getPaymasterStubData({
      // ... other required params
      factory: '0xfb6dab6200b8958c2655c3747708f82243d3f32e',
      factoryData: '0xf14ddffc000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb9226600000000000000000000000000000000000000000000000000000000000000000',
    })
  6. Configure Paymaster for `estimateUserOperationGas`

    main

    The paymaster option in estimateUserOperationGas allows you to set up sponsorship for the User Operation. You can provide several types of values:

    • Address: Provide a specific Paymaster contract address.
    • true: Tells the client to assume the Bundler Client supports Paymaster RPC methods (like pm_getPaymasterData).
    • PaymasterClient: Use a dedicated Paymaster Client.
    • Custom Functions: Provide custom logic for sponsorship.
  7. Understand the return value of writeContract

    main

    Unlike readContract, which returns the data returned by the function, writeContract only returns a Hash (the transaction hash).

    If you need to see what the return data of a write function would be, use simulateContract. simulateContract does not execute a transaction and does not require gas.

  8. Hoist an account on a Wallet Client

    main

    To avoid passing the account object to every transaction call, you can hoist the account directly onto the WalletClient when creating it. This makes the account the default signer for all subsequent actions performed by that client.

    import { createWalletClient, http } from 'viem'
    import { privateKeyToAccount } from 'viem/accounts'
    
    export const walletClient = createWalletClient({
      account: privateKeyToAccount('0x...'),
      transport: http()
    })
    
    // Now you can call sendTransaction without passing the account
    const hash = await walletClient.sendTransaction({
      to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
      value: 1000000000000000000n
    })
  9. Use `token.transferSync` vs `token.transfer`

    main

    The token.transferSync action is a convenience method that waits for the transaction to be included in a block before returning the result.

    For better performance, use the non-sync token.transfer action, which returns the transaction hash immediately. You can then manually wait for the receipt using client.waitForTransactionReceipt.

    import { Actions } from 'viem/tempo'
    import { client } from './viem.config'
    
    // Non-sync version for performance optimization
    const hash = await client.token.transfer({
      amount: { formatted: '10.5' },
      to: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb',
      token: 'pathusd',
    })
    
    const receipt = await client.waitForTransactionReceipt({ hash })
    
    // Extract event data from logs
    const { args } = Actions.token.transfer.extractEvent(receipt.logs)
  10. Perform Deployless Calls

    main

    A Deployless Call allows you to call a function on a contract that has not yet been deployed to the blockchain. This is a common pattern when interacting with contracts like ERC-4337 Smart Accounts where the address is derived but the bytecode hasn't been deployed.

    There are two primary ways to perform this in Viem:

    1. Via Bytecode: Call the function by providing the contract's bytecode directly.
    2. Via a Deploy Factory: "Temporarily deploys" a contract using a provided Deploy Factory and then calls the function on the resulting address.

    Note: This pattern is also accessible via the readContract and getContract APIs.