diff --git a/packages/adapters/bitcoin/src/connectors/TrezorConnector/index.ts b/packages/adapters/bitcoin/src/connectors/TrezorConnector/index.ts
index bda2db6827..400fe701a0 100644
--- a/packages/adapters/bitcoin/src/connectors/TrezorConnector/index.ts
+++ b/packages/adapters/bitcoin/src/connectors/TrezorConnector/index.ts
@@ -591,15 +591,27 @@ export class TrezorConnector extends ProviderEventEmitter implements BitcoinConn
return
}
- await getTrezorConnect().init({
- manifest: {
- email: 'support@reown.com',
- appUrl: typeof window === 'undefined' ? 'https://reown.com' : window.location.origin,
- appName: 'Reown AppKit'
- },
- lazyLoad: true,
- popup: true
- })
+ try {
+ await getTrezorConnect().init({
+ manifest: {
+ email: 'support@reown.com',
+ appUrl: typeof window === 'undefined' ? 'https://reown.com' : window.location.origin,
+ appName: 'Reown AppKit'
+ },
+ lazyLoad: true,
+ popup: true
+ })
+ } catch (error) {
+ /*
+ * Trezor Connect is a page-global singleton: the host app (or another
+ * connector) may have initialized it first, which init() reports as an
+ * error even though the instance is fully usable.
+ */
+ const message = error instanceof Error ? error.message : String(error)
+ if (!message.toLowerCase().includes('already initialized')) {
+ throw error
+ }
+ }
this.initialized = true
diff --git a/packages/adapters/ethers5/package.json b/packages/adapters/ethers5/package.json
index 5df7057c3f..09fd4dbd53 100644
--- a/packages/adapters/ethers5/package.json
+++ b/packages/adapters/ethers5/package.json
@@ -26,6 +26,7 @@
"@reown/appkit-scaffold-ui": "workspace:*",
"@reown/appkit-utils": "workspace:*",
"@reown/appkit-wallet": "workspace:*",
+ "@trezor/connect-web": "9.7.3",
"@walletconnect/universal-provider": "2.23.7",
"valtio": "2.1.7"
},
diff --git a/packages/adapters/ethers5/src/client.ts b/packages/adapters/ethers5/src/client.ts
index 0c6886450f..087bcb9902 100644
--- a/packages/adapters/ethers5/src/client.ts
+++ b/packages/adapters/ethers5/src/client.ts
@@ -15,6 +15,7 @@ import { ConstantsUtil, PresetsUtil } from '@reown/appkit-common'
import {
AdapterBlueprint,
AssetController,
+ type ChainAdapterConnector,
ChainController,
type CombinedProvider,
type Connector,
@@ -42,6 +43,7 @@ import {
} from '@reown/appkit-utils/ethers'
import type { W3mFrameProvider } from '@reown/appkit-wallet'
+import { TrezorConnector } from './connectors/TrezorConnector/index.js'
import { Ethers5Methods } from './utils/Ethers5Methods.js'
export interface EIP6963ProviderDetail {
@@ -273,6 +275,15 @@ export class Ethers5Adapter extends AdapterBlueprint {
})
}
})
+
+ const trezorConnector = TrezorConnector.getWallet({
+ requestedChains: this.getCaipNetworks(),
+ requestedCaipNetworkId: ChainController.getActiveCaipNetwork(CommonConstantsUtil.CHAIN.EVM)
+ ?.caipNetworkId
+ })
+ if (trezorConnector) {
+ this.addConnector(trezorConnector as unknown as ChainAdapterConnector)
+ }
}
private async disconnectAll() {
diff --git a/packages/adapters/ethers5/src/connectors/TrezorConnector/index.ts b/packages/adapters/ethers5/src/connectors/TrezorConnector/index.ts
new file mode 100644
index 0000000000..20e544d30c
--- /dev/null
+++ b/packages/adapters/ethers5/src/connectors/TrezorConnector/index.ts
@@ -0,0 +1,459 @@
+import * as TrezorConnectWeb from '@trezor/connect-web'
+import { utils } from 'ethers'
+
+import type { CaipNetwork, CaipNetworkId } from '@reown/appkit-common'
+import { CoreHelperUtil, type Provider, type RequestArguments } from '@reown/appkit-controllers'
+
+/**
+ * Standard Ethereum derivation path, first account. Matches the address
+ * MetaMask and Ledger Live derive for the same seed, so funds appear where
+ * users expect them.
+ *
+ * Trezor firmware may reject signing for chains with their own registered
+ * SLIP-44 coin type (e.g. Rootstock: 137 mainnet / 37310 testnet) from this
+ * path with "Forbidden key path" unless the device's Safety Checks setting
+ * is set to "Prompt".
+ */
+const ETH_DERIVATION_PATH = "m/44'/60'/0'/0/0"
+
+interface TrezorResponse
{
+ success: boolean
+ payload: P & { error?: string; code?: string }
+}
+
+interface TrezorConnectApi {
+ init(settings: {
+ manifest: { email: string; appUrl: string; appName?: string }
+ lazyLoad?: boolean
+ popup?: boolean
+ }): Promise
+ ethereumGetAddress(params: {
+ path: string
+ showOnTrezor?: boolean
+ }): Promise>
+ ethereumSignTransaction(params: {
+ path: string
+ transaction: {
+ to: string
+ value: string
+ gasPrice: string
+ gasLimit: string
+ nonce: string
+ data: string
+ chainId: number
+ }
+ }): Promise>
+ ethereumSignMessage(params: {
+ path: string
+ message: string
+ hex?: boolean
+ }): Promise>
+ ethereumSignTypedData(params: {
+ path: string
+ data: Record
+ metamask_v4_compat: boolean
+ }): Promise>
+}
+
+let cachedTrezorConnect: TrezorConnectApi | undefined = undefined
+
+/**
+ * `@trezor/connect-web` is CommonJS and exposes its API as `exports.default`,
+ * alongside `export *` named exports.
+ *
+ * Bundlers that honour the `__esModule` marker (webpack, Rollup, and Vite's
+ * source transform) hand that object back as the default import. Node's ESM/CJS
+ * interop does not: there, and under esbuild's node-mode interop — which Vite
+ * uses when it prebundles this package as a dependency — the default import is
+ * the whole `module.exports`, so the API sits one level deeper and
+ * `TrezorConnect.init` is undefined.
+ *
+ * Probing for `init` covers every interop shape instead of assuming one. It is
+ * deliberately lazy so that a bad resolution surfaces when the connector is
+ * used rather than breaking the adapter's module import.
+ */
+function getTrezorConnect(): TrezorConnectApi {
+ if (cachedTrezorConnect) {
+ return cachedTrezorConnect
+ }
+
+ const namespace = TrezorConnectWeb as unknown as {
+ default?: { default?: unknown } & Record
+ }
+
+ const candidates = [namespace.default?.default, namespace.default, namespace]
+ const resolved = candidates.find(
+ candidate => typeof (candidate as TrezorConnectApi | undefined)?.init === 'function'
+ )
+
+ if (!resolved) {
+ throw new Error(
+ '@trezor/connect-web did not expose an init() method. This usually means the module was ' +
+ 'loaded through an interop path that hides its default export.'
+ )
+ }
+
+ cachedTrezorConnect = resolved as TrezorConnectApi
+
+ return cachedTrezorConnect
+}
+
+function rpcError(message: string, code: number): Error {
+ return Object.assign(new Error(message), { code })
+}
+
+function isUserRejection(message: string): boolean {
+ const lower = message.toLowerCase()
+
+ return lower.includes('cancel') || lower.includes('closed') || lower.includes('denied')
+}
+
+interface EthTransaction {
+ from?: string
+ to?: string
+ value?: string
+ data?: string
+ gas?: string
+ gasLimit?: string
+ gasPrice?: string
+ nonce?: string
+}
+
+type Listener = (data: unknown) => void
+
+export namespace TrezorConnectorTypes {
+ export interface ConstructorParams {
+ /** Networks the host app configured; only eip155 ones are used. */
+ requestedChains: CaipNetwork[]
+ /** The network to start on; falls back to the first requested chain. */
+ requestedCaipNetworkId?: CaipNetworkId
+ }
+
+ export type GetWalletParams = ConstructorParams
+}
+
+/**
+ * EIP-1193 provider backed by Trezor Connect, registered by the adapter like
+ * an announced browser wallet. Read-only JSON-RPC calls are forwarded to the
+ * active network's RPC endpoint; account and signing requests go to the
+ * device. Transactions are signed on the device and broadcast through the
+ * same RPC endpoint as legacy gas-price transactions, which every EVM chain
+ * accepts — including those without EIP-1559 support, such as Rootstock.
+ */
+export class TrezorConnector implements Provider {
+ public readonly id = 'trezor'
+ public readonly name = 'Trezor'
+ public readonly chain = 'eip155'
+ public readonly type = 'ANNOUNCED'
+ public readonly chains: CaipNetwork[] = []
+ public readonly imageUrl =
+ 'https://pbs.twimg.com/profile_images/1876994745022529536/5FD_cxXO_400x400.jpg'
+
+ public readonly provider = this
+
+ private readonly listeners = new Map>()
+ private readonly rpcUrls = new Map()
+ private accounts: string[] = []
+ private initialized = false
+ private chainIdHex = '0x1'
+
+ constructor({ requestedChains, requestedCaipNetworkId }: TrezorConnectorTypes.ConstructorParams) {
+ const evmChains = requestedChains.filter(chain => chain.chainNamespace === 'eip155')
+ this.chains = evmChains
+
+ for (const network of evmChains) {
+ const id = Number(network.id)
+ const rpcUrl = network.rpcUrls?.default?.http?.[0]
+ if (Number.isFinite(id) && rpcUrl) {
+ this.rpcUrls.set(`0x${id.toString(16)}`, rpcUrl)
+ }
+ }
+
+ const requested = evmChains.find(chain => chain.caipNetworkId === requestedCaipNetworkId)
+ const initialChain = requested ?? evmChains[0]
+ if (initialChain) {
+ this.chainIdHex = `0x${Number(initialChain.id).toString(16)}`
+ }
+ }
+
+ public static getWallet(
+ params: TrezorConnectorTypes.GetWalletParams
+ ): TrezorConnector | undefined {
+ if (!CoreHelperUtil.isClient()) {
+ return undefined
+ }
+
+ // Trezor uses a popup flow, so it's always available in browser environments
+ return new TrezorConnector(params)
+ }
+
+ // -- Provider event emitter --------------------------------- //
+
+ public on(event: string, listener: Listener): void {
+ if (!this.listeners.has(event)) {
+ this.listeners.set(event, new Set())
+ }
+ this.listeners.get(event)?.add(listener)
+ }
+
+ public removeListener(event: string, listener: (data: T) => void): void {
+ this.listeners.get(event)?.delete(listener as Listener)
+ }
+
+ public emit(event: string, data?: unknown): void {
+ this.listeners.get(event)?.forEach(listener => listener(data))
+ }
+
+ // -- Provider interface ------------------------------------- //
+
+ public async connect(): Promise {
+ const [address] = await this.connectAccounts()
+
+ return address ?? ''
+ }
+
+ public async disconnect(): Promise {
+ this.accounts = []
+ this.emit('accountsChanged', [])
+ this.emit('disconnect')
+
+ return Promise.resolve()
+ }
+
+ public async request(args: RequestArguments): Promise {
+ const method = args.method
+ const params = args.params as unknown[] | undefined
+
+ switch (method) {
+ case 'eth_requestAccounts':
+ return (await this.connectAccounts()) as T
+ case 'eth_accounts':
+ return this.accounts as T
+ case 'eth_chainId':
+ return this.chainIdHex as T
+ case 'net_version':
+ return String(parseInt(this.chainIdHex, 16)) as T
+ case 'wallet_switchEthereumChain':
+ return this.switchChain(params) as T
+ case 'wallet_addEthereumChain':
+ return null as T
+ case 'wallet_getPermissions':
+ case 'wallet_requestPermissions':
+ return [] as T
+ case 'wallet_revokePermissions':
+ this.accounts = []
+ this.emit('accountsChanged', [])
+
+ return null as T
+ case 'eth_sendTransaction':
+ return (await this.sendTransaction((params?.[0] ?? {}) as EthTransaction)) as T
+ case 'personal_sign':
+ return (await this.signMessage(String(params?.[0] ?? ''))) as T
+ case 'eth_sign':
+ return (await this.signMessage(String(params?.[1] ?? ''))) as T
+ case 'eth_signTypedData_v4':
+ case 'eth_signTypedData':
+ return (await this.signTypedData(params?.[1])) as T
+ default:
+ return (await this.rpcRequest(method, params)) as T
+ }
+ }
+
+ // -- Private methods ----------------------------------------- //
+
+ private async initTrezor(): Promise {
+ const trezor = getTrezorConnect()
+
+ if (this.initialized) {
+ return trezor
+ }
+
+ try {
+ await trezor.init({
+ manifest: {
+ email: 'support@reown.com',
+ appUrl: typeof window === 'undefined' ? 'https://reown.com' : window.location.origin,
+ appName: 'Reown AppKit'
+ },
+ lazyLoad: true,
+ popup: true
+ })
+ } catch (error) {
+ /*
+ * Trezor Connect is a page-global singleton: the host app (or another
+ * connector, e.g. the Bitcoin adapter's) may have initialized it first,
+ * which init() reports as an error even though the instance is usable.
+ */
+ const message = error instanceof Error ? error.message : String(error)
+ if (!message.toLowerCase().includes('already initialized')) {
+ throw error
+ }
+ }
+
+ this.initialized = true
+
+ return trezor
+ }
+
+ private async connectAccounts(): Promise {
+ if (this.accounts.length > 0) {
+ return this.accounts
+ }
+
+ const trezor = await this.initTrezor()
+ const result = await trezor.ethereumGetAddress({
+ path: ETH_DERIVATION_PATH,
+ showOnTrezor: false
+ })
+ if (!result.success) {
+ const message = result.payload.error ?? 'Trezor: ethereumGetAddress failed'
+ throw rpcError(message, isUserRejection(message) ? 4001 : -32603)
+ }
+
+ this.accounts = [result.payload.address]
+ this.emit('accountsChanged', this.accounts)
+
+ return this.accounts
+ }
+
+ private switchChain(params?: unknown[]): null {
+ const requested = (params?.[0] as { chainId?: string } | undefined)?.chainId?.toLowerCase()
+ if (!requested || !this.rpcUrls.has(requested)) {
+ throw rpcError(`Unrecognized chain ID ${requested ?? ''}`, 4902)
+ }
+
+ if (requested !== this.chainIdHex) {
+ this.chainIdHex = requested
+ this.emit('chainChanged', this.chainIdHex)
+ }
+
+ return null
+ }
+
+ private async sendTransaction(tx: EthTransaction): Promise {
+ const [from] = await this.connectAccounts()
+ const chainId = parseInt(this.chainIdHex, 16)
+ if (!tx.to) {
+ throw rpcError('eth_sendTransaction requires a `to` address', -32602)
+ }
+
+ const [nonce, gasPrice, gasLimit] = (await Promise.all([
+ tx.nonce ?? this.rpcRequest('eth_getTransactionCount', [from, 'pending']),
+ tx.gasPrice ?? this.rpcRequest('eth_gasPrice', []),
+ tx.gas ??
+ tx.gasLimit ??
+ this.rpcRequest('eth_estimateGas', [
+ {
+ from,
+ to: tx.to,
+ value: tx.value ?? '0x0',
+ data: tx.data ?? '0x'
+ }
+ ])
+ ])) as [string, string, string]
+
+ const trezor = await this.initTrezor()
+ const result = await trezor.ethereumSignTransaction({
+ path: ETH_DERIVATION_PATH,
+ transaction: {
+ to: tx.to,
+ value: tx.value ?? '0x0',
+ gasPrice,
+ gasLimit,
+ nonce,
+ data: tx.data ?? '0x',
+ chainId
+ }
+ })
+ if (!result.success) {
+ const message = result.payload.error ?? 'Trezor: ethereumSignTransaction failed'
+ throw rpcError(message, isUserRejection(message) ? 4001 : -32603)
+ }
+
+ const raw = utils.serializeTransaction(
+ {
+ to: tx.to,
+ value: tx.value ?? '0x0',
+ gasPrice,
+ gasLimit,
+ nonce: parseInt(nonce, 16),
+ data: tx.data ?? '0x',
+ chainId
+ },
+ {
+ r: result.payload.r,
+ s: result.payload.s,
+ v: parseInt(result.payload.v, 16)
+ }
+ )
+
+ return (await this.rpcRequest('eth_sendRawTransaction', [raw])) as string
+ }
+
+ private async signMessage(message: string): Promise {
+ const trezor = await this.initTrezor()
+ await this.connectAccounts()
+ const hex = message.startsWith('0x')
+ ? message.slice(2)
+ : Array.from(new TextEncoder().encode(message), byte =>
+ byte.toString(16).padStart(2, '0')
+ ).join('')
+ const result = await trezor.ethereumSignMessage({
+ path: ETH_DERIVATION_PATH,
+ message: hex,
+ hex: true
+ })
+ if (!result.success) {
+ const errorMessage = result.payload.error ?? 'Trezor: ethereumSignMessage failed'
+ throw rpcError(errorMessage, isUserRejection(errorMessage) ? 4001 : -32603)
+ }
+ const signature = result.payload.signature
+
+ return signature.startsWith('0x') ? signature : `0x${signature}`
+ }
+
+ private async signTypedData(payload: unknown): Promise {
+ const trezor = await this.initTrezor()
+ await this.connectAccounts()
+ const data =
+ typeof payload === 'string'
+ ? (JSON.parse(payload) as Record)
+ : (payload as Record)
+ const result = await trezor.ethereumSignTypedData({
+ path: ETH_DERIVATION_PATH,
+ data,
+ metamask_v4_compat: true
+ })
+ if (!result.success) {
+ const errorMessage = result.payload.error ?? 'Trezor: ethereumSignTypedData failed'
+ throw rpcError(errorMessage, isUserRejection(errorMessage) ? 4001 : -32603)
+ }
+ const signature = result.payload.signature
+
+ return signature.startsWith('0x') ? signature : `0x${signature}`
+ }
+
+ private async rpcRequest(method: string, params?: unknown[]): Promise {
+ const rpcUrl = this.rpcUrls.get(this.chainIdHex)
+ if (!rpcUrl) {
+ throw rpcError(`No RPC endpoint for chain ${this.chainIdHex}`, 4901)
+ }
+
+ const response = await fetch(rpcUrl, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ jsonrpc: '2.0', id: Date.now(), method, params: params ?? [] })
+ })
+ if (!response.ok) {
+ throw rpcError(`RPC request failed with status ${response.status}`, -32603)
+ }
+
+ const body: { result?: unknown; error?: { message: string; code: number } } =
+ await response.json()
+ if (body.error) {
+ throw rpcError(body.error.message, body.error.code)
+ }
+
+ return body.result
+ }
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index dfef6c8d2d..c1210acca9 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -2461,9 +2461,12 @@ importers:
'@reown/appkit-wallet':
specifier: workspace:*
version: link:../../wallet
+ '@trezor/connect-web':
+ specifier: 9.7.3
+ version: 9.7.3(@solana/sysvars@5.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@5.9.2)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))
'@walletconnect/universal-provider':
specifier: 2.23.7
- version: 2.23.7(aws4fetch@1.0.20)(bufferutil@4.1.0)(db0@0.3.4)(ioredis@5.9.1)(typescript@5.8.3)(utf-8-validate@5.0.10)
+ version: 2.23.7(aws4fetch@1.0.20)(bufferutil@4.1.0)(db0@0.3.4)(ioredis@5.9.1)(typescript@5.9.2)(utf-8-validate@5.0.10)
ethers:
specifier: '>=4.1 <6.0.0'
version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)
@@ -24258,7 +24261,7 @@ snapshots:
scule: 1.3.0
semver: 7.7.3
tinyglobby: 0.2.15
- ufo: 1.6.2
+ ufo: 1.6.4
unctx: 2.5.0
untyped: 2.0.0
transitivePeerDependencies:
@@ -24284,7 +24287,7 @@ snapshots:
scule: 1.3.0
semver: 7.7.3
tinyglobby: 0.2.15
- ufo: 1.6.2
+ ufo: 1.6.4
unctx: 2.5.0
untyped: 2.0.0
transitivePeerDependencies:
@@ -38804,8 +38807,8 @@ snapshots:
'@typescript-eslint/parser': 6.18.1(eslint@8.56.0)(typescript@5.9.2)
eslint: 8.56.0
eslint-import-resolver-node: 0.3.9
- eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.8.3))(eslint@8.56.0))(eslint@8.56.0)
- eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.56.0)
+ eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.56.0)
+ eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.9.2))(eslint@8.56.0)
eslint-plugin-jsx-a11y: 6.10.2(eslint@8.56.0)
eslint-plugin-react: 7.37.5(eslint@8.56.0)
eslint-plugin-react-hooks: 5.2.0(eslint@8.56.0)
@@ -38878,6 +38881,21 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@8.56.0):
+ dependencies:
+ '@nolyfill/is-core-module': 1.0.39
+ debug: 4.4.3
+ eslint: 8.56.0
+ get-tsconfig: 4.13.0
+ is-bun-module: 2.0.0
+ stable-hash: 0.0.5
+ tinyglobby: 0.2.15
+ unrs-resolver: 1.11.1
+ optionalDependencies:
+ eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.9.2))(eslint@8.56.0)
+ transitivePeerDependencies:
+ - supports-color
+
eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.1(jiti@2.6.1)):
dependencies:
'@nolyfill/is-core-module': 1.0.39
@@ -38904,6 +38922,17 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ eslint-module-utils@2.12.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@8.56.0))(eslint@8.56.0):
+ dependencies:
+ debug: 3.2.7
+ optionalDependencies:
+ '@typescript-eslint/parser': 6.18.1(eslint@8.56.0)(typescript@5.9.2)
+ eslint: 8.56.0
+ eslint-import-resolver-node: 0.3.9
+ eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.56.0)
+ transitivePeerDependencies:
+ - supports-color
+
eslint-module-utils@2.12.1(@typescript-eslint/parser@6.18.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)):
dependencies:
debug: 3.2.7
@@ -38955,6 +38984,35 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
+ eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.9.2))(eslint@8.56.0):
+ dependencies:
+ '@rtsao/scc': 1.1.0
+ array-includes: 3.1.9
+ array.prototype.findlastindex: 1.2.6
+ array.prototype.flat: 1.3.3
+ array.prototype.flatmap: 1.3.3
+ debug: 3.2.7
+ doctrine: 2.1.0
+ eslint: 8.56.0
+ eslint-import-resolver-node: 0.3.9
+ eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@8.56.0))(eslint@8.56.0)
+ hasown: 2.0.2
+ is-core-module: 2.13.1
+ is-glob: 4.0.3
+ minimatch: 3.1.2
+ object.fromentries: 2.0.8
+ object.groupby: 1.0.3
+ object.values: 1.2.1
+ semver: 6.3.1
+ string.prototype.trimend: 1.0.9
+ tsconfig-paths: 3.15.0
+ optionalDependencies:
+ '@typescript-eslint/parser': 6.18.1(eslint@8.56.0)(typescript@5.9.2)
+ transitivePeerDependencies:
+ - eslint-import-resolver-typescript
+ - eslint-import-resolver-webpack
+ - supports-color
+
eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.18.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1)):
dependencies:
'@rtsao/scc': 1.1.0
@@ -41143,7 +41201,7 @@ snapshots:
node-forge: 1.3.3
pathe: 1.1.2
std-env: 3.10.0
- ufo: 1.6.2
+ ufo: 1.6.4
untun: 0.1.3
uqr: 0.1.2
@@ -41320,7 +41378,7 @@ snapshots:
mlly: 1.8.0
regexp-tree: 0.1.27
type-level-regexp: 0.1.17
- ufo: 1.6.2
+ ufo: 1.6.4
unplugin: 2.3.11
magic-string-ast@1.0.3:
@@ -45842,7 +45900,7 @@ snapshots:
defu: 6.1.4
ohash: 1.1.6
pathe: 1.1.2
- ufo: 1.6.2
+ ufo: 1.6.4
unenv@2.0.0-rc.17:
dependencies:
@@ -47164,7 +47222,7 @@ snapshots:
dependencies:
'@babel/core': 7.28.6
'@babel/traverse': 7.28.6
- '@babel/types': 7.28.6
+ '@babel/types': 7.29.7
babylon: 7.0.0-beta.47
webassembly-interpreter: 0.0.30
transitivePeerDependencies: