Need Help to migrate from v9 to v10

  • Describe your issue or question:

    • Which platform or framework are you using (e.g., React, Vue, Android, iOS, Unity, Node, etc.)

Nuxt3

  • Which Web3Auth/ Embedded Wallet SDK (SDK Name and version) are you using?
"@web3auth/ethereum-provider": "^9.7.0",

"@web3auth/modal": "^10.5.4",
  • What is not working as expected?

We’re implementing wallet integration using JWTs obtained from our own authentication. In V9, we could integrate using NO MODAL and UX_MODE with redirect settings, but I don’t know how to do it in V10. Please advise.

  • Code snippets: Include the portion of your code that is causing problems.

import {
Web3AuthNoModal,
WALLET_CONNECTORS,
AUTH_CONNECTION,
LOGIN_MODE,
UX_MODE,
type IProvider,
WEB3AUTH_NETWORK,
type WEB3AUTH_NETWORK_TYPE,
} from ‘@web3auth/no-modal’
import {
createPublicClient,
createWalletClient,
custom,
} from ‘viem’
import { SiweMessage } from ‘siwe’
import type { RuntimeConfig } from ‘nuxt/schema’
import { useRuntimeConfig } from ‘#app
import { EIP2612_PERMIT_TYPE, ERC20_ABI, ERC20_PERMIT_ABI, EXCHANGE_ABI, type PermitSignature } from ‘@/types/erc20’

// ブラウザの言語設定用の定数
const LANGUAGES = {
en: ‘en’,
ja: ‘ja’,
} as const

type LANGUAGE_TYPE = typeof LANGUAGES[keyof typeof LANGUAGES]

export class Web3AuthService {
private web3auth: Web3AuthNoModal | null = null
private provider: IProvider | null = null
private initialized: boolean = false
private config: RuntimeConfig = useRuntimeConfig()

// constructor() {
// // 空のコンストラクタ
// }

async init() {
try {
// すでに初期化済みの場合は現在の状態を返す
if (this.initialized && this.web3auth) {
const isConnected = this.web3auth.connected
// 接続状態をLocalStorageに保存
if (isConnected) {
setLocalStorage(‘web3auth_is_connected’, ‘true’)
}
return {
isLoggedIn: isConnected,
provider: this.provider,
}
}

  // Web3Authの設定情報を環境変数から取得
  const clientId = this.config.public.web3AuthClientId as string
  if (!clientId) {
    console.error('Web3Auth Client ID is missing')
    return { isLoggedIn: false, provider: null }
  }

  // Web3Auth Network設定
  const web3AuthNetwork = (this.config.public.web3AuthNetwork as string) || WEB3AUTH_NETWORK.SAPPHIRE_DEVNET

  // Chain ID設定
  const chainIdStr = (this.config.public.chainId as string) || 'aa36a7'

  this.web3auth = new Web3AuthNoModal({
    clientId,
    web3AuthNetwork: web3AuthNetwork as WEB3AUTH_NETWORK_TYPE,
    sessionTime: 86400 * 30,
    defaultChainId: chainIdStr,
    enableLogging: true,
    walletServicesConfig: {
      language: this.getBrowserLanguage(),
    } as WalletServicesConfig,
  })

  await this.web3auth.init()
  this.provider = this.web3auth.provider
  this.initialized = true

  return {
    isLoggedIn: this.web3auth.connected,
    provider: this.provider,
  }
} catch (error) {
  console.error('Web3Auth initialization error:', error)
  return {
    isLoggedIn: false,
    provider: null,
  }
}

}

async loginWithAccessToken(accessToken: string) {
if (!this.web3auth) {
console.error(‘web3auth not initialized yet’)
return null
}

if (!accessToken) {
  console.error('Access token is missing')
  return null
}

try {
  // 既存のセッションをクリア
  if (this.web3auth.connected) {
    await this.logout()
  }

  try {
    const web3authProvider = await this.web3auth.connectTo(WALLET_CONNECTORS.AUTH, {
      authConnection: AUTH_CONNECTION.CUSTOM,
      authConnectionId: this.config.public.web3AuthJwtVerifier as string,
      extraLoginOptions: {
        uxMode: UX_MODE.REDIRECT, // <- v9 is possible but v10 is not
        domain: window.location.origin,
        idToken: accessToken,
        redirectUri: `${window.location.origin}/auth-callback`,
        client_id: this.config.public.web3AuthClientId as string,
        userIdField: 'sub',
        isUserIdCaseSensitive: true,
        loginMode: LOGIN_MODE.NO_MODAL,
      },
    }, LOGIN_MODE.NO_MODAL)

    // プロバイダーを設定
    this.provider = web3authProvider

    return web3authProvider
  } catch (connectError) {
    console.error('Error connecting to Web3Auth:', connectError)
    return null
  }
} catch (error) {
  console.error('Access token login error:', error)
  return null
}

}

// ログアウト
async logout() {
try {
if (!this.web3auth) {
console.error(‘web3auth not initialized yet’)
return false
}

  if (this.web3auth.connected) {
    await this.web3auth.logout()
    this.provider = null

    // LocalStorageの接続状態をクリア
    removeLocalStorage('web3auth_is_connected')
    return true
  } else {
    return true
  }
} catch (error) {
  console.error('ログアウトエラー:', error)
  return false
}

}

getWeb3Auth() {
return this.web3auth
}

getProvider() {
return this.provider
}

isConnected() {
return this.web3auth?.connected
}

// ブラウザの言語設定を取得し、サポートされている言語に変換するメソッド
private getBrowserLanguage(): LANGUAGE_TYPE {
const localeCookie = useCookie(‘i18n_redirected’)
if (!localeCookie.value) {
return LANGUAGES.en
}
return localeCookie.value as LANGUAGE_TYPE
}
}

Hi 鍾敏 — thanks for the clear description and the code sample. You’re asking about migrating a Web3Auth no-modal + JWT redirect flow from v9 to v10 — that’s a migration / integration question, so I gathered the relevant info and a suggested migration path below.

Parsed details from your message

  • Issue type: Migration (v9 → v10) for no-modal / JWT redirect flow
  • Platform / framework: Nuxt3
  • SDKs / packages in your message:
  • Code snippets: provided (init + loginWithAccessToken + logout)
  • Links / images: none

Observations / likely cause

  • You currently mix v9 (ethereum-provider) and v10 (modal). v10 revamped Web3Auth into a core + adapters model. The older “no-modal” style lives in older packages; in v10 the recommended way to run a no-UI (no-modal) redirect flow is to use Web3Auth Core + the OpenLogin adapter (configured for uxMode: “redirect”).
  • Primary action: align package versions and switch to the v10 core + openlogin-adapter approach for a JWT redirect/no-modal UX.

Proposed migration steps (high level)

  1. Align versions

    • Make sure your @web3auth packages are all v10-compatible. Either upgrade @web3auth/ethereum-provider to a v10-compatible package or use the v10 core + adapters. Mixing major versions can cause missing API/behavior.
  2. Use Web3Auth Core + OpenLogin adapter for no-modal redirect

    • In v10 the core + adapters model replaces the old “no-modal” flows. Use @web3auth/core (or Web3Auth) plus @web3auth/openlogin-adapter and configure the adapter with adapterSettings. Set uxMode: “redirect” and redirectUrl for the redirect flow.
  3. Login with your JWT (custom verifier)

    • Use the openlogin adapter’s login flow for JWT (loginProvider: ‘jwt’) and pass extraLoginOptions: { id_token: accessToken, domain, userIdField, … } similar to what you already do. The adapter will perform the redirect when uxMode is redirect.
  4. Callback handling

    • On your redirect callback page (/auth-callback) call init() on Web3AuthCore so it can restore the session / complete the redirect flow (this is how it usually works with redirect flows in adapter-based systems).

Minimal example (v10-style, adapt to Nuxt3/service class)

  • (Install) npm i @web3auth/core @web3auth/openlogin-adapter

  • Skeleton (pseudo-code to adapt into your class):
    import { Web3Auth } from “@web3auth/core”
    import { OpenloginAdapter } from “@web3auth/openlogin-adapter”

    const web3auth = new Web3Auth({
    clientId,
    chainConfig: { chainNamespace: “eip155”, chainId: 0x${chainIdStr} },
    web3AuthNetwork: web3AuthNetwork,
    })

    const openloginAdapter = new OpenloginAdapter({
    adapterSettings: {
    uxMode: “redirect”,
    redirectUrl: ${window.location.origin}/auth-callback,
    // loginConfig / verifier config may be required depending on your Web3Auth Console setup
    },
    loginConfig: {
    jwt: {
    verifier: this.config.public.web3AuthJwtVerifier, // your verifier name
    },
    },
    })

    web3auth.configureAdapter(openloginAdapter)
    await web3auth.init()

    // Trigger login (this will redirect when uxMode = redirect)
    await web3auth.connectTo(“openlogin”, {
    loginProvider: “jwt”,
    extraLoginOptions: {
    id_token: accessToken,
    domain: window.location.origin,
    userIdField: “sub”,
    isUserIdCaseSensitive: true,
    },
    })

Notes and caveats

  • The above code is a conceptual v10 pattern — adapter property names (loginConfig, adapterSettings, connectTo signature) are the correct high-level pieces to use, but small naming differences can exist between versions; check the v10 OpenLogin adapter docs for exact params.
  • On redirect flows you typically do NOT get a provider object immediately — the browser will leave and then return to your callback route. On that page call init() (or the specific SDK redirect handler) to complete the session restore and obtain the provider.
  • Make sure your Web3Auth Console (verifiers) is configured for your JWT verifier and that the verifier name matches what you pass.

What I recommend you do next (so I can help faster)

  1. Confirm your package.json (list of @web3auth/* versions) so I can confirm exact upgrade steps.
  2. Tell me whether you prefer using Web3Auth Core + OpenLogin adapter (no UI) in v10 — if yes I can give a more exact Nuxt3-ready code example for your class/service file.
  3. If you’ve tried a v10 approach and hit errors, share the browser console logs / screenshots from the callback and init steps.

If you want I can: (A) produce a complete Nuxt3 service class using the v10 core + openlogin-adapter that mirrors your current class (init, loginWithAccessToken, logout, callback handling), or (B) point to the specific v10 OpenLogin adapter docs. Which would you prefer?

Note: This response was generated by an AI bot and may require further verification. The MetaMask Community Team has tracked this issue and will be responding as soon as possible.

Additionally, we would recommend you to join our biweekly Office Hours to get this resolved even faster. MetaMask Developer Office Hours

Thank you for your prompt response.

I want to know the below your solution

>(A) produce a complete Nuxt3 service class using the v10 core + openlogin-adapter that mirrors your current class (init, loginWithAccessToken, logout, callback handling)

You do not require Openlogin Adapter or ethereum provider with v10 SDK. Please check our docs here: MetaMask Embedded Wallets | MetaMask