Skip to content
This repository has been archived by the owner on Feb 21, 2024. It is now read-only.

Expose purser-metamask account change hook method #207

Merged
merged 7 commits into from
Mar 4, 2019
Merged
Show file tree
Hide file tree
Changes from all 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
29 changes: 28 additions & 1 deletion docs/_Modules_purser-metamask.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,36 @@ This method returns a `Promise` which, after resolving, it will `return` only re

**Usage examples:**

Open the metamask wallet:
Detect if Metamask is available:
```js
import { detect as isMetamaskAvailable } from '@colony/purser-metamask';

await isMetamaskAvailable(); // true
```

### `accountChangeHook`

```js
await accountChangeHook(callback: Function);
```

This is a utility method to allow end users to hook into Metamask's State Event Observer, and execute a callback when that changes. _(Eg: When an account is changed in the Metamask UI)_

This method takes a callback as an argument, which will be added to the state events array. When the state changes, all the callbacks added to that array are called in order.

When this is is called, it will receive a `state` Object as an only argument, Object which contains the new updated state.

This utility method is useful to act on account changes from within a dApp. _(Eg: To logout a user)_

**Usage examples:**

Hook into the state change events with a simple callback:
```js
import { accountChangeHook } from '@colony/purser-metamask';

const walletChangedCallback = ({ selectedAddress }) => {
console.log(`You changed your wallet. The new address is: ${selectedAddress}`);
};

await accountChangeHook(walletChangedCallback);
```
43 changes: 41 additions & 2 deletions modules/node_modules/@colony/purser-metamask/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions modules/node_modules/@colony/purser-metamask/messages.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

65 changes: 65 additions & 0 deletions modules/tests/purser-metamask/accountChangeHook.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import metamaskWallet from '@colony/purser-metamask';
import {
detect as detectHelper,
setStateEventObserver,
} from '@colony/purser-metamask/helpers';

jest.dontMock('@colony/purser-metamask');

/*
* @TODO Fix manual mocks
* This is needed since Jest won't see our manual mocks (because of our custom monorepo structure)
* and will replace them with automatic ones
*/
jest.mock('@colony/purser-metamask/helpers', () =>
require('@mocks/purser-metamask/helpers'),
);

/*
* Mock the global injected inpage provider
*/
global.web3 = {
currentProvider: {
publicConfigStore: {
_events: {
update: [],
},
},
},
};

const mockedCallback = jest.fn(state => state);

describe('Metamask` Wallet Module', () => {
describe('`accountChangeHook()` static method', () => {
test('Calls the correct helper method', async () => {
await metamaskWallet.accountChangeHook();
/*
* Call the helper method
*/
expect(setStateEventObserver).toHaveBeenCalled();
});
test('Detects if Metamask is available', async () => {
await metamaskWallet.accountChangeHook();
/*
* Calls the `detect()` helper
*/
expect(detectHelper).toHaveBeenCalled();
});
test('Adds a callback to the state observer', async () => {
await metamaskWallet.accountChangeHook(mockedCallback);
expect(
/* eslint-disable-next-line no-underscore-dangle */
global.web3.currentProvider.publicConfigStore._events.update,
).toContain(mockedCallback);
});
test('Catches if something goes wrong', async () => {
/*
* We're re-mocking the helpers just for this test so we can simulate
* an error along the way
*/
setStateEventObserver.mockRejectedValueOnce(new Error());
expect(metamaskWallet.accountChangeHook()).rejects.toThrow();
});
});
});