Skip to content

Commit ac8f8c3

Browse files
authored
feat: multichain initial request+deeplinks (#1351)
* fix: upgrade dependencies and improve test typings * fix: refactor unitary tests, improve logic and testing fixtures * fix: improve tests docs and uncomment connect.test.ts * fix: add web mobile testing scenario and fixtures * fix: adding web mobile env tests * fix: configure tests to set proper user agent for mobile web * fix: improve install modal and testing * fix: adding support for invokeMethod and reconnecting after deeplinks * fix: issue setting the default transport when running install modal * fix: improve tests and separation of concerns * fix: linter issues * fix: invoke test fixes * fix: remove only * fix: restore missing tests * fix: expire connections * fix: clear timeout after request completes or rejects * fix: increase grace period
1 parent 1cff69d commit ac8f8c3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+2101
-1447
lines changed

packages/sdk-multichain/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"@biomejs/biome": "2.0.0",
3333
"@metamask/auto-changelog": "^3.4.3",
3434
"@react-native-async-storage/async-storage": "^1.23.1",
35+
"@types/jsdom": "^21.1.7",
3536
"@types/ws": "^8.18.1",
3637
"@vitest/coverage-v8": "^3.2.4",
3738
"esbuild-plugin-umd-wrapper": "^3.0.0",
@@ -53,8 +54,8 @@
5354
},
5455
"license": "MIT",
5556
"dependencies": {
56-
"@metamask/mobile-wallet-protocol-core": "^0.1.0",
57-
"@metamask/mobile-wallet-protocol-dapp-client": "^0.1.0",
57+
"@metamask/mobile-wallet-protocol-core": "^0.2.0",
58+
"@metamask/mobile-wallet-protocol-dapp-client": "^0.2.1",
5859
"@metamask/multichain-api-client": "^0.8.0",
5960
"@metamask/onboarding": "^1.0.1",
6061
"@metamask/sdk-analytics": "workspace:^",
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
export const MWP_RELAY_URL = 'wss://mm-sdk-relay.api.cx.metamask.io/connection/websocket';
2+
3+
export const METAMASK_CONNECT_BASE_URL = 'https://metamask.app.link/connect';
4+
export const METAMASK_DEEPLINK_BASE = 'metamask://connect';

packages/sdk-multichain/src/connect.test.ts

Lines changed: 192 additions & 284 deletions
Large diffs are not rendered by default.

packages/sdk-multichain/src/domain/errors/rpc.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@ export class RPCReadonlyRequestErr extends BaseErr<'RPC', RPCErrorCodes> {
2929
export class RPCInvokeMethodErr extends BaseErr<'RPC', RPCErrorCodes> {
3030
static readonly code = 53;
3131
constructor(public readonly reason: string) {
32-
super(`RPCErr${RPCInvokeMethodErr.code}: RPC Client invoke method reason ${reason}`, RPCInvokeMethodErr.code);
32+
super(`RPCErr${RPCInvokeMethodErr.code}: RPC Client invoke method reason (${reason})`, RPCInvokeMethodErr.code);
3333
}
3434
}

packages/sdk-multichain/src/domain/multichain/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ export abstract class MultichainCore extends EventEmitter<SDKEvents> {
2525
abstract provider: MultichainApiClient<RPCAPI>;
2626
abstract transport: Transport;
2727

28-
abstract getCurrentSession(): Promise<SessionData | undefined>;
2928
/**
3029
* Establishes a connection to the multichain provider, or re-use existing session
3130
*

packages/sdk-multichain/src/domain/multichain/types.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import type { StoreClient } from '../store';
2-
import type { MultichainCore, SessionData } from '.';
3-
import type { RPC_URLS_MAP } from './api/types';
2+
import type { MultichainCore } from '.';
3+
import type { RPC_URLS_MAP, Scope } from './api/types';
44
import type { ModalFactory } from '../../ui';
55
import type { SessionRequest } from '@metamask/mobile-wallet-protocol-core';
66
import type { PlatformType } from '../platform';
7+
import type { Transport } from '@metamask/multichain-api-client';
8+
import type { CaipAccountId } from '@metamask/utils';
79

810
export type { SessionData } from '@metamask/multichain-api-client';
911

@@ -56,13 +58,19 @@ export type MultichainOptions = {
5658
preferDesktop?: boolean;
5759
};
5860
mobile?: {
61+
preferredOpenLink?: (deeplink: string, target?: string) => void;
62+
/**
63+
* The `MetaMaskSDK` constructor option `useDeeplink: boolean` controls which type of link is used:
64+
* - If `true`, the SDK will attempt to use the `metamask://` deeplink.
65+
* - If `false` (the default for web), the SDK will use the `https://metamask.app.link` universal link.
66+
*/
5967
useDeeplink?: boolean;
6068
};
6169
/** Optional transport configuration */
6270
transport?: {
6371
/** Extension ID for browser extension transport */
6472
extensionId?: string;
65-
onResumeSession?: (session: SessionData) => void;
73+
onNotification?: (notification: unknown) => void;
6674
};
6775
};
6876

@@ -79,3 +87,7 @@ type MultiChainFNOptions = Omit<MultichainOptions, 'storage' | 'ui'> & {
7987
* providing all necessary options for SDK initialization.
8088
*/
8189
export type CreateMultichainFN = (options: MultiChainFNOptions) => Promise<MultichainCore>;
90+
91+
export type ExtendedTransport = Omit<Transport, 'connect'> & {
92+
connect: (props?: { scopes: Scope[]; caipAccountIds: CaipAccountId[] }) => Promise<void>;
93+
};

packages/sdk-multichain/src/domain/platform/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,15 @@ export function isMetamaskExtensionInstalled(): boolean {
7474
}
7575
return Boolean(window.ethereum?.isMetaMask);
7676
}
77+
78+
export function isSecure() {
79+
const platformType = getPlatformType();
80+
return isReactNative() || platformType === PlatformType.MobileWeb;
81+
}
82+
83+
export function hasExtension() {
84+
if (typeof window !== 'undefined') {
85+
return window.ethereum?.isMetaMask ?? false;
86+
}
87+
return false;
88+
}

packages/sdk-multichain/src/domain/ui/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export interface InstallWidgetProps extends Components.MmInstallModal {
1515

1616
export interface OTPCodeWidgetProps extends Components.MmOtpModal {
1717
parentElement?: Element;
18-
onClose: () => void;
18+
onClose: () => Promise<void>;
1919
onDisconnect?: () => void;
2020
createOTPCode: () => Promise<OTPCode>;
2121
updateOTPCode: (otpValue: string) => void;

0 commit comments

Comments
 (0)