Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: _handleChainChanged in MetaMaskInpageProvider to handle networkVersion #171

Merged
merged 3 commits into from
May 12, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
20 changes: 20 additions & 0 deletions src/BaseProvider.rpc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,4 +309,24 @@ describe('BaseProvider: RPC', () => {
});
});
});
describe('provider events', () => {
shanejonas marked this conversation as resolved.
Show resolved Hide resolved
// eslint-disable-next-line jest/no-test-callback
it('calls chainChanged when it chainId changes ', (done) => {
const mockStream = new MockDuplexStream();
const p = new BaseProvider(mockStream);
(p as any)._state.initialized = true;
p.on('chainChanged', (changed) => {
expect(changed).toBeDefined();
done();
});
mockStream.push({
name: 'metamask-provider',
data: {
jsonrpc: '2.0',
method: 'metamask_chainChanged',
params: { chainId: '0x1' },
},
});
});
});
});
25 changes: 7 additions & 18 deletions src/BaseProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -420,32 +420,21 @@ export default class BaseProvider extends SafeEventEmitter {
*/
protected _handleChainChanged({
chainId,
networkVersion,
}: { chainId?: string; networkVersion?: string } = {}) {
if (
!chainId ||
typeof chainId !== 'string' ||
!chainId.startsWith('0x') ||
!networkVersion ||
typeof networkVersion !== 'string'
) {
if (!chainId || typeof chainId !== 'string' || !chainId.startsWith('0x')) {
this._log.error(
'MetaMask: Received invalid network parameters. Please report this bug.',
{ chainId, networkVersion },
{ chainId },
);
return;
}

if (networkVersion === 'loading') {
this._handleDisconnect(true);
} else {
this._handleConnect(chainId);
this._handleConnect(chainId);

if (chainId !== this.chainId) {
this.chainId = chainId;
if (this._state.initialized) {
this.emit('chainChanged', this.chainId);
}
shanejonas marked this conversation as resolved.
Show resolved Hide resolved
if (chainId !== this.chainId) {
this.chainId = chainId;
if (this._state.initialized) {
this.emit('chainChanged', this.chainId);
}
}
}
Expand Down
38 changes: 38 additions & 0 deletions src/MetaMaskInpageProvider.rpc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -636,4 +636,42 @@ describe('MetaMaskInpageProvider: RPC', () => {
);
});
});
describe('provider events', () => {
shanejonas marked this conversation as resolved.
Show resolved Hide resolved
// eslint-disable-next-line jest/no-test-callback
it('calls chainChanged when it chainId changes ', (done) => {
const mockStream = new MockDuplexStream();
const p = new MetaMaskInpageProvider(mockStream);
rekmarks marked this conversation as resolved.
Show resolved Hide resolved
(p as any)._state.initialized = true;
p.on('chainChanged', (changed) => {
expect(changed).toBe('0x1');
done();
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should avoid disabling jest/no-test-callback by removing the callback and wrapping these lines in a Promise and awaiting it at the end of the test. Similarly below.

mockStream.push({
name: 'metamask-provider',
data: {
jsonrpc: '2.0',
method: 'metamask_chainChanged',
params: { chainId: '0x1', networkVersion: '0x1' },
},
});
});
// eslint-disable-next-line jest/no-test-callback
it('calls networkChanged when it networkVersion changes ', (done) => {
const mockStream = new MockDuplexStream();
const p = new MetaMaskInpageProvider(mockStream);
(p as any)._state.initialized = true;
p.on('networkChanged', (changed) => {
expect(changed).toBe('0x1');
done();
});
mockStream.push({
name: 'metamask-provider',
data: {
jsonrpc: '2.0',
method: 'metamask_chainChanged',
params: { chainId: '0x1', networkVersion: '0x1' },
},
});
});
});
});
50 changes: 50 additions & 0 deletions src/MetaMaskInpageProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -395,4 +395,54 @@ export default class MetaMaskInpageProvider extends BaseProvider {
},
);
}

/**
* Upon receipt of a new chainId and networkVersion, emits corresponding
* events and sets relevant public state.
* Does nothing if neither the chainId nor the networkVersion are different
* from existing values.
*
* @emits MetamaskInpageProvider#chainChanged
shanejonas marked this conversation as resolved.
Show resolved Hide resolved
* @param networkInfo - An object with network info.
* @param networkInfo.chainId - The latest chain ID.
* @param networkInfo.networkVersion - The latest network ID.
*/
protected _handleChainChanged({
chainId,
networkVersion,
}: { chainId?: string; networkVersion?: string } = {}) {
if (
!chainId ||
typeof chainId !== 'string' ||
!chainId.startsWith('0x') ||
!networkVersion ||
typeof networkVersion !== 'string'
) {
this._log.error(
'MetaMask: Received invalid network parameters. Please report this bug.',
{ chainId, networkVersion },
);
return;
}

if (networkVersion === 'loading') {
this._handleDisconnect(true);
} else {
this._handleConnect(chainId);

if (chainId !== this.chainId) {
this.chainId = chainId;
if (this._state.initialized) {
this.emit('chainChanged', this.chainId);
}
}

if (networkVersion !== this.networkVersion) {
this.networkVersion = networkVersion;
if (this._state.initialized) {
this.emit('networkChanged', this.networkVersion);
}
}
shanejonas marked this conversation as resolved.
Show resolved Hide resolved
}
}
}