@reown/appkit-controllers 1.8.21 → 1.8.22-coinbase-4100-provider-reauth.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.
@@ -0,0 +1,226 @@
1
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
2
+ import { ApiController } from '../../src/controllers/ApiController.js';
3
+ import { ChainController } from '../../src/controllers/ChainController.js';
4
+ import { ConnectionController } from '../../src/controllers/ConnectionController.js';
5
+ import { ConnectorController } from '../../src/controllers/ConnectorController.js';
6
+ import { OptionsController } from '../../src/controllers/OptionsController.js';
7
+ import { PublicStateController } from '../../src/controllers/PublicStateController.js';
8
+ import { ConnectUtil } from '../../src/utils/ConnectUtil.js';
9
+ import { ConnectionControllerUtil } from '../../src/utils/ConnectionControllerUtil.js';
10
+ import { ConnectorControllerUtil } from '../../src/utils/ConnectorControllerUtil.js';
11
+ import { CoreHelperUtil } from '../../src/utils/CoreHelperUtil.js';
12
+ import { HeadlessWalletUtil } from '../../src/utils/HeadlessWalletUtil.js';
13
+ import { MobileWalletUtil } from '../../src/utils/MobileWallet.js';
14
+ const injectedWallet = {
15
+ id: 'mm',
16
+ name: 'MetaMask',
17
+ imageUrl: 'icon',
18
+ connectors: [{ id: 'io.metamask', chain: 'eip155' }],
19
+ walletInfo: {},
20
+ isInjected: true,
21
+ isRecent: false
22
+ };
23
+ const apiWallet = {
24
+ id: 'wc_wallet',
25
+ name: 'Some Wallet',
26
+ imageUrl: 'icon',
27
+ connectors: [],
28
+ walletInfo: {},
29
+ isInjected: false,
30
+ isRecent: false
31
+ };
32
+ beforeEach(() => {
33
+ vi.restoreAllMocks();
34
+ vi.spyOn(ChainController, 'state', 'get').mockReturnValue({
35
+ activeChain: 'eip155'
36
+ });
37
+ vi.spyOn(PublicStateController, 'set').mockImplementation(vi.fn());
38
+ });
39
+ describe('HeadlessWalletUtil.fetchWallets', () => {
40
+ it('searches when a search term is given', async () => {
41
+ const searchWallet = vi
42
+ .spyOn(ApiController, 'searchWallet')
43
+ .mockResolvedValue(undefined);
44
+ const fetchByPage = vi.spyOn(ApiController, 'fetchWalletsByPage');
45
+ await HeadlessWalletUtil.fetchWallets({ search: 'rainbow', includePayOnly: true });
46
+ expect(searchWallet).toHaveBeenCalledWith({ includePayOnly: true, search: 'rainbow' });
47
+ expect(fetchByPage).not.toHaveBeenCalled();
48
+ });
49
+ it('maps the deprecated `query` to `search`', async () => {
50
+ const searchWallet = vi
51
+ .spyOn(ApiController, 'searchWallet')
52
+ .mockResolvedValue(undefined);
53
+ await HeadlessWalletUtil.fetchWallets({ query: 'rbw' });
54
+ expect(searchWallet).toHaveBeenCalledWith({ search: 'rbw' });
55
+ });
56
+ it('lists from page 1 and clears prior search when no search term', async () => {
57
+ const fetchByPage = vi
58
+ .spyOn(ApiController, 'fetchWalletsByPage')
59
+ .mockResolvedValue(undefined);
60
+ ApiController.state.search = [{ id: 'stale' }];
61
+ await HeadlessWalletUtil.fetchWallets({ sort: 'wcpay' });
62
+ expect(ApiController.state.search).toEqual([]);
63
+ expect(fetchByPage).toHaveBeenCalledWith({ page: 1, sort: 'wcpay' });
64
+ });
65
+ });
66
+ describe('HeadlessWalletUtil.getWalletList', () => {
67
+ it('projects the initial + WalletConnect lists with pagination', () => {
68
+ vi.spyOn(ConnectUtil, 'getInitialWallets').mockReturnValue([injectedWallet]);
69
+ vi.spyOn(ConnectUtil, 'getWalletConnectWallets').mockReturnValue([apiWallet]);
70
+ ApiController.state.page = 2;
71
+ ApiController.state.count = 99;
72
+ expect(HeadlessWalletUtil.getWalletList()).toEqual({
73
+ wallets: [injectedWallet],
74
+ wcWallets: [apiWallet],
75
+ page: 2,
76
+ count: 99
77
+ });
78
+ });
79
+ });
80
+ describe('HeadlessWalletUtil.connect', () => {
81
+ it('connects an injected wallet via its connector', async () => {
82
+ const connector = { id: 'io.metamask' };
83
+ vi.spyOn(ConnectorController, 'getConnector').mockReturnValue(connector);
84
+ const connectExternal = vi
85
+ .spyOn(ConnectorControllerUtil, 'connectExternal')
86
+ .mockResolvedValue(undefined);
87
+ await HeadlessWalletUtil.connect(injectedWallet, 'eip155');
88
+ expect(PublicStateController.set).toHaveBeenCalledWith({ connectingWallet: injectedWallet });
89
+ expect(connectExternal).toHaveBeenCalledWith(connector);
90
+ });
91
+ it('falls back to a connector found by wallet id (API wallet)', async () => {
92
+ const fallback = { id: 'baseAccount', explorerId: 'wc_wallet' };
93
+ // apiWallet has no connectors, so the first (guarded) lookup is skipped — only the
94
+ // fallback lookup by wallet id runs, and it resolves the Base Account connector.
95
+ const getConnector = vi
96
+ .spyOn(ConnectorController, 'getConnector')
97
+ .mockReturnValue(fallback);
98
+ const connectExternal = vi
99
+ .spyOn(ConnectorControllerUtil, 'connectExternal')
100
+ .mockResolvedValue(undefined);
101
+ await HeadlessWalletUtil.connect(apiWallet, 'eip155');
102
+ expect(getConnector).toHaveBeenCalledTimes(1);
103
+ expect(getConnector).toHaveBeenCalledWith({ id: 'wc_wallet', namespace: 'eip155' });
104
+ expect(connectExternal).toHaveBeenCalledWith(fallback);
105
+ });
106
+ it('deeplinks on mobile when the wallet declares a mobile link', async () => {
107
+ vi.spyOn(ConnectorController, 'getConnector').mockReturnValue(undefined);
108
+ vi.spyOn(CoreHelperUtil, 'isMobile').mockReturnValue(true);
109
+ vi.spyOn(ConnectUtil, 'mapWalletItemToWcWallet').mockReturnValue({
110
+ id: 'wc_wallet',
111
+ name: 'Some Wallet',
112
+ mobile_link: 'somewallet://'
113
+ });
114
+ const onConnectMobile = vi
115
+ .spyOn(ConnectionControllerUtil, 'onConnectMobile')
116
+ .mockImplementation(vi.fn());
117
+ await HeadlessWalletUtil.connect(apiWallet, 'eip155', { wcPayUrl: 'https://pay/x' });
118
+ expect(onConnectMobile).toHaveBeenCalledWith(expect.objectContaining({ mobile_link: 'somewallet://' }), 'https://pay/x');
119
+ });
120
+ it('redirects via MobileWalletUtil on mobile when there is no mobile link', async () => {
121
+ vi.spyOn(ConnectorController, 'getConnector').mockReturnValue(undefined);
122
+ vi.spyOn(CoreHelperUtil, 'isMobile').mockReturnValue(true);
123
+ vi.spyOn(ConnectUtil, 'mapWalletItemToWcWallet').mockReturnValue({
124
+ id: 'wc_wallet',
125
+ name: 'Some Wallet'
126
+ });
127
+ vi.spyOn(OptionsController, 'state', 'get').mockReturnValue({ enableCoinbase: true });
128
+ const redirect = vi
129
+ .spyOn(MobileWalletUtil, 'handleMobileDeeplinkRedirect')
130
+ .mockImplementation(vi.fn());
131
+ await HeadlessWalletUtil.connect(apiWallet, 'eip155');
132
+ expect(redirect).toHaveBeenCalledWith('wc_wallet', 'eip155', { isCoinbaseDisabled: false });
133
+ });
134
+ it('falls back to WalletConnect on desktop', async () => {
135
+ vi.spyOn(ConnectorController, 'getConnector').mockReturnValue(undefined);
136
+ vi.spyOn(CoreHelperUtil, 'isMobile').mockReturnValue(false);
137
+ const connectWc = vi
138
+ .spyOn(ConnectionController, 'connectWalletConnect')
139
+ .mockResolvedValue(undefined);
140
+ await HeadlessWalletUtil.connect(apiWallet, 'eip155');
141
+ expect(connectWc).toHaveBeenCalledWith({ cache: 'never' });
142
+ });
143
+ it('clears connectingWallet and rethrows on failure', async () => {
144
+ vi.spyOn(ConnectorController, 'getConnector').mockReturnValue({ id: 'io.metamask' });
145
+ vi.spyOn(ConnectorControllerUtil, 'connectExternal').mockRejectedValue(new Error('boom'));
146
+ await expect(HeadlessWalletUtil.connect(injectedWallet, 'eip155')).rejects.toThrow('boom');
147
+ expect(PublicStateController.set).toHaveBeenLastCalledWith({ connectingWallet: undefined });
148
+ });
149
+ it('falls back to the active chain when no namespace is given', async () => {
150
+ const getConnector = vi
151
+ .spyOn(ConnectorController, 'getConnector')
152
+ .mockReturnValue({ id: 'io.metamask' });
153
+ vi.spyOn(ConnectorControllerUtil, 'connectExternal').mockResolvedValue(undefined);
154
+ await HeadlessWalletUtil.connect(injectedWallet);
155
+ expect(getConnector).toHaveBeenCalledWith(expect.objectContaining({ namespace: 'eip155' }));
156
+ });
157
+ });
158
+ describe('HeadlessWalletUtil.prefetchWalletConnectUri', () => {
159
+ it('resets then fetches the URI with auto cache', async () => {
160
+ const resetUri = vi.spyOn(ConnectionController, 'resetUri').mockImplementation(vi.fn());
161
+ const setWcLinking = vi.spyOn(ConnectionController, 'setWcLinking').mockImplementation(vi.fn());
162
+ const connectWc = vi
163
+ .spyOn(ConnectionController, 'connectWalletConnect')
164
+ .mockResolvedValue(undefined);
165
+ await HeadlessWalletUtil.prefetchWalletConnectUri();
166
+ expect(resetUri).toHaveBeenCalled();
167
+ expect(setWcLinking).toHaveBeenCalledWith(undefined);
168
+ expect(connectWc).toHaveBeenCalledWith({ cache: 'auto' });
169
+ });
170
+ });
171
+ describe('HeadlessWalletUtil.getWalletConnectUri', () => {
172
+ it('reads wcUri / wcError / wcFetchingUri from the connection layer', () => {
173
+ ConnectionController.state.wcUri = 'wc:read-test';
174
+ ConnectionController.state.wcError = true;
175
+ ConnectionController.state.wcFetchingUri = false;
176
+ expect(HeadlessWalletUtil.getWalletConnectUri()).toEqual({
177
+ wcUri: 'wc:read-test',
178
+ wcError: true,
179
+ wcFetchingUri: false
180
+ });
181
+ });
182
+ it('coerces a missing wcError to a boolean', () => {
183
+ ConnectionController.state.wcUri = undefined;
184
+ ConnectionController.state.wcError = undefined;
185
+ ConnectionController.state.wcFetchingUri = true;
186
+ expect(HeadlessWalletUtil.getWalletConnectUri()).toEqual({
187
+ wcUri: undefined,
188
+ wcError: false,
189
+ wcFetchingUri: true
190
+ });
191
+ });
192
+ });
193
+ describe('HeadlessWalletUtil.subscribeWalletConnectUri', () => {
194
+ it('fires on wcUri / wcError / wcFetchingUri changes and unsubscribes cleanly', async () => {
195
+ const flush = () => new Promise(resolve => setTimeout(resolve, 0));
196
+ const callback = vi.fn();
197
+ // Establish a known baseline before subscribing so each mutation below is a real change.
198
+ ConnectionController.state.wcUri = undefined;
199
+ ConnectionController.state.wcFetchingUri = false;
200
+ const unsubscribe = HeadlessWalletUtil.subscribeWalletConnectUri(callback);
201
+ ConnectionController.state.wcUri = 'wc:sub-test';
202
+ await flush();
203
+ expect(callback).toHaveBeenCalledTimes(1);
204
+ ConnectionController.state.wcFetchingUri = true;
205
+ await flush();
206
+ expect(callback).toHaveBeenCalledTimes(2);
207
+ unsubscribe();
208
+ ConnectionController.state.wcUri = 'wc:after-unsub';
209
+ await flush();
210
+ expect(callback).toHaveBeenCalledTimes(2);
211
+ });
212
+ });
213
+ describe('HeadlessWalletUtil resets', () => {
214
+ it('resetWcUri resets the URI + linking', () => {
215
+ const resetUri = vi.spyOn(ConnectionController, 'resetUri').mockImplementation(vi.fn());
216
+ const setWcLinking = vi.spyOn(ConnectionController, 'setWcLinking').mockImplementation(vi.fn());
217
+ HeadlessWalletUtil.resetWcUri();
218
+ expect(resetUri).toHaveBeenCalled();
219
+ expect(setWcLinking).toHaveBeenCalledWith(undefined);
220
+ });
221
+ it('resetConnectingWallet clears the connecting wallet', () => {
222
+ HeadlessWalletUtil.resetConnectingWallet();
223
+ expect(PublicStateController.set).toHaveBeenCalledWith({ connectingWallet: undefined });
224
+ });
225
+ });
226
+ //# sourceMappingURL=HeadlessWalletUtil.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HeadlessWalletUtil.test.js","sourceRoot":"","sources":["../../../../tests/utils/HeadlessWalletUtil.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,213 @@
1
+ import { afterEach, describe, expect, it, vi } from 'vitest';
2
+ import { ChainController, isCoinbaseConnectorId, isUnauthorizedProviderError, maybeWrapCoinbaseProvider, withCoinbaseReauth } from '../../exports/index.js';
3
+ // -- Helpers ------------------------------------------------------------------
4
+ const unauthorized = () => ({
5
+ code: 4100,
6
+ message: "Must call 'eth_requestAccounts' before other methods"
7
+ });
8
+ /**
9
+ * Minimal EIP-1193-ish provider whose `request` is a spy. `impl` decides the
10
+ * behaviour per call so we can script "fail 4100 → succeed on retry".
11
+ */
12
+ function createProvider(impl) {
13
+ return {
14
+ request: vi.fn(impl),
15
+ on: vi.fn(),
16
+ removeListener: vi.fn()
17
+ };
18
+ }
19
+ // -- Tests --------------------------------------------------------------------
20
+ describe('isCoinbaseConnectorId', () => {
21
+ it('matches Coinbase connector ids, tolerating casing variants', () => {
22
+ expect(isCoinbaseConnectorId('coinbaseWallet')).toBe(true);
23
+ expect(isCoinbaseConnectorId('coinbaseWalletSDK')).toBe(true);
24
+ // wagmi restore path can surface connector.type.toUpperCase()
25
+ expect(isCoinbaseConnectorId('COINBASEWALLET')).toBe(true);
26
+ expect(isCoinbaseConnectorId('walletConnect')).toBe(false);
27
+ expect(isCoinbaseConnectorId('injected')).toBe(false);
28
+ expect(isCoinbaseConnectorId('EXTERNAL')).toBe(false);
29
+ expect(isCoinbaseConnectorId(undefined)).toBe(false);
30
+ });
31
+ });
32
+ describe('maybeWrapCoinbaseProvider', () => {
33
+ it('wraps an eip155 Coinbase provider (by connector id, not remapped type)', () => {
34
+ const provider = createProvider(async () => null);
35
+ const wrapped = maybeWrapCoinbaseProvider({
36
+ connectorId: 'coinbaseWalletSDK',
37
+ chainNamespace: 'eip155',
38
+ provider
39
+ });
40
+ expect(wrapped).not.toBe(provider);
41
+ });
42
+ it('leaves a non-Coinbase provider untouched (identity preserved)', () => {
43
+ const provider = createProvider(async () => null);
44
+ // The ethers/live paths remap Coinbase to type 'EXTERNAL'; guarding on the
45
+ // connector id (not the type) is what makes the fix adapter-agnostic.
46
+ const same = maybeWrapCoinbaseProvider({
47
+ connectorId: 'walletConnect',
48
+ chainNamespace: 'eip155',
49
+ provider
50
+ });
51
+ expect(same).toBe(provider);
52
+ });
53
+ it('does not wrap a Coinbase connector on a non-eip155 namespace', () => {
54
+ const provider = createProvider(async () => null);
55
+ const same = maybeWrapCoinbaseProvider({
56
+ connectorId: 'coinbaseWalletSDK',
57
+ chainNamespace: 'solana',
58
+ provider
59
+ });
60
+ expect(same).toBe(provider);
61
+ });
62
+ });
63
+ describe('isUnauthorizedProviderError', () => {
64
+ it('matches EIP-1193 code 4100', () => {
65
+ expect(isUnauthorizedProviderError({ code: 4100 })).toBe(true);
66
+ });
67
+ it('matches the eth_requestAccounts wording without a code', () => {
68
+ expect(isUnauthorizedProviderError({
69
+ message: "Must call 'eth_requestAccounts' before other methods"
70
+ })).toBe(true);
71
+ });
72
+ it('walks the cause chain', () => {
73
+ const nested = { message: 'wrapped', cause: { code: 4100 } };
74
+ expect(isUnauthorizedProviderError(nested)).toBe(true);
75
+ });
76
+ it('does not treat user rejection (4001) or plain errors as unauthorized', () => {
77
+ expect(isUnauthorizedProviderError({ code: 4001, message: 'User rejected' })).toBe(false);
78
+ expect(isUnauthorizedProviderError(new Error('boom'))).toBe(false);
79
+ expect(isUnauthorizedProviderError(undefined)).toBe(false);
80
+ });
81
+ it('is cycle-safe via bounded depth', () => {
82
+ const cyclic = { message: 'x' };
83
+ cyclic.cause = cyclic;
84
+ expect(isUnauthorizedProviderError(cyclic)).toBe(false);
85
+ });
86
+ });
87
+ describe('withCoinbaseReauth', () => {
88
+ afterEach(() => {
89
+ vi.restoreAllMocks();
90
+ });
91
+ it('passes through a successful request without re-auth', async () => {
92
+ const provider = createProvider(async () => '0xresult');
93
+ const wrapped = withCoinbaseReauth(provider);
94
+ await expect(wrapped.request({ method: 'eth_sign' })).resolves.toBe('0xresult');
95
+ expect(provider.request).toHaveBeenCalledTimes(1);
96
+ expect(provider.request).not.toHaveBeenCalledWith({ method: 'eth_requestAccounts' });
97
+ });
98
+ it('recovers a 4100 by re-authorizing then retrying once', async () => {
99
+ let signAttempts = 0;
100
+ const provider = createProvider(async ({ method }) => {
101
+ if (method === 'eth_signTypedData_v4') {
102
+ signAttempts += 1;
103
+ if (signAttempts === 1) {
104
+ throw unauthorized();
105
+ }
106
+ return '0xsig';
107
+ }
108
+ return null;
109
+ });
110
+ const wrapped = withCoinbaseReauth(provider);
111
+ await expect(wrapped.request({ method: 'eth_signTypedData_v4' })).resolves.toBe('0xsig');
112
+ expect(provider.request).toHaveBeenCalledWith({ method: 'eth_requestAccounts' });
113
+ // original (fail) + requestAccounts + retry (success) = 3
114
+ expect(provider.request).toHaveBeenCalledTimes(3);
115
+ });
116
+ it('re-asserts the active chain before retrying eth_sendTransaction', async () => {
117
+ vi.spyOn(ChainController, 'getActiveCaipNetwork').mockReturnValue({ id: 8453 });
118
+ let sendAttempts = 0;
119
+ const provider = createProvider(async ({ method }) => {
120
+ if (method === 'eth_sendTransaction') {
121
+ sendAttempts += 1;
122
+ if (sendAttempts === 1) {
123
+ throw unauthorized();
124
+ }
125
+ return '0xhash';
126
+ }
127
+ return null;
128
+ });
129
+ const wrapped = withCoinbaseReauth(provider);
130
+ await expect(wrapped.request({ method: 'eth_sendTransaction' })).resolves.toBe('0xhash');
131
+ // Base 8453 → 0x2105; asserted before the retry
132
+ expect(provider.request).toHaveBeenCalledWith({
133
+ method: 'wallet_switchEthereumChain',
134
+ params: [{ chainId: '0x2105' }]
135
+ });
136
+ });
137
+ it('does NOT switch chain when recovering a non-transaction method', async () => {
138
+ const switchSpy = vi.spyOn(ChainController, 'getActiveCaipNetwork');
139
+ let attempts = 0;
140
+ const provider = createProvider(async ({ method }) => {
141
+ if (method === 'eth_signTypedData_v4') {
142
+ attempts += 1;
143
+ if (attempts === 1) {
144
+ throw unauthorized();
145
+ }
146
+ return '0xsig';
147
+ }
148
+ return null;
149
+ });
150
+ const wrapped = withCoinbaseReauth(provider);
151
+ await wrapped.request({ method: 'eth_signTypedData_v4' });
152
+ expect(switchSpy).not.toHaveBeenCalled();
153
+ expect(provider.request).not.toHaveBeenCalledWith(expect.objectContaining({ method: 'wallet_switchEthereumChain' }));
154
+ });
155
+ it('propagates a non-4100 error without attempting re-auth', async () => {
156
+ const rejection = { code: 4001, message: 'User rejected' };
157
+ const provider = createProvider(async () => {
158
+ throw rejection;
159
+ });
160
+ const wrapped = withCoinbaseReauth(provider);
161
+ await expect(wrapped.request({ method: 'eth_sendTransaction' })).rejects.toBe(rejection);
162
+ expect(provider.request).toHaveBeenCalledTimes(1);
163
+ expect(provider.request).not.toHaveBeenCalledWith({ method: 'eth_requestAccounts' });
164
+ });
165
+ it('propagates a rejected re-auth prompt and does not retry the signing call', async () => {
166
+ const promptRejection = { code: 4001, message: 'User rejected the request' };
167
+ let sendAttempts = 0;
168
+ const provider = createProvider(async ({ method }) => {
169
+ if (method === 'eth_requestAccounts') {
170
+ throw promptRejection;
171
+ }
172
+ if (method === 'eth_sendTransaction') {
173
+ sendAttempts += 1;
174
+ throw unauthorized();
175
+ }
176
+ return null;
177
+ });
178
+ const wrapped = withCoinbaseReauth(provider);
179
+ await expect(wrapped.request({ method: 'eth_sendTransaction' })).rejects.toBe(promptRejection);
180
+ expect(sendAttempts).toBe(1); // no retry after the failed handshake
181
+ });
182
+ it('fails once (no loop) when the retry is still unauthorized', async () => {
183
+ const provider = createProvider(async ({ method }) => {
184
+ if (method === 'eth_requestAccounts') {
185
+ return ['0xabc'];
186
+ }
187
+ // eth_signTypedData_v4 always unauthorized
188
+ throw unauthorized();
189
+ });
190
+ const wrapped = withCoinbaseReauth(provider);
191
+ await expect(wrapped.request({ method: 'eth_signTypedData_v4' })).rejects.toMatchObject({
192
+ code: 4100
193
+ });
194
+ // original + requestAccounts + one retry = 3, then it gives up
195
+ expect(provider.request).toHaveBeenCalledTimes(3);
196
+ });
197
+ it('returns a stable wrapper for the same instance and is not double-wrapped', () => {
198
+ const provider = createProvider(async () => null);
199
+ const first = withCoinbaseReauth(provider);
200
+ const second = withCoinbaseReauth(provider);
201
+ expect(first).toBe(second);
202
+ // wrapping the wrapper is a no-op
203
+ expect(withCoinbaseReauth(first)).toBe(first);
204
+ });
205
+ it('delegates non-request members to the raw provider', () => {
206
+ const provider = createProvider(async () => null);
207
+ const wrapped = withCoinbaseReauth(provider);
208
+ const listener = () => undefined;
209
+ wrapped.on('accountsChanged', listener);
210
+ expect(provider.on).toHaveBeenCalledWith('accountsChanged', listener);
211
+ });
212
+ });
213
+ //# sourceMappingURL=ProviderReauthUtil.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProviderReauthUtil.test.js","sourceRoot":"","sources":["../../../../tests/utils/ProviderReauthUtil.test.ts"],"names":[],"mappings":"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"}