diff --git a/packages/@magic-sdk/provider/src/core/sdk-exceptions.ts b/packages/@magic-sdk/provider/src/core/sdk-exceptions.ts index 0f72f57cc..a480b0ba4 100644 --- a/packages/@magic-sdk/provider/src/core/sdk-exceptions.ts +++ b/packages/@magic-sdk/provider/src/core/sdk-exceptions.ts @@ -110,6 +110,13 @@ export function createModalNotReadyError() { return new MagicSDKError(SDKErrorCode.ModalNotReady, 'Modal is not ready.'); } +export function createResponseTimeoutError(methodType: string, messageId: number) { + return new MagicSDKError( + SDKErrorCode.ResponseTimeout, + `Response timed out for method: ${methodType} with message id: ${messageId}`, + ); +} + export function createMalformedResponseError() { return new MagicSDKError(SDKErrorCode.MalformedResponse, 'Response from the Magic iframe is malformed.'); } diff --git a/packages/@magic-sdk/provider/test/spec/core/sdk-exceptions/error-factories.spec.ts b/packages/@magic-sdk/provider/test/spec/core/sdk-exceptions/error-factories.spec.ts index 59070b14a..de8982094 100644 --- a/packages/@magic-sdk/provider/test/spec/core/sdk-exceptions/error-factories.spec.ts +++ b/packages/@magic-sdk/provider/test/spec/core/sdk-exceptions/error-factories.spec.ts @@ -35,6 +35,12 @@ test('Creates a `MODAL_NOT_READY` error', async () => { errorAssertions(error, 'MODAL_NOT_READY', 'Modal is not ready.'); }); +test('Creates a `RESPONSE_TIMEOUT` error', async () => { + const { createResponseTimeoutError } = require('../../../../src/core/sdk-exceptions'); + const error = createResponseTimeoutError('test_method', 123); + errorAssertions(error, 'RESPONSE_TIMEOUT', 'Response timed out for method: test_method with message id: 123'); +}); + test('Creates a `MALFORMED_RESPONSE` error', async () => { const { createMalformedResponseError } = require('../../../../src/core/sdk-exceptions'); const error = createMalformedResponseError(); diff --git a/packages/@magic-sdk/provider/test/spec/core/view-controller/post.spec.ts b/packages/@magic-sdk/provider/test/spec/core/view-controller/post.spec.ts index 74a83f6dd..80c93bba8 100644 --- a/packages/@magic-sdk/provider/test/spec/core/view-controller/post.spec.ts +++ b/packages/@magic-sdk/provider/test/spec/core/view-controller/post.spec.ts @@ -3,13 +3,14 @@ import browserEnv from '@ikscodes/browser-env'; import { MagicIncomingWindowMessage, MagicOutgoingWindowMessage, JsonRpcRequestPayload } from '@magic-sdk/types'; +import { create } from 'lodash'; import { createViewController, TestViewController } from '../../../factories'; import { JsonRpcResponse } from '../../../../src/core/json-rpc'; import * as storage from '../../../../src/util/storage'; import * as webCryptoUtils from '../../../../src/util/web-crypto'; import * as deviceShareWebCryptoUtils from '../../../../src/util/device-share-web-crypto'; import { SDKEnvironment } from '../../../../src/core/sdk-environment'; -import { createModalNotReadyError } from '../../../../src/core/sdk-exceptions'; +import { createModalNotReadyError, createResponseTimeoutError } from '../../../../src/core/sdk-exceptions'; /** * Create a dummy request payload. @@ -262,6 +263,24 @@ test('throws MODAL_NOT_READY error when not connected to the internet', async () } }); +test('throws RESPONSE_TIMEOUT error if response takes longer than 10 seconds', async () => { + const eventWithRt = { data: { ...responseEvent().data } }; + const { handlerSpy, onSpy } = stubViewController(viewController, [ + [MagicIncomingWindowMessage.MAGIC_HANDLE_RESPONSE, eventWithRt], + ]); + + // @ts-ignore protected variable + viewController.responseTimeout = 1; + + const payload = requestPayload(); + + try { + await viewController.post(MagicOutgoingWindowMessage.MAGIC_HANDLE_REQUEST, payload); + } catch (e) { + expect(e).toEqual(createResponseTimeoutError('eth_accounts', 1)); + } +}); + test('does not call web crypto api if platform is not web', async () => { SDKEnvironment.platform = 'react-native'; const eventWithRt = { data: { ...responseEvent().data } }; diff --git a/packages/@magic-sdk/react-native-bare/src/react-native-webview-controller.tsx b/packages/@magic-sdk/react-native-bare/src/react-native-webview-controller.tsx index 34e5b2b72..0cdda873f 100644 --- a/packages/@magic-sdk/react-native-bare/src/react-native-webview-controller.tsx +++ b/packages/@magic-sdk/react-native-bare/src/react-native-webview-controller.tsx @@ -2,7 +2,7 @@ import React, { useState, useCallback, useMemo, useEffect } from 'react'; import { Linking, StyleSheet, View } from 'react-native'; import { WebView } from 'react-native-webview'; import { SafeAreaView } from 'react-native-safe-area-context'; -import { ViewController, createModalNotReadyError } from '@magic-sdk/provider'; +import { ViewController, createModalNotReadyError, createResponseTimeoutError } from '@magic-sdk/provider'; import { MagicMessageEvent } from '@magic-sdk/types'; import { isTypedArray } from 'lodash'; import Global = NodeJS.Global; @@ -62,6 +62,7 @@ export class ReactNativeWebViewController extends ViewController { private webView!: WebView | null; private container!: ViewWrapper | null; private styles: any; + private messageTimeouts = new Map(); protected init() { this.webView = null; @@ -139,6 +140,18 @@ export class ReactNativeWebViewController extends ViewController { }, [show]); const handleWebViewMessage = useCallback((event: any) => { + const data = JSON.parse(event.nativeEvent.data); + + if (data?.response?.id) { + const messageId = data.response.id; + + // Clear timeout if message is received in time + if (this.messageTimeouts.has(messageId)) { + clearTimeout(this.messageTimeouts.get(messageId)); + this.messageTimeouts.delete(messageId); + } + } + // Process the received message this.handleReactNativeWebViewMessage(event); }, []); @@ -216,7 +229,22 @@ export class ReactNativeWebViewController extends ViewController { } protected async _post(data: any) { + // Safely access `method` and `id` from `payload`, defaulting to undefined if not present + const methodType = data.payload?.method; + const messageId = data.payload?.id; + if (this.webView && (this.webView as any).postMessage) { + // Setup timeout for message response + if (methodType && messageId) { + const timeout = setTimeout(() => { + this.messageTimeouts.delete(messageId); + + throw createResponseTimeoutError(methodType, messageId); + }, 10000); // 10-second timeout + + this.messageTimeouts.set(messageId, timeout); + } + (this.webView as any).postMessage( JSON.stringify(data, (key, value) => { // parse Typed Array to Stringify object diff --git a/packages/@magic-sdk/react-native-bare/test/spec/react-native-webview-controller/_post.spec.ts b/packages/@magic-sdk/react-native-bare/test/spec/react-native-webview-controller/_post.spec.ts index f8ceaf4a1..d0d41c32a 100644 --- a/packages/@magic-sdk/react-native-bare/test/spec/react-native-webview-controller/_post.spec.ts +++ b/packages/@magic-sdk/react-native-bare/test/spec/react-native-webview-controller/_post.spec.ts @@ -1,5 +1,6 @@ import browserEnv from '@ikscodes/browser-env'; -import { createModalNotReadyError } from '@magic-sdk/provider'; +import { createModalNotReadyError, createResponseTimeoutError } from '@magic-sdk/provider'; +import { SDKErrorCode } from '@magic-sdk/types'; import { createReactNativeWebViewController } from '../../factories'; import { reactNativeStyleSheetStub } from '../../mocks'; @@ -50,3 +51,88 @@ test('Process Typed Array in a Solana Request', async () => { 'http://example.com', ]); }); + +test('Throws RESPONSE_TIMEOUT error if response takes longer than 10 seconds', async () => { + const overlay = createReactNativeWebViewController('http://example.com'); + + const postStub = jest.fn(); + overlay.webView = { postMessage: postStub }; + + // Assume `_post` method returns a promise that rejects upon timeout + const payload = { method: 'testMethod', id: 123 }; + + try { + await overlay._post({ msgType: 'MAGIC_HANDLE_REQUEST-troll', payload }); + } catch (error) { + expect(error.code).toBe(SDKErrorCode.ResponseTimeout); + } +}); + +test('Adds a timeout to messageTimeouts map on message send', async () => { + const overlay = createReactNativeWebViewController('http://example.com'); + + overlay.webView = { postMessage: jest.fn() }; + const payload = { method: 'testMethod', id: 123 }; + + try { + await overlay._post({ msgType: 'MAGIC_HANDLE_REQUEST-troll', payload }); + } catch (error) { + expect(error.code).toBe(SDKErrorCode.ResponseTimeout); + } + + expect(overlay.messageTimeouts.has(123)).toBe(true); +}); + +test('Removes timeout from messageTimeouts map on response', async () => { + const overlay = createReactNativeWebViewController('http://example.com'); + + // Mock the WebView and its postMessage method + overlay.webView = { postMessage: jest.fn() }; + + const payload = { method: 'testMethod', id: 123 }; + try { + await overlay._post({ msgType: 'MAGIC_HANDLE_REQUEST-troll', payload }); + } catch (error) { + expect(error.code).toBe(SDKErrorCode.ResponseTimeout); + } + + try { + // Simulate receiving a response by directly invoking the message handler + overlay.handleReactNativeWebViewMessage({ + nativeEvent: { + data: JSON.stringify({ response: { id: 123 } }), + }, + }); + } catch (e) { + console.log(e); + } + + expect(overlay.messageTimeouts.has(123)).toBe(true); +}); + +test('Removes timeout from messageTimeouts map on timeout', async () => { + expect.assertions(2); // Make sure both assertions are checked + const overlay = createReactNativeWebViewController('http://example.com'); + + overlay.webView = { postMessage: jest.fn() }; + + // Mock setTimeout to immediately invoke its callback to simulate a timeout + jest.spyOn(global, 'setTimeout').mockImplementationOnce((cb) => { + cb(); + return 123; // Return a mock timer ID + }); + + const payload = { method: 'testMethod', id: 123 }; + + try { + await overlay._post({ msgType: 'MAGIC_HANDLE_REQUEST-troll', payload }); + } catch (error) { + // Expect that the error was thrown due to a timeout + expect(error.code).toBe(SDKErrorCode.ResponseTimeout); + // Expect that the timeout was removed from the map after the error was thrown + expect(overlay.messageTimeouts.has(123)).toBe(false); + } + + // Restore original setTimeout function + jest.restoreAllMocks(); +}); diff --git a/packages/@magic-sdk/react-native-expo/src/react-native-webview-controller.tsx b/packages/@magic-sdk/react-native-expo/src/react-native-webview-controller.tsx index 97c1f802a..3b035de1a 100644 --- a/packages/@magic-sdk/react-native-expo/src/react-native-webview-controller.tsx +++ b/packages/@magic-sdk/react-native-expo/src/react-native-webview-controller.tsx @@ -2,7 +2,7 @@ import React, { useState, useCallback, useMemo, useEffect } from 'react'; import { Linking, StyleSheet, View } from 'react-native'; import { WebView } from 'react-native-webview'; import { SafeAreaView } from 'react-native-safe-area-context'; -import { ViewController, createModalNotReadyError } from '@magic-sdk/provider'; +import { ViewController, createModalNotReadyError, createResponseTimeoutError } from '@magic-sdk/provider'; import { MagicMessageEvent } from '@magic-sdk/types'; import { isTypedArray } from 'lodash'; import Global = NodeJS.Global; @@ -62,6 +62,7 @@ export class ReactNativeWebViewController extends ViewController { private webView!: WebView | null; private container!: ViewWrapper | null; private styles: any; + private messageTimeouts = new Map(); protected init() { this.webView = null; @@ -139,6 +140,18 @@ export class ReactNativeWebViewController extends ViewController { }, [show]); const handleWebViewMessage = useCallback((event: any) => { + const data = JSON.parse(event.nativeEvent.data); + + if (data?.response?.id) { + const messageId = data.response.id; + + // Clear timeout if message is received in time + if (this.messageTimeouts.has(messageId)) { + clearTimeout(this.messageTimeouts.get(messageId)); + this.messageTimeouts.delete(messageId); + } + } + // Process the received message this.handleReactNativeWebViewMessage(event); }, []); @@ -216,7 +229,21 @@ export class ReactNativeWebViewController extends ViewController { } protected async _post(data: any) { + // Safely access `method` and `id` from `payload`, defaulting to undefined if not present + const methodType = data.payload?.method; + const messageId = data.payload?.id; + if (this.webView && (this.webView as any).postMessage) { + // Setup timeout for message response + if (methodType && messageId) { + const timeout = setTimeout(() => { + this.messageTimeouts.delete(messageId); + throw createResponseTimeoutError(methodType, messageId); + }, 10000); // 10-second timeout + + this.messageTimeouts.set(messageId, timeout); + } + (this.webView as any).postMessage( JSON.stringify(data, (key, value) => { // parse Typed Array to Stringify object diff --git a/packages/@magic-sdk/react-native-expo/test/spec/react-native-webview-controller/_post.spec.ts b/packages/@magic-sdk/react-native-expo/test/spec/react-native-webview-controller/_post.spec.ts index f8ceaf4a1..00d15097b 100644 --- a/packages/@magic-sdk/react-native-expo/test/spec/react-native-webview-controller/_post.spec.ts +++ b/packages/@magic-sdk/react-native-expo/test/spec/react-native-webview-controller/_post.spec.ts @@ -1,5 +1,6 @@ import browserEnv from '@ikscodes/browser-env'; -import { createModalNotReadyError } from '@magic-sdk/provider'; +import { createModalNotReadyError, createResponseTimeoutError } from '@magic-sdk/provider'; +import { SDKErrorCode } from '@magic-sdk/types'; import { createReactNativeWebViewController } from '../../factories'; import { reactNativeStyleSheetStub } from '../../mocks'; @@ -50,3 +51,87 @@ test('Process Typed Array in a Solana Request', async () => { 'http://example.com', ]); }); + +test('Throws RESPONSE_TIMEOUT error if response takes longer than 10 seconds', async () => { + const overlay = createReactNativeWebViewController('http://example.com'); + const postStub = jest.fn(); + overlay.webView = { postMessage: postStub }; + + // Assume `_post` method returns a promise that rejects upon timeout + const payload = { method: 'testMethod', id: 123 }; + + try { + await overlay._post({ msgType: 'MAGIC_HANDLE_REQUEST-troll', payload }); + } catch (error) { + expect(error.code).toBe(SDKErrorCode.ResponseTimeout); + } +}); + +test('Adds a timeout to messageTimeouts map on message send', async () => { + const overlay = createReactNativeWebViewController('http://example.com'); + + overlay.webView = { postMessage: jest.fn() }; + const payload = { method: 'testMethod', id: 123 }; + + try { + await overlay._post({ msgType: 'MAGIC_HANDLE_REQUEST-troll', payload }); + } catch (error) { + expect(error.code).toBe(SDKErrorCode.ResponseTimeout); + } + + expect(overlay.messageTimeouts.has(123)).toBe(true); +}); + +test('Removes timeout from messageTimeouts map on response', async () => { + const overlay = createReactNativeWebViewController('http://example.com'); + + // Mock the WebView and its postMessage method + overlay.webView = { postMessage: jest.fn() }; + + const payload = { method: 'testMethod', id: 123 }; + try { + await overlay._post({ msgType: 'MAGIC_HANDLE_REQUEST-troll', payload }); + } catch (error) { + expect(error.code).toBe(SDKErrorCode.ResponseTimeout); + } + + try { + // Simulate receiving a response by directly invoking the message handler + overlay.handleReactNativeWebViewMessage({ + nativeEvent: { + data: JSON.stringify({ response: { id: 123 } }), + }, + }); + } catch (e) { + console.log(e); + } + + expect(overlay.messageTimeouts.has(123)).toBe(true); +}); + +test('Removes timeout from messageTimeouts map on timeout', async () => { + expect.assertions(2); // Make sure both assertions are checked + const overlay = createReactNativeWebViewController('http://example.com'); + + overlay.webView = { postMessage: jest.fn() }; + + // Mock setTimeout to immediately invoke its callback to simulate a timeout + jest.spyOn(global, 'setTimeout').mockImplementationOnce((cb) => { + cb(); + return 123; // Return a mock timer ID + }); + + const payload = { method: 'testMethod', id: 123 }; + + try { + await overlay._post({ msgType: 'MAGIC_HANDLE_REQUEST-troll', payload }); + } catch (error) { + // Expect that the error was thrown due to a timeout + expect(error.code).toBe(SDKErrorCode.ResponseTimeout); + // Expect that the timeout was removed from the map after the error was thrown + expect(overlay.messageTimeouts.has(123)).toBe(false); + } + + // Restore original setTimeout function + jest.restoreAllMocks(); +}); diff --git a/packages/@magic-sdk/types/src/core/exception-types.ts b/packages/@magic-sdk/types/src/core/exception-types.ts index 322623b55..a4d300896 100644 --- a/packages/@magic-sdk/types/src/core/exception-types.ts +++ b/packages/@magic-sdk/types/src/core/exception-types.ts @@ -5,6 +5,7 @@ export enum SDKErrorCode { InvalidArgument = 'INVALID_ARGUMENT', ExtensionNotInitialized = 'EXTENSION_NOT_INITIALIZED', IncompatibleExtensions = 'INCOMPATIBLE_EXTENSIONS', + ResponseTimeout = 'RESPONSE_TIMEOUT', } export enum SDKWarningCode { diff --git a/yarn.lock b/yarn.lock index eea7c786f..42e053a1f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2045,7 +2045,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/algorand@workspace:packages/@magic-ext/algorand" dependencies: - "@magic-sdk/commons": ^20.0.0 + "@magic-sdk/commons": ^21.0.0 languageName: unknown linkType: soft @@ -2054,8 +2054,8 @@ __metadata: resolution: "@magic-ext/aptos@workspace:packages/@magic-ext/aptos" dependencies: "@aptos-labs/wallet-adapter-core": ^2.2.0 - "@magic-sdk/commons": ^20.0.0 - "@magic-sdk/provider": ^24.0.0 + "@magic-sdk/commons": ^21.0.0 + "@magic-sdk/provider": ^25.0.0 aptos: ^1.8.5 peerDependencies: "@aptos-labs/wallet-adapter-core": ^2.2.0 @@ -2067,7 +2067,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/avalanche@workspace:packages/@magic-ext/avalanche" dependencies: - "@magic-sdk/commons": ^20.0.0 + "@magic-sdk/commons": ^21.0.0 languageName: unknown linkType: soft @@ -2075,7 +2075,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/bitcoin@workspace:packages/@magic-ext/bitcoin" dependencies: - "@magic-sdk/commons": ^20.0.0 + "@magic-sdk/commons": ^21.0.0 languageName: unknown linkType: soft @@ -2083,7 +2083,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/conflux@workspace:packages/@magic-ext/conflux" dependencies: - "@magic-sdk/commons": ^20.0.0 + "@magic-sdk/commons": ^21.0.0 languageName: unknown linkType: soft @@ -2091,7 +2091,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/cosmos@workspace:packages/@magic-ext/cosmos" dependencies: - "@magic-sdk/commons": ^20.0.0 + "@magic-sdk/commons": ^21.0.0 languageName: unknown linkType: soft @@ -2099,7 +2099,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/ed25519@workspace:packages/@magic-ext/ed25519" dependencies: - "@magic-sdk/commons": ^20.0.0 + "@magic-sdk/commons": ^21.0.0 languageName: unknown linkType: soft @@ -2107,7 +2107,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/flow@workspace:packages/@magic-ext/flow" dependencies: - "@magic-sdk/commons": ^20.0.0 + "@magic-sdk/commons": ^21.0.0 "@onflow/fcl": ^1.4.1 "@onflow/types": ^1.1.0 peerDependencies: @@ -2120,8 +2120,8 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/gdkms@workspace:packages/@magic-ext/gdkms" dependencies: - "@magic-sdk/commons": ^20.0.0 - "@magic-sdk/types": ^20.0.0 + "@magic-sdk/commons": ^21.0.0 + "@magic-sdk/types": ^21.0.0 "@peculiar/webcrypto": ^1.4.3 languageName: unknown linkType: soft @@ -2130,7 +2130,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/harmony@workspace:packages/@magic-ext/harmony" dependencies: - "@magic-sdk/commons": ^20.0.0 + "@magic-sdk/commons": ^21.0.0 languageName: unknown linkType: soft @@ -2148,7 +2148,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/icon@workspace:packages/@magic-ext/icon" dependencies: - "@magic-sdk/commons": ^20.0.0 + "@magic-sdk/commons": ^21.0.0 languageName: unknown linkType: soft @@ -2156,7 +2156,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/near@workspace:packages/@magic-ext/near" dependencies: - "@magic-sdk/commons": ^20.0.0 + "@magic-sdk/commons": ^21.0.0 languageName: unknown linkType: soft @@ -2164,17 +2164,17 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/oauth2@workspace:packages/@magic-ext/oauth2" dependencies: - "@magic-sdk/commons": ^20.0.0 + "@magic-sdk/commons": ^21.0.0 "@types/crypto-js": ~3.1.47 crypto-js: ^3.3.0 languageName: unknown linkType: soft -"@magic-ext/oauth@^18.0.0, @magic-ext/oauth@workspace:packages/@magic-ext/oauth": +"@magic-ext/oauth@^19.0.0, @magic-ext/oauth@workspace:packages/@magic-ext/oauth": version: 0.0.0-use.local resolution: "@magic-ext/oauth@workspace:packages/@magic-ext/oauth" dependencies: - "@magic-sdk/commons": ^20.0.0 + "@magic-sdk/commons": ^21.0.0 "@types/crypto-js": ~3.1.47 crypto-js: ^3.3.0 languageName: unknown @@ -2184,7 +2184,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/oidc@workspace:packages/@magic-ext/oidc" dependencies: - "@magic-sdk/commons": ^20.0.0 + "@magic-sdk/commons": ^21.0.0 languageName: unknown linkType: soft @@ -2192,7 +2192,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/polkadot@workspace:packages/@magic-ext/polkadot" dependencies: - "@magic-sdk/commons": ^20.0.0 + "@magic-sdk/commons": ^21.0.0 languageName: unknown linkType: soft @@ -2200,8 +2200,8 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/react-native-bare-oauth@workspace:packages/@magic-ext/react-native-bare-oauth" dependencies: - "@magic-sdk/react-native-bare": ^25.0.0 - "@magic-sdk/types": ^20.0.0 + "@magic-sdk/react-native-bare": ^26.0.0 + "@magic-sdk/types": ^21.0.0 "@types/crypto-js": ~3.1.47 crypto-js: ^3.3.0 react-native-device-info: ^10.3.0 @@ -2216,7 +2216,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/react-native-expo-oauth@workspace:packages/@magic-ext/react-native-expo-oauth" dependencies: - "@magic-sdk/react-native-expo": ^25.0.0 + "@magic-sdk/react-native-expo": ^26.0.0 "@magic-sdk/types": ^10.0.0 "@types/crypto-js": ~3.1.47 crypto-js: ^3.3.0 @@ -2231,7 +2231,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/solana@workspace:packages/@magic-ext/solana" dependencies: - "@magic-sdk/commons": ^20.0.0 + "@magic-sdk/commons": ^21.0.0 "@solana/web3.js": ^1.87.2 peerDependencies: "@solana/web3.js": ^1.87.2 @@ -2242,7 +2242,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/taquito@workspace:packages/@magic-ext/taquito" dependencies: - "@magic-sdk/commons": ^20.0.0 + "@magic-sdk/commons": ^21.0.0 languageName: unknown linkType: soft @@ -2250,7 +2250,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/terra@workspace:packages/@magic-ext/terra" dependencies: - "@magic-sdk/commons": ^20.0.0 + "@magic-sdk/commons": ^21.0.0 languageName: unknown linkType: soft @@ -2258,7 +2258,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/tezos@workspace:packages/@magic-ext/tezos" dependencies: - "@magic-sdk/commons": ^20.0.0 + "@magic-sdk/commons": ^21.0.0 languageName: unknown linkType: soft @@ -2266,7 +2266,7 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/webauthn@workspace:packages/@magic-ext/webauthn" dependencies: - "@magic-sdk/commons": ^20.0.0 + "@magic-sdk/commons": ^21.0.0 languageName: unknown linkType: soft @@ -2274,16 +2274,16 @@ __metadata: version: 0.0.0-use.local resolution: "@magic-ext/zilliqa@workspace:packages/@magic-ext/zilliqa" dependencies: - "@magic-sdk/commons": ^20.0.0 + "@magic-sdk/commons": ^21.0.0 languageName: unknown linkType: soft -"@magic-sdk/commons@^20.0.0, @magic-sdk/commons@workspace:packages/@magic-sdk/commons": +"@magic-sdk/commons@^21.0.0, @magic-sdk/commons@workspace:packages/@magic-sdk/commons": version: 0.0.0-use.local resolution: "@magic-sdk/commons@workspace:packages/@magic-sdk/commons" dependencies: - "@magic-sdk/provider": ^24.0.0 - "@magic-sdk/types": ^20.0.0 + "@magic-sdk/provider": ^25.0.0 + "@magic-sdk/types": ^21.0.0 peerDependencies: "@magic-sdk/provider": ">=18.6.0" "@magic-sdk/types": ">=15.8.0" @@ -2307,17 +2307,17 @@ __metadata: "@babel/core": ^7.9.6 "@babel/plugin-proposal-optional-chaining": ^7.9.0 "@babel/runtime": ^7.9.6 - "@magic-ext/oauth": ^18.0.0 - magic-sdk: ^24.0.0 + "@magic-ext/oauth": ^19.0.0 + magic-sdk: ^25.0.0 languageName: unknown linkType: soft -"@magic-sdk/provider@^24.0.0, @magic-sdk/provider@workspace:packages/@magic-sdk/provider": +"@magic-sdk/provider@^25.0.0, @magic-sdk/provider@workspace:packages/@magic-sdk/provider": version: 0.0.0-use.local resolution: "@magic-sdk/provider@workspace:packages/@magic-sdk/provider" dependencies: "@babel/plugin-transform-modules-commonjs": ^7.9.6 - "@magic-sdk/types": ^20.0.0 + "@magic-sdk/types": ^21.0.0 "@peculiar/webcrypto": ^1.1.7 eventemitter3: ^4.0.4 localforage: ^1.7.4 @@ -2329,7 +2329,7 @@ __metadata: languageName: unknown linkType: soft -"@magic-sdk/react-native-bare@^25.0.0, @magic-sdk/react-native-bare@workspace:packages/@magic-sdk/react-native-bare": +"@magic-sdk/react-native-bare@^26.0.0, @magic-sdk/react-native-bare@workspace:packages/@magic-sdk/react-native-bare": version: 0.0.0-use.local resolution: "@magic-sdk/react-native-bare@workspace:packages/@magic-sdk/react-native-bare" dependencies: @@ -2337,9 +2337,9 @@ __metadata: "@babel/core": ^7.15.0 "@babel/plugin-transform-flow-strip-types": ^7.14.5 "@babel/runtime": ~7.10.4 - "@magic-sdk/commons": ^20.0.0 - "@magic-sdk/provider": ^24.0.0 - "@magic-sdk/types": ^20.0.0 + "@magic-sdk/commons": ^21.0.0 + "@magic-sdk/provider": ^25.0.0 + "@magic-sdk/types": ^21.0.0 "@react-native-async-storage/async-storage": ^1.15.5 "@react-native-community/netinfo": ">11.0.0" "@testing-library/react-native": ^12.4.0 @@ -2369,7 +2369,7 @@ __metadata: languageName: unknown linkType: soft -"@magic-sdk/react-native-expo@^25.0.0, @magic-sdk/react-native-expo@workspace:packages/@magic-sdk/react-native-expo": +"@magic-sdk/react-native-expo@^26.0.0, @magic-sdk/react-native-expo@workspace:packages/@magic-sdk/react-native-expo": version: 0.0.0-use.local resolution: "@magic-sdk/react-native-expo@workspace:packages/@magic-sdk/react-native-expo" dependencies: @@ -2377,9 +2377,9 @@ __metadata: "@babel/core": ^7.15.0 "@babel/plugin-transform-flow-strip-types": ^7.14.5 "@babel/runtime": ~7.10.4 - "@magic-sdk/commons": ^20.0.0 - "@magic-sdk/provider": ^24.0.0 - "@magic-sdk/types": ^20.0.0 + "@magic-sdk/commons": ^21.0.0 + "@magic-sdk/provider": ^25.0.0 + "@magic-sdk/types": ^21.0.0 "@react-native-async-storage/async-storage": ^1.15.5 "@react-native-community/netinfo": ">11.0.0" "@testing-library/react-native": ^12.4.0 @@ -2409,7 +2409,7 @@ __metadata: languageName: unknown linkType: soft -"@magic-sdk/types@^20.0.0, @magic-sdk/types@workspace:packages/@magic-sdk/types": +"@magic-sdk/types@^21.0.0, @magic-sdk/types@workspace:packages/@magic-sdk/types": version: 0.0.0-use.local resolution: "@magic-sdk/types@workspace:packages/@magic-sdk/types" languageName: unknown @@ -12754,16 +12754,16 @@ fsevents@^2.3.2: languageName: unknown linkType: soft -"magic-sdk@^24.0.0, magic-sdk@workspace:packages/magic-sdk": +"magic-sdk@^25.0.0, magic-sdk@workspace:packages/magic-sdk": version: 0.0.0-use.local resolution: "magic-sdk@workspace:packages/magic-sdk" dependencies: "@babel/core": ^7.9.6 "@babel/plugin-proposal-optional-chaining": ^7.9.0 "@babel/runtime": ^7.9.6 - "@magic-sdk/commons": ^20.0.0 - "@magic-sdk/provider": ^24.0.0 - "@magic-sdk/types": ^20.0.0 + "@magic-sdk/commons": ^21.0.0 + "@magic-sdk/provider": ^25.0.0 + "@magic-sdk/types": ^21.0.0 localforage: ^1.7.4 localforage-driver-memory: ^1.0.5 languageName: unknown