Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/connect-evm/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Remove `@metamask/chain-agnostic-permission` dependency. The two helpers used from it (`getEthAccounts`, `getPermittedEthChainIds`) and the `parseScopeString` utility are now implemented locally on top of `@metamask/utils` primitives. This drops the transitive `@metamask/controller-utils` / `lodash` / `bn.js` / `eth-ens-namehash` / `fast-deep-equal` / `@metamask/ethjs-unit` chain from the `connect-evm` bundle.

### Fixed

- Return method-specific values from intercepted EIP-1193 account requests: `eth_requestAccounts` now resolves to an accounts array, and `eth_coinbase` now resolves to the selected account instead of the full accounts array. [297](https://github.com/MetaMask/connect-monorepo/pull/297)

## [1.2.0]

### Added
Expand Down
113 changes: 113 additions & 0 deletions packages/connect-evm/src/connect.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -871,6 +871,119 @@ describe('MetamaskConnectEVM', () => {
});

describe('#requestInterceptor', () => {
it('returns an accounts array for eth_requestAccounts', async () => {
const mockCore = createMockCore();
mockCore.storage.adapter.get.mockResolvedValue(JSON.stringify('0x1'));
mockCore.connect.mockImplementation(async (): Promise<void> => {
const session: SessionData = {
sessionScopes: {
'eip155:1': {
methods: [],
notifications: [],
accounts: ['eip155:1:0x1234567890123456789012345678901234567890'],
},
},
};
mockCore.emit('wallet_sessionChanged', session);
});

const client = await MetamaskConnectEVM.create({ core: mockCore });

await expect(
client.getProvider().request({
method: 'eth_requestAccounts',
params: [],
}),
).resolves.toEqual(['0x1234567890123456789012345678901234567890']);
});

it('keeps wallet_requestPermissions returning the connect result', async () => {
const mockCore = createMockCore();
mockCore.storage.adapter.get.mockResolvedValue(JSON.stringify('0x1'));
mockCore.connect.mockImplementation(async (): Promise<void> => {
const session: SessionData = {
sessionScopes: {
'eip155:1': {
methods: [],
notifications: [],
accounts: ['eip155:1:0x1234567890123456789012345678901234567890'],
},
},
};
mockCore.emit('wallet_sessionChanged', session);
});

const client = await MetamaskConnectEVM.create({ core: mockCore });

await expect(
client.getProvider().request({
method: 'wallet_requestPermissions',
// eslint-disable-next-line @typescript-eslint/naming-convention
params: [{ eth_accounts: {} }],
}),
).resolves.toEqual({
accounts: ['0x1234567890123456789012345678901234567890'],
chainId: '0x1',
});
});

it('returns all accounts for eth_accounts', async () => {
const mockCore = createMockCore();
mockCore.storage.adapter.get.mockResolvedValue(JSON.stringify('0x1'));
const client = await MetamaskConnectEVM.create({ core: mockCore });

const connectPromise = new Promise<void>((resolve) => {
client.getProvider().once('connect', () => resolve());
});
mockCore.emit('wallet_sessionChanged', {
sessionScopes: {
'eip155:1': {
methods: [],
notifications: [],
accounts: [
'eip155:1:0x1111111111111111111111111111111111111111',
'eip155:1:0x2222222222222222222222222222222222222222',
],
},
},
});
await connectPromise;

await expect(
client.getProvider().request({ method: 'eth_accounts', params: [] }),
).resolves.toEqual([
'0x1111111111111111111111111111111111111111',
'0x2222222222222222222222222222222222222222',
]);
});

it('returns the selected account for eth_coinbase', async () => {
const mockCore = createMockCore();
mockCore.storage.adapter.get.mockResolvedValue(JSON.stringify('0x1'));
const client = await MetamaskConnectEVM.create({ core: mockCore });

const connectPromise = new Promise<void>((resolve) => {
client.getProvider().once('connect', () => resolve());
});
mockCore.emit('wallet_sessionChanged', {
sessionScopes: {
'eip155:1': {
methods: [],
notifications: [],
accounts: [
'eip155:1:0x1111111111111111111111111111111111111111',
'eip155:1:0x2222222222222222222222222222222222222222',
],
},
},
});
await connectPromise;

await expect(
client.getProvider().request({ method: 'eth_coinbase', params: [] }),
).resolves.toBe('0x1111111111111111111111111111111111111111');
});

it('wallet_requestPermissions passes forceRequest: true to core.connect', async () => {
const mockCore = createMockCore();
mockCore.storage.adapter.get.mockResolvedValue(JSON.stringify('0x1'));
Expand Down
6 changes: 6 additions & 0 deletions packages/connect-evm/src/connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,9 @@ export class MetamaskConnectEVM {
forceRequest: shouldForceConnectionRequest,
});
await this.#trackWalletActionSucceeded(method, scope, params);
if (request.method === 'eth_requestAccounts') {
return result.accounts;
}
return result;
} catch (error) {
await this.#trackWalletActionFailed(method, scope, params, error);
Expand All @@ -669,6 +672,9 @@ export class MetamaskConnectEVM {
}

if (isAccountsRequest(request)) {
if (request.method === 'eth_coinbase') {
return this.#provider.selectedAccount ?? null;
}
return this.#provider.accounts;
}

Expand Down
Loading