Skip to content

Commit

Permalink
feat: separately handle extension connectWith
Browse files Browse the repository at this point in the history
  • Loading branch information
abretonc7s committed Mar 15, 2024
1 parent 9e79977 commit 3476c77
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 58 deletions.
76 changes: 48 additions & 28 deletions packages/sdk/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,3 @@
export const METHODS_TO_REDIRECT: { [method: string]: boolean } = {
eth_requestAccounts: true,
eth_sendTransaction: true,
eth_signTransaction: true,
eth_sign: true,
eth_accounts: true,
personal_sign: true,
eth_signTypedData: true,
eth_signTypedData_v3: true,
eth_signTypedData_v4: true,
wallet_requestPermissions: true,
wallet_getPermissions: true,
wallet_watchAsset: true,
wallet_addEthereumChain: true,
wallet_switchEthereumChain: true,
metamask_connectSign: true,
metamask_connectWith: true,
personal_ecRecover: true,
metamask_batch: true,
metamask_open: true,
};

export const lcAnalyticsRPCs = Object.keys(METHODS_TO_REDIRECT).map((method) =>
method.toLowerCase(),
);

export const STORAGE_PATH = '.sdk-comm';
export const STORAGE_PROVIDER_TYPE = 'providerType';
export const RPC_METHODS = {
METAMASK_GETPROVIDERSTATE: 'metamask_getProviderState',
METAMASK_CONNECTSIGN: 'metamask_connectSign',
Expand All @@ -34,11 +6,59 @@ export const RPC_METHODS = {
METAMASK_BATCH: 'metamask_batch',
PERSONAL_SIGN: 'personal_sign',
WALLET_REQUESTPERMISSIONS: 'wallet_requestPermissions',
WALLET_GETPERMISSIONS: 'wallet_getPermissions',
WALLET_WATCHASSET: 'wallet_watchAsset',
WALLET_ADDETHEREUMCHAIN: 'wallet_addEthereumChain',
WALLET_SWITCHETHETHEREUMCHAIN: 'wallet_switchEthereumChain',
ETH_REQUESTACCOUNTS: 'eth_requestAccounts',
ETH_ACCOUNTS: 'eth_accounts',
ETH_CHAINID: 'eth_chainId',
ETH_SENDTRANSACTION: 'eth_sendTransaction',
ETH_SIGNTYPEDDATA: 'eth_signTypedData',
ETH_SIGNTYPEDDATA_V3: 'eth_signTypedData_v3',
ETH_SIGNTYPEDDATA_V4: 'eth_signTypedData_v4',
ETH_SIGNTRANSACTION: 'eth_signTransaction',
ETH_SIGN: 'eth_sign',
PERSONAL_EC_RECOVER: 'personal_ecRecover',
};

export const METHODS_TO_REDIRECT: { [method: string]: boolean } = {
[RPC_METHODS.ETH_REQUESTACCOUNTS]: true,
[RPC_METHODS.ETH_SENDTRANSACTION]: true,
[RPC_METHODS.ETH_SIGNTRANSACTION]: true,
[RPC_METHODS.ETH_SIGN]: true,
[RPC_METHODS.ETH_ACCOUNTS]: true,
[RPC_METHODS.PERSONAL_SIGN]: true,
[RPC_METHODS.ETH_SIGNTYPEDDATA]: true,
[RPC_METHODS.ETH_SIGNTYPEDDATA_V3]: true,
[RPC_METHODS.ETH_SIGNTYPEDDATA_V4]: true,
[RPC_METHODS.WALLET_REQUESTPERMISSIONS]: true,
[RPC_METHODS.WALLET_GETPERMISSIONS]: true,
[RPC_METHODS.WALLET_WATCHASSET]: true,
[RPC_METHODS.WALLET_ADDETHEREUMCHAIN]: true,
[RPC_METHODS.WALLET_SWITCHETHETHEREUMCHAIN]: true,
[RPC_METHODS.METAMASK_CONNECTSIGN]: true,
[RPC_METHODS.METAMASK_CONNECTWITH]: true,
[RPC_METHODS.PERSONAL_EC_RECOVER]: true,
[RPC_METHODS.METAMASK_BATCH]: true,
[RPC_METHODS.METAMASK_OPEN]: true,
};

export const lcAnalyticsRPCs = Object.keys(METHODS_TO_REDIRECT).map((method) =>
method.toLowerCase(),
);

// unsupported extension connectWith methods
export const rpcWithAccountParam = [
'eth_signTypedData',
'eth_signTypedData_v3',
'eth_signTypedData_v4',
'eth_sign',
].map((method) => method.toLowerCase());

export const STORAGE_PATH = '.sdk-comm';
export const STORAGE_PROVIDER_TYPE = 'providerType';

export const EXTENSION_EVENTS = {
CHAIN_CHANGED: 'chainChanged',
ACCOUNTS_CHANGED: 'accountsChanged',
Expand Down
66 changes: 66 additions & 0 deletions packages/sdk/src/provider/extensionConnectWithOverwrite.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { rpcWithAccountParam, RPC_METHODS } from '../config';
import { MetaMaskSDK } from '../sdk';
import { logger } from '../utils/logger';

export const extensionConnectWithOverwrite = async ({
method,
sdk,
params,
}: {
method: string;
sdk: MetaMaskSDK;
params: any;
}) => {
if (!sdk.isExtensionActive()) {
throw new Error(`SDK state invalid -- extension is not active`);

Check warning on line 15 in packages/sdk/src/provider/extensionConnectWithOverwrite.ts

View check run for this annotation

Codecov / codecov/patch

packages/sdk/src/provider/extensionConnectWithOverwrite.ts#L13-L15

Added lines #L13 - L15 were not covered by tests
}

logger(

Check warning on line 18 in packages/sdk/src/provider/extensionConnectWithOverwrite.ts

View check run for this annotation

Codecov / codecov/patch

packages/sdk/src/provider/extensionConnectWithOverwrite.ts#L18

Added line #L18 was not covered by tests
`[MetaMaskProvider: extensionConnectWithOverwrite()] Overwriting request method`,
method,
params,
);

const accounts = (await sdk.getProvider()?.request({

Check warning on line 24 in packages/sdk/src/provider/extensionConnectWithOverwrite.ts

View check run for this annotation

Codecov / codecov/patch

packages/sdk/src/provider/extensionConnectWithOverwrite.ts#L24

Added line #L24 was not covered by tests
method: RPC_METHODS.ETH_REQUESTACCOUNTS,
params: [],
})) as string[];
if (!accounts.length) {
throw new Error(`SDK state invalid -- undefined accounts`);

Check warning on line 29 in packages/sdk/src/provider/extensionConnectWithOverwrite.ts

View check run for this annotation

Codecov / codecov/patch

packages/sdk/src/provider/extensionConnectWithOverwrite.ts#L28-L29

Added lines #L28 - L29 were not covered by tests
}

if (method?.toLowerCase() === RPC_METHODS.PERSONAL_SIGN.toLowerCase()) {
const connectedRpc = {

Check warning on line 33 in packages/sdk/src/provider/extensionConnectWithOverwrite.ts

View check run for this annotation

Codecov / codecov/patch

packages/sdk/src/provider/extensionConnectWithOverwrite.ts#L32-L33

Added lines #L32 - L33 were not covered by tests
method,
params: [params[0], accounts[0]],
};
return await sdk.getProvider()?.request(connectedRpc);
} else if (
method?.toLowerCase() === RPC_METHODS.ETH_SENDTRANSACTION.toLowerCase()

Check warning on line 39 in packages/sdk/src/provider/extensionConnectWithOverwrite.ts

View check run for this annotation

Codecov / codecov/patch

packages/sdk/src/provider/extensionConnectWithOverwrite.ts#L37-L39

Added lines #L37 - L39 were not covered by tests
) {
const connectedRpc = {

Check warning on line 41 in packages/sdk/src/provider/extensionConnectWithOverwrite.ts

View check run for this annotation

Codecov / codecov/patch

packages/sdk/src/provider/extensionConnectWithOverwrite.ts#L41

Added line #L41 was not covered by tests
method,
params: [
{
...params[0],
from: accounts[0],
},
],
};
return await sdk.getProvider()?.request(connectedRpc);

Check warning on line 50 in packages/sdk/src/provider/extensionConnectWithOverwrite.ts

View check run for this annotation

Codecov / codecov/patch

packages/sdk/src/provider/extensionConnectWithOverwrite.ts#L50

Added line #L50 was not covered by tests
}

// TODO: implement overwrite for each remaining signedTyped methods
if (rpcWithAccountParam.includes(method.toLowerCase())) {
console.warn(

Check warning on line 55 in packages/sdk/src/provider/extensionConnectWithOverwrite.ts

View check run for this annotation

Codecov / codecov/patch

packages/sdk/src/provider/extensionConnectWithOverwrite.ts#L54-L55

Added lines #L54 - L55 were not covered by tests
`MetaMaskSDK connectWith method=${method} -- not handled by the extension -- call separately`,
);
return accounts;

Check warning on line 58 in packages/sdk/src/provider/extensionConnectWithOverwrite.ts

View check run for this annotation

Codecov / codecov/patch

packages/sdk/src/provider/extensionConnectWithOverwrite.ts#L58

Added line #L58 was not covered by tests
}

// Re-create the query on the active provider
return await sdk.getProvider()?.request({

Check warning on line 62 in packages/sdk/src/provider/extensionConnectWithOverwrite.ts

View check run for this annotation

Codecov / codecov/patch

packages/sdk/src/provider/extensionConnectWithOverwrite.ts#L62

Added line #L62 was not covered by tests
method,
params,
});
};
48 changes: 18 additions & 30 deletions packages/sdk/src/provider/initializeMobileProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { rpcRequestHandler } from '../services/rpc-requests/RPCRequestHandler';
import { PROVIDER_UPDATE_TYPE } from '../types/ProviderUpdateType';
import { logger } from '../utils/logger';
import { wait } from '../utils/wait';
import { extensionConnectWithOverwrite } from './extensionConnectWithOverwrite';

const initializeMobileProvider = ({
checkInstallationOnAllCalls = false,
Expand Down Expand Up @@ -193,6 +194,8 @@ const initializeMobileProvider = ({
(!isInstalled || (isInstalled && !socketConnected)) &&
method !== RPC_METHODS.METAMASK_GETPROVIDERSTATE
) {
const params = args?.[0]?.params || [];

Check warning on line 197 in packages/sdk/src/provider/initializeMobileProvider.ts

View check run for this annotation

Codecov / codecov/patch

packages/sdk/src/provider/initializeMobileProvider.ts#L197

Added line #L197 was not covered by tests

if (
ALLOWED_CONNECT_METHODS.indexOf(method) !== -1 ||
checkInstallationOnAllCalls
Expand All @@ -217,8 +220,6 @@ const initializeMobileProvider = ({
method.toLowerCase() ===
RPC_METHODS.METAMASK_CONNECTSIGN.toLowerCase()
) {
const [temp] = args;
const { params } = temp;
const accounts = (await sdk.getProvider()?.request({
method: RPC_METHODS.ETH_REQUESTACCOUNTS,
params: [],
Expand All @@ -235,38 +236,23 @@ const initializeMobileProvider = ({
method.toLowerCase() ===
RPC_METHODS.METAMASK_CONNECTWITH.toLowerCase()
) {
const accounts = (await sdk.getProvider()?.request({
method: RPC_METHODS.ETH_REQUESTACCOUNTS,
params: [],
})) as string[];
if (!accounts.length) {
throw new Error(`SDK state invalid -- undefined accounts`);
}

const [initialMethod] = args;
console.log(`connectWith:: initialMethod`, initialMethod);
const { params } = initialMethod;
const [rpc] = params;
console.warn(`FIXME:: handle CONNECT_WITH`, rpc);

if (
rpc.method?.toLowerCase() ===
RPC_METHODS.PERSONAL_SIGN.toLowerCase()
) {
const connectedRpc = {
method: rpc.method,
params: [rpc.params[0], accounts[0]],
};
console.log(`connectWith:: connectedRpc`, connectedRpc);
return await sdk.getProvider()?.request(connectedRpc);
}
console.warn(`FIXME:: handle CONNECT_WITH`, rpc);
// Overwrite rpc method with correct account information
return await extensionConnectWithOverwrite({

Check warning on line 241 in packages/sdk/src/provider/initializeMobileProvider.ts

View check run for this annotation

Codecov / codecov/patch

packages/sdk/src/provider/initializeMobileProvider.ts#L241

Added line #L241 was not covered by tests
method: rpc.method,
sdk,
params: rpc.params,
});
}

logger(

Check warning on line 248 in packages/sdk/src/provider/initializeMobileProvider.ts

View check run for this annotation

Codecov / codecov/patch

packages/sdk/src/provider/initializeMobileProvider.ts#L248

Added line #L248 was not covered by tests
`[initializeMobileProvider: sendRequest()] sending '${method}' on active provider`,
params,
);
// Re-create the query on the active provider
return await sdk.getProvider()?.request({
method,
params: args,
params,
});
}

Expand Down Expand Up @@ -309,7 +295,7 @@ const initializeMobileProvider = ({
// Re-create the query on the active provider
return await sdk.getProvider()?.request({
method,
params: args,
params,
});
}
throw err;
Expand All @@ -327,12 +313,14 @@ const initializeMobileProvider = ({
// It means there was a switch of provider while waiting for initialization -- redirect to the extension.
logger(
`[initializeMobileProvider: sendRequest()] EXTENSION active - redirect request '${method}' to it`,
args,
params,
);

// redirect to extension
return await sdk.getProvider()?.request({
method,
params: args,
params,
});
}

Expand Down

0 comments on commit 3476c77

Please sign in to comment.