@getpara/cosmos-wallet-connectors 2.0.0-fc.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -0
- package/dist/providers/CosmosExternalWalletContext.d.ts +1 -1
- package/dist/providers/CosmosExternalWalletContext.js +70 -31
- package/dist/providers/ParaCosmosContext.d.ts +1 -1
- package/dist/providers/ParaCosmosContext.js +19 -2
- package/dist/providers/externalHooks.d.ts +2 -3
- package/dist/providers/externalHooks.js +1 -1
- package/dist/types/ExternalHooks.d.ts +1 -1
- package/dist/types/Wallet.d.ts +1 -1
- package/dist/wallets/connectors/cosmostation/cosmostation.js +1 -1
- package/dist/wallets/connectors/keplr/keplr.js +1 -1
- package/dist/wallets/connectors/leap/leap.js +1 -1
- package/package.json +7 -8
package/README.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
https://www.npmjs.com/package/@getpara/cosmos-wallet-connectors
|
|
2
|
+
|
|
3
|
+
`@getpara/cosmos-wallet-connectors` is a package that provides wallet connectors for Cosmos-based blockchains when using Para's React SDK Lite.
|
|
4
|
+
This package enables integration with Cosmos wallets like Keplr, Leap, and Cosmostation in Para applications. After installation, you can configure it in your ParaProvider to support external Cosmos wallet connections.
|
|
5
|
+
###Prerequisites
|
|
6
|
+
|
|
7
|
+
To use Para, you need an API key. This key authenticates your requests to Para services and is essential for integration.
|
|
8
|
+
|
|
9
|
+
Don't have an API key yet? Request access to the [Developer Portal](https://developer.getpara.com/) to create API keys, manage billing, teams, and more.
|
|
10
|
+
|
|
11
|
+
###Learn more
|
|
12
|
+
|
|
13
|
+
For more information on Para’s Cosmos wallet connection visit the [Para Docs](https://docs.getpara.com/v2/react/guides/external-wallets/cosmos-lite#cosmos-wallets-with-react-sdk-lite)
|
|
@@ -12,4 +12,4 @@ export type CosmosExternalWalletContextType = ExternalWalletContextType<CosmosSi
|
|
|
12
12
|
export type CosmosExternalWalletProviderConfig = ExternalWalletProviderConfigBase;
|
|
13
13
|
export type CosmosExternalWalletProviderConfigFull = ExternalWalletProviderConfig<WalletWithType, Omit<ParaCosmosProviderConfig, 'wallets'>>;
|
|
14
14
|
export declare const CosmosExternalWalletContext: import("react").Context<CosmosExternalWalletContextType>;
|
|
15
|
-
export declare function CosmosExternalWalletProvider({ children, onSwitchWallet, selectedChainId, wallets: incompleteWallets, chains, multiChain, shouldUseSuggestChainAndConnect, onSwitchChain, para, walletsWithFullAuth, connectedWallet, includeWalletVerification, connectionOnly, }: CosmosExternalWalletProviderConfigFull & PropsWithChildren): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export declare function CosmosExternalWalletProvider({ children, onSwitchWallet, selectedChainId, wallets: incompleteWallets, chains, multiChain, shouldUseSuggestChainAndConnect, onSwitchChain, para, walletsWithFullAuth, connectedWallet: connectedWalletProp, includeWalletVerification, connectionOnly, }: CosmosExternalWalletProviderConfigFull & PropsWithChildren): import("react/jsx-runtime").JSX.Element;
|
|
@@ -15,8 +15,9 @@ import {
|
|
|
15
15
|
useDisconnect,
|
|
16
16
|
useSuggestChainAndConnect,
|
|
17
17
|
getChainInfo,
|
|
18
|
-
getWallet as grazGetWallet
|
|
19
|
-
|
|
18
|
+
getWallet as grazGetWallet,
|
|
19
|
+
WALLET_TYPES
|
|
20
|
+
} from "graz";
|
|
20
21
|
import { useExternalWalletStore } from "../stores/useStore.js";
|
|
21
22
|
import { rawSecp256k1PubkeyToRawAddress } from "@getpara/web-sdk";
|
|
22
23
|
import {
|
|
@@ -24,7 +25,9 @@ import {
|
|
|
24
25
|
} from "@getpara/react-common";
|
|
25
26
|
import { formatEthHexAddress } from "../utils/formatEthHexAddress.js";
|
|
26
27
|
import { externalHooks } from "./externalHooks.js";
|
|
27
|
-
const CosmosExternalWalletContext = createContext(
|
|
28
|
+
const CosmosExternalWalletContext = createContext(
|
|
29
|
+
defaultCosmosExternalWallet
|
|
30
|
+
);
|
|
28
31
|
function CosmosExternalWalletProvider({
|
|
29
32
|
children,
|
|
30
33
|
onSwitchWallet,
|
|
@@ -36,29 +39,34 @@ function CosmosExternalWalletProvider({
|
|
|
36
39
|
onSwitchChain,
|
|
37
40
|
para,
|
|
38
41
|
walletsWithFullAuth,
|
|
39
|
-
connectedWallet,
|
|
42
|
+
connectedWallet: connectedWalletProp,
|
|
40
43
|
includeWalletVerification,
|
|
41
44
|
connectionOnly
|
|
42
45
|
}) {
|
|
43
|
-
var _a, _b, _c
|
|
46
|
+
var _a, _b, _c;
|
|
44
47
|
const { suggestAndConnectAsync } = useSuggestChainAndConnect();
|
|
45
48
|
const {
|
|
46
49
|
data: account,
|
|
47
50
|
isConnecting,
|
|
48
51
|
isReconnecting,
|
|
49
52
|
isConnected
|
|
50
|
-
} = useAccount(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
} = useAccount(
|
|
54
|
+
multiChain ? {
|
|
55
|
+
chainId: chains.map((c) => c.chainId)
|
|
56
|
+
} : selectedChainId ? {
|
|
57
|
+
chainId: [selectedChainId]
|
|
58
|
+
} : void 0
|
|
59
|
+
);
|
|
54
60
|
const { connectAsync } = useConnect();
|
|
55
|
-
const { disconnectAsync } = useDisconnect();
|
|
61
|
+
const { disconnectAsync, status: disconnectStatus } = useDisconnect();
|
|
56
62
|
const { walletType } = useActiveWalletType();
|
|
57
63
|
const isLocalConnecting = useExternalWalletStore((state) => state.isConnecting);
|
|
58
64
|
const updateExternalWalletState = useExternalWalletStore((state) => state.updateState);
|
|
59
|
-
const
|
|
60
|
-
const
|
|
61
|
-
const
|
|
65
|
+
const isConnectError = useRef(false);
|
|
66
|
+
const connectedWallet = connectedWalletProp ? para.findWallet(connectedWalletProp.id, connectedWalletProp.type) : null;
|
|
67
|
+
const ethAddress = (_b = (_a = account == null ? void 0 : account[selectedChainId]) == null ? void 0 : _a.ethereumHexAddress) == null ? void 0 : _b.toLowerCase();
|
|
68
|
+
const address = (_c = account == null ? void 0 : account[selectedChainId]) == null ? void 0 : _c.bech32Address;
|
|
69
|
+
const disconnectTypeRef = useRef();
|
|
62
70
|
const verificationMessage = useRef();
|
|
63
71
|
const reset = () => __async(this, null, function* () {
|
|
64
72
|
yield disconnectAsync();
|
|
@@ -94,6 +102,7 @@ function CosmosExternalWalletProvider({
|
|
|
94
102
|
const storedExternalWallet = para.externalWallets[(_a2 = changeResp.ethAddress) != null ? _a2 : ""];
|
|
95
103
|
const { provider, providerId } = getProvider(walletType);
|
|
96
104
|
para.setExternalWallet({
|
|
105
|
+
partnerId: para.partnerId,
|
|
97
106
|
address: changeResp.ethAddress,
|
|
98
107
|
type: "COSMOS",
|
|
99
108
|
provider,
|
|
@@ -116,6 +125,7 @@ function CosmosExternalWalletProvider({
|
|
|
116
125
|
try {
|
|
117
126
|
return yield para.loginExternalWallet({
|
|
118
127
|
externalWallet: {
|
|
128
|
+
partnerId: para.partnerId,
|
|
119
129
|
address: address2,
|
|
120
130
|
type: "COSMOS",
|
|
121
131
|
provider,
|
|
@@ -124,32 +134,39 @@ function CosmosExternalWalletProvider({
|
|
|
124
134
|
withFullParaAuth,
|
|
125
135
|
withVerification: includeWalletVerification,
|
|
126
136
|
isConnectionOnly: connectionOnly
|
|
127
|
-
}
|
|
137
|
+
},
|
|
138
|
+
uri: window == null ? void 0 : window.location.origin,
|
|
139
|
+
chainId: selectedChainId
|
|
128
140
|
});
|
|
129
|
-
} catch (
|
|
141
|
+
} catch (e) {
|
|
130
142
|
yield reset();
|
|
131
143
|
throw "Error logging you in. Please try again.";
|
|
132
144
|
}
|
|
133
145
|
});
|
|
134
146
|
useEffect(() => {
|
|
135
147
|
const storedExternalWallet = para.externalWallets[ethAddress != null ? ethAddress : ""];
|
|
136
|
-
if (isConnected && !isConnecting && !isReconnecting && !isLocalConnecting && !!ethAddress && !storedExternalWallet && walletType !== GrazWalletType.PARA && !
|
|
148
|
+
if (isConnected && !isConnecting && !isReconnecting && !isLocalConnecting && !!ethAddress && !storedExternalWallet && walletType !== GrazWalletType.PARA && !disconnectTypeRef.current) {
|
|
137
149
|
reset();
|
|
138
150
|
}
|
|
139
151
|
}, [isConnecting, isLocalConnecting, isReconnecting, isConnected]);
|
|
140
152
|
useEffect(() => {
|
|
141
153
|
const connect2 = () => __async(this, null, function* () {
|
|
142
154
|
var _a2;
|
|
143
|
-
if (!isLocalConnecting && !isConnecting && !isReconnecting && connectedWallet && connectedWallet.type === "COSMOS" && (connectedWallet.isExternal ? walletType !== ((_a2 = connectedWallet.name) == null ? void 0 : _a2.toLowerCase()) : walletType !== "para") && !
|
|
155
|
+
if (!isLocalConnecting && !isConnecting && !isReconnecting && connectedWallet && connectedWallet.type === "COSMOS" && (connectedWallet.isExternal ? walletType !== ((_a2 = connectedWallet.name) == null ? void 0 : _a2.toLowerCase()) : walletType !== "para") && !disconnectTypeRef.current && !isConnectError.current) {
|
|
144
156
|
const isLoggedIn = yield para.isFullyLoggedIn();
|
|
145
157
|
if (!isLoggedIn) {
|
|
146
158
|
return;
|
|
147
159
|
}
|
|
148
160
|
const chainId = multiChain ? chains.map((c) => c.chainId) : selectedChainId;
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
161
|
+
const targetWalletType = connectedWallet.isExternal ? connectedWallet.name.toLowerCase() : GrazWalletType.PARA;
|
|
162
|
+
try {
|
|
163
|
+
yield connectAsync({
|
|
164
|
+
walletType: targetWalletType,
|
|
165
|
+
chainId
|
|
166
|
+
});
|
|
167
|
+
} catch (e) {
|
|
168
|
+
isConnectError.current = true;
|
|
169
|
+
}
|
|
153
170
|
}
|
|
154
171
|
});
|
|
155
172
|
connect2();
|
|
@@ -157,7 +174,7 @@ function CosmosExternalWalletProvider({
|
|
|
157
174
|
const signMessage = (_0) => __async(this, [_0], function* ({ message, externalWallet }) {
|
|
158
175
|
let wallet, signAddress, signEthAddress;
|
|
159
176
|
if (externalWallet) {
|
|
160
|
-
const commonWallet = wallets.find((w) => w.
|
|
177
|
+
const commonWallet = wallets.find((w) => w.id === externalWallet.providerId);
|
|
161
178
|
wallet = grazGetWallet(commonWallet == null ? void 0 : commonWallet.grazType);
|
|
162
179
|
signAddress = externalWallet.addressBech32;
|
|
163
180
|
signEthAddress = externalWallet.address;
|
|
@@ -229,6 +246,7 @@ function CosmosExternalWalletProvider({
|
|
|
229
246
|
const address2 = formatEthHexAddress(rawAddress);
|
|
230
247
|
const { provider, providerId } = getProvider(walletType2);
|
|
231
248
|
return {
|
|
249
|
+
partnerId: para.partnerId,
|
|
232
250
|
type: "COSMOS",
|
|
233
251
|
address: address2,
|
|
234
252
|
addressBech32,
|
|
@@ -249,7 +267,7 @@ function CosmosExternalWalletProvider({
|
|
|
249
267
|
var _a2, _b2;
|
|
250
268
|
updateExternalWalletState({ isConnecting: true });
|
|
251
269
|
const walletId = (_a2 = getWallet(walletType2)) == null ? void 0 : _a2.id;
|
|
252
|
-
const isFullAuthWallet = walletsWithFullAuth.includes(walletId.toUpperCase());
|
|
270
|
+
const isFullAuthWallet = walletsWithFullAuth === "ALL" || walletsWithFullAuth.includes(walletId.toUpperCase());
|
|
253
271
|
try {
|
|
254
272
|
const externalWallet = yield connectBase(walletType2, chainId);
|
|
255
273
|
const authState = yield login(__spreadProps(__spreadValues({}, externalWallet), {
|
|
@@ -268,21 +286,37 @@ function CosmosExternalWalletProvider({
|
|
|
268
286
|
updateExternalWalletState({ isConnecting: false });
|
|
269
287
|
}
|
|
270
288
|
});
|
|
271
|
-
const
|
|
289
|
+
const injectedWallets = WALLET_TYPES.filter((w) => !incompleteWallets.some((iw) => iw.grazType === w) && checkWallet(w)).map((w) => {
|
|
290
|
+
const wallet = grazGetWallet(w);
|
|
291
|
+
if (!wallet.eip6963ProviderInfo) {
|
|
292
|
+
return void 0;
|
|
293
|
+
}
|
|
294
|
+
const eipInfo = wallet.eip6963ProviderInfo;
|
|
295
|
+
return __spreadValues({
|
|
296
|
+
grazType: w,
|
|
297
|
+
// Using name here for the injected connector since that's the only common id across the networks
|
|
298
|
+
id: eipInfo.name,
|
|
299
|
+
internalId: eipInfo.name,
|
|
300
|
+
iconUrl: eipInfo.icon
|
|
301
|
+
}, eipInfo);
|
|
302
|
+
}).filter((w) => !!w);
|
|
303
|
+
const allWallets = [...incompleteWallets, ...injectedWallets];
|
|
304
|
+
const getWallet = (walletType2) => allWallets.find((w) => w.grazType === walletType2 || w.grazMobileType === walletType2);
|
|
272
305
|
const getProvider = (walletType2) => {
|
|
273
306
|
const wallet = getWallet(walletType2);
|
|
274
307
|
return {
|
|
275
308
|
provider: wallet == null ? void 0 : wallet.name,
|
|
276
|
-
providerId: wallet == null ? void 0 : wallet.
|
|
309
|
+
providerId: wallet == null ? void 0 : wallet.id
|
|
277
310
|
};
|
|
278
311
|
};
|
|
279
|
-
const wallets =
|
|
312
|
+
const wallets = allWallets.map((wallet) => {
|
|
280
313
|
return __spreadProps(__spreadValues({
|
|
281
314
|
connect: () => connect(wallet.grazType),
|
|
282
315
|
connectMobile: () => connect(wallet.grazType),
|
|
283
|
-
getQrUri: () => "",
|
|
284
316
|
type: "COSMOS"
|
|
285
317
|
}, wallet), {
|
|
318
|
+
// Using name here since that's the only common id across the networks
|
|
319
|
+
id: wallet.name,
|
|
286
320
|
installed: checkWallet(wallet.grazType)
|
|
287
321
|
});
|
|
288
322
|
}).filter((w) => !!w);
|
|
@@ -307,11 +341,11 @@ function CosmosExternalWalletProvider({
|
|
|
307
341
|
}), [para, multiChain, chains, selectedChainId]);
|
|
308
342
|
const requestInfo = (providerId) => __async(this, null, function* () {
|
|
309
343
|
var _a2;
|
|
310
|
-
const wallet = wallets.find((w) => w.
|
|
344
|
+
const wallet = wallets.find((w) => w.id === providerId);
|
|
311
345
|
if (!wallet) {
|
|
312
346
|
throw new Error(`Wallet for provider ${providerId} not found`);
|
|
313
347
|
}
|
|
314
|
-
|
|
348
|
+
disconnectTypeRef.current = "ACCOUNT_LINKING";
|
|
315
349
|
try {
|
|
316
350
|
const externalWallet = yield connectBase(
|
|
317
351
|
wallet.grazType,
|
|
@@ -323,14 +357,18 @@ function CosmosExternalWalletProvider({
|
|
|
323
357
|
throw new Error((_a2 = e == null ? void 0 : e.message) != null ? _a2 : e);
|
|
324
358
|
}
|
|
325
359
|
});
|
|
326
|
-
const disconnectBase = () => __async(this,
|
|
360
|
+
const disconnectBase = (_0, ..._1) => __async(this, [_0, ..._1], function* (_, { disconnectType } = {}) {
|
|
327
361
|
var _a2;
|
|
328
|
-
|
|
362
|
+
if (disconnectType) {
|
|
363
|
+
disconnectTypeRef.current = disconnectType;
|
|
364
|
+
}
|
|
329
365
|
try {
|
|
330
366
|
yield disconnectAsync();
|
|
331
367
|
} catch (e) {
|
|
332
368
|
console.error("Error linking account:", e);
|
|
333
369
|
throw new Error((_a2 = e == null ? void 0 : e.message) != null ? _a2 : e);
|
|
370
|
+
} finally {
|
|
371
|
+
disconnectTypeRef.current = void 0;
|
|
334
372
|
}
|
|
335
373
|
});
|
|
336
374
|
return /* @__PURE__ */ jsx(
|
|
@@ -342,6 +380,7 @@ function CosmosExternalWalletProvider({
|
|
|
342
380
|
chains: formattedChains,
|
|
343
381
|
chainId: selectedChainId,
|
|
344
382
|
disconnect: disconnectAsync,
|
|
383
|
+
disconnectStatus,
|
|
345
384
|
switchChain,
|
|
346
385
|
connectParaEmbedded,
|
|
347
386
|
signMessage,
|
|
@@ -2,7 +2,7 @@ import { PropsWithChildren } from 'react';
|
|
|
2
2
|
import { WalletList } from '../types/Wallet.js';
|
|
3
3
|
import { CosmosExternalWalletProviderConfig } from './CosmosExternalWalletContext.js';
|
|
4
4
|
import { ChainInfo } from '@keplr-wallet/types';
|
|
5
|
-
import { ConfigureGrazArgs } from '
|
|
5
|
+
import { ConfigureGrazArgs } from 'graz';
|
|
6
6
|
export type ParaCosmosProviderConfig = {
|
|
7
7
|
wallets: WalletList;
|
|
8
8
|
chains: ChainInfo[];
|
|
@@ -6,7 +6,8 @@ import {
|
|
|
6
6
|
import { jsx } from "react/jsx-runtime";
|
|
7
7
|
import { useMemo } from "react";
|
|
8
8
|
import { CosmosExternalWalletProvider } from "./CosmosExternalWalletContext.js";
|
|
9
|
-
import {
|
|
9
|
+
import { ParaGrazConnector } from "@getpara/graz-connector";
|
|
10
|
+
import { GrazProvider } from "graz";
|
|
10
11
|
function ParaCosmosProvider({
|
|
11
12
|
children,
|
|
12
13
|
config,
|
|
@@ -26,10 +27,26 @@ function ParaCosmosProvider({
|
|
|
26
27
|
}),
|
|
27
28
|
[walletsWithType, config, internalConfig]
|
|
28
29
|
);
|
|
30
|
+
const paraConfig = useMemo(
|
|
31
|
+
() => ({
|
|
32
|
+
paraWeb: para
|
|
33
|
+
}),
|
|
34
|
+
[para]
|
|
35
|
+
);
|
|
29
36
|
return (
|
|
30
37
|
// Casting Para as any here to avoid ts errors due to the graz version being behind.
|
|
31
38
|
// TODO: update graz para sdk to current version
|
|
32
|
-
/* @__PURE__ */ jsx(
|
|
39
|
+
/* @__PURE__ */ jsx(
|
|
40
|
+
GrazProvider,
|
|
41
|
+
{
|
|
42
|
+
grazOptions: __spreadValues({
|
|
43
|
+
chains,
|
|
44
|
+
autoReconnect: true,
|
|
45
|
+
paraConfig: __spreadProps(__spreadValues({}, paraConfig), { connectorClass: ParaGrazConnector })
|
|
46
|
+
}, grazProviderProps),
|
|
47
|
+
children: /* @__PURE__ */ jsx(CosmosExternalWalletProvider, __spreadProps(__spreadValues({}, cosmosExternalWalletProviderProps), { children }))
|
|
48
|
+
}
|
|
49
|
+
)
|
|
33
50
|
);
|
|
34
51
|
}
|
|
35
52
|
export {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { useAccount } from '
|
|
2
|
-
import { MultiChainHookArgs } from '../types/ExternalHooks.js';
|
|
1
|
+
import { useAccount } from 'graz';
|
|
3
2
|
export type TExternalHooks = {
|
|
4
|
-
useAccount: typeof useAccount
|
|
3
|
+
useAccount: typeof useAccount;
|
|
5
4
|
};
|
|
6
5
|
export declare const externalHooks: {
|
|
7
6
|
useAccount: typeof useAccount;
|
package/dist/types/Wallet.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import "../../../chunk-IV3L3JVM.js";
|
|
3
3
|
import { icon } from "./cosmostationIcon.js";
|
|
4
|
-
import { WalletType } from "
|
|
4
|
+
import { WalletType } from "graz";
|
|
5
5
|
import { isMobile } from "@getpara/web-sdk";
|
|
6
6
|
const cosmostationWallet = () => {
|
|
7
7
|
return {
|
package/package.json
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getpara/cosmos-wallet-connectors",
|
|
3
|
-
"version": "2.0.0
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"dependencies": {
|
|
5
|
-
"@getpara/graz": "2.0.0
|
|
6
|
-
"@getpara/react-common": "2.0.0
|
|
7
|
-
"@getpara/web-sdk": "2.0.0
|
|
5
|
+
"@getpara/graz-connector": "2.0.0",
|
|
6
|
+
"@getpara/react-common": "2.0.0",
|
|
7
|
+
"@getpara/web-sdk": "2.0.0",
|
|
8
8
|
"@leapwallet/cosmos-social-login-capsule-provider": "^0.0.41",
|
|
9
|
-
"starknet": "^6.11.0",
|
|
10
9
|
"zustand": "^4.5.2",
|
|
11
10
|
"zustand-sync-tabs": "^0.2.2"
|
|
12
11
|
},
|
|
13
12
|
"devDependencies": {
|
|
14
|
-
"@getpara/graz": "2.0.0-alpha.3",
|
|
15
13
|
"@types/react": "^18.0.31",
|
|
16
14
|
"@types/react-dom": "^18.2.7",
|
|
15
|
+
"graz": "^0.4.1",
|
|
17
16
|
"typescript": "^5.8.3"
|
|
18
17
|
},
|
|
19
18
|
"exports": {
|
|
@@ -24,10 +23,10 @@
|
|
|
24
23
|
"dist",
|
|
25
24
|
"package.json"
|
|
26
25
|
],
|
|
27
|
-
"gitHead": "
|
|
26
|
+
"gitHead": "a64b6aa9b3c481a2d955022f621e495fb55e549e",
|
|
28
27
|
"main": "dist/index.js",
|
|
29
28
|
"peerDependencies": {
|
|
30
|
-
"
|
|
29
|
+
"graz": ">=0.4.1",
|
|
31
30
|
"react": ">=18",
|
|
32
31
|
"react-dom": ">=18"
|
|
33
32
|
},
|