Skip to content

@rainbow-me/rainbowkit@2.2.0

Latest
Compare
Choose a tag to compare
@DanielSinclair DanielSinclair released this 15 Oct 09:09
· 6 commits to main since this release
d1c0e9b

Minor Changes

  • f02bced: The Authentication API now supports ERC-1271 and ERC-6492 for smart contract signature verification to enable Sign-in with Ethereum for Smart Contract Wallets, including Coinbase Smart Wallet and Argent.

    We have also deprecated the siwe and ethers peer dependencies in favor of viem/siwe to make RainbowKit even more seamless.

    No changes are necessary for dApps that don't rely on the Authentication API.

    Follow the appropriate steps below to migrate.

    NextAuth Authentication

    1. Remove siwe and ethers
    npm uninstall siwe ethers
    1. Upgrade RainbowKit, rainbowkit-siwe-next-auth, and viem
    npm i @rainbow-me/rainbowkit@^2.2.0 rainbow-me/rainbowkit-siwe-next-auth@^0.5.0 viem@^2.12.0
    1. Create a Public Client

    This allows viem to verify smart contract signatures.

    const config = getDefaultConfig({
      /* your config */
    });
    + const publicClient = config.getClient().extend(publicActions);
    1. Adjust your authorize implementation in /api/auth/[...nextauth].ts
    - import { SiweMessage } from 'siwe';
    + import {
    +   type SiweMessage,
    +   parseSiweMessage,
    +   validateSiweMessage,
    + } from 'viem/siwe';
    
    export function getAuthOptions(req: IncomingMessage): NextAuthOptions {
      const providers = [
        CredentialsProvider({
          async authorize(credentials: any) {
    
    -       const siwe = new SiweMessage(
    -         JSON.parse(credentials?.message || '{}'),
    -       );
    +       const siweMessage = parseSiweMessage(
    +         credentials?.message,
    +       ) as SiweMessage;
    
    +       if (!validateSiweMessage({
    +         address: siweMessage?.address,
    +         message: siweMessage,
    +       })) {
    +         return null;
    +       }
    
            /* ... */
    
    -       await siwe.verify({ signature: credentials?.signature || '' });
    +       const valid = await publicClient.verifyMessage({
    +         address: siweMessage?.address,
    +         message: credentials?.message,
    +         signature: credentials?.signature,
    +       });
    
    +       if (!valid) {
    +         return null;
    +       }
          },
          /* ... */
        })
      ]
    }

    Reference the with-next-siwe-next-auth example for more guidance.

    Custom Authentication

    1. Remove siwe and ethers
    npm uninstall siwe ethers
    1. Upgrade RainbowKit and viem
    npm i @rainbow-me/rainbowkit@^2.2.0 viem@^2.12.0
    1. Create a Public Client

    This allows viem to verify smart contract signatures.

    const config = getDefaultConfig({
      /* your config */
    });
    
    + const publicClient = config.getClient().extend(publicActions);
    1. Adjust your createAuthenticationAdapter implementation
    - import { SiweMessage } from 'siwe';
    + import { createSiweMessage } from 'viem/siwe';
    
    createAuthenticationAdapter({
      getNonce: async () => {
        const response = await fetch('/api/nonce');
        return await response.text();
      },
    
      createMessage: ({ nonce, address, chainId }) => {
    -   return new SiweMessage({
    +   return createSiweMessage({
          domain: window.location.host,
          address,
          statement: 'Sign in with Ethereum to the app.',
          uri: window.location.origin,
          version: '1',
          chainId,
          nonce,
        });
      },
    
    - getMessageBody: ({ message }) => {
    -   return message.prepareMessage();
    - },
    
      /* ... */
    })
    1. Adopt generateSiweNonce
    - import { generateNonce } from 'siwe';
    + import { generateSiweNonce } from 'viem/siwe';
    
    - req.session.nonce = generateNonce();
    + req.session.nonce = generateSiweNonce();
    1. Adopt parseSiweMessage and verifyMessage if your Verify handler
    - import { SiweMessage } from 'siwe';
    + import { parseSiweMessage, type SiweMessage } from 'viem/siwe';
    
    const { message, signature } = req.body;
    - const siweMessage = new SiweMessage(message);
    - const { success, error, data } = await siweMessage.verify({
    -  signature,
    - });
    + const siweMessage = parseSiweMessage(message) as SiweMessage;
    + const success = await publicClient.verifyMessage({
    +   address: siweMessage.address,
    +   message,
    +   signature,
    + });
    
    - if (!success) throw error;
    + if (!success) throw new Error('Invalid signature.');
    
    - if (data.nonce !== req.session.nonce)
    + if (siweMessage.nonce !== req.session.nonce)
    +   return res.status(422).json({ message: 'Invalid nonce.' });

    Reference the with-next-siwe-iron-session example for more guidance.