forked from MetaMask/metamask-docs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
improve onboarding docs and add examples (MetaMask#117)
* improve onboarding docs and add examples
- Loading branch information
1 parent
afb6414
commit 20ae87f
Showing
1 changed file
with
164 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,171 @@ | ||
# Onboarding Library | ||
As an Ethereum enabled site developer, sending users offsite to install MetaMask presents challenges. Most notably, you must inform the user to return to your site and refresh their browser after the installation. Your site will detect the user's newly installed MetaMask extension only after that refresh. We at MetaMask care deeply about user experience, and we knew that this workflow needed to be improved. | ||
|
||
MetaMask now allows sites to register as onboarding the user, so that the user is redirected back to the initiating site after onboarding. This is accomplished through the use of the [metamask-onboarding library](https://github.com/MetaMask/metamask-onboarding). | ||
MetaMask now provides a [metamask-onboarding library](https://github.com/MetaMask/metamask-onboarding) designed to improve and simplify the onboarding experience. The new library exposes an API to initiate the onboarding process. In the process, it registers your site as the origin of the onboarding request. MetaMask will check for this origin after the user completes the onboarding flow. If it finds an origin, the final confirmation button of the MetaMask onboarding flow will indicate that the user will be redirected back to your site. | ||
|
||
At the end of onboarding, the text of the button will show the origin of the site the user is about to be redirected to. This is intended to help prevent phishing attempts, as it highlights that a redirect is taking place to an untrusted third party. | ||
## Getting Started | ||
1. Install @metamask/onboarding using npm or yarn. | ||
2. Import the Onboarding Library or include it in your page. | ||
|
||
```javascript | ||
// As an ES6 module | ||
import MetaMaskOnboarding from '@metamask/onboarding'; | ||
// Or as an ES5 module | ||
const MetamaskOnboarding = require('@metamask/onboarding'); | ||
``` | ||
|
||
If you'd prefer you can instead include the prebuilt ES5 bundle that ships with the library: | ||
```html | ||
<script type="text/javascript" src="./metamask-onboarding.bundle.js"></script> | ||
``` | ||
|
||
3. Create a new instance of the Onboarding library | ||
|
||
```javascript | ||
const onboarding = new MetaMaskOnboarding(); | ||
``` | ||
|
||
4. Start the onboarding process in response to a user event (e.g. a button click). | ||
|
||
```javascript | ||
onboarding.startOnboarding(); | ||
``` | ||
|
||
## Examples | ||
### Basic Usage | ||
```javascript | ||
const onboarding = new MetamaskOnboarding(); | ||
onboarding.startOnboarding(); | ||
``` | ||
|
||
### Using React | ||
```jsx | ||
import MetaMaskOnboarding from '@metamask/onboarding'; | ||
import React from 'react'; | ||
|
||
const ONBOARD_TEXT = 'Click here to install MetaMask!'; | ||
const CONNECT_TEXT = 'Connect'; | ||
const CONNECTED_TEXT = 'Connected'; | ||
|
||
export function OnboardingButton() { | ||
const [buttonText, setButtonText] = React.useState(ONBOARD_TEXT); | ||
const [isDisabled, setDisabled] = React.useState(false); | ||
const [accounts, setAccounts] = React.useState([]); | ||
const onboarding = React.useRef(); | ||
|
||
React.useEffect(() => { | ||
if (!onboarding.current) { | ||
onboarding.current = new MetaMaskOnboarding(); | ||
} | ||
}, []) | ||
|
||
React.useEffect(() => { | ||
if (MetaMaskOnboarding.isMetaMaskInstalled()) { | ||
if (accounts.length > 0) { | ||
setButtonText(CONNECTED_TEXT); | ||
setDisabled(true); | ||
onboarding.current.stopOnboarding(); | ||
} else { | ||
setButtonText(CONNECT_TEXT); | ||
setDisabled(false); | ||
} | ||
} | ||
}, [accounts]); | ||
|
||
React.useEffect(() => { | ||
function handleNewAccounts(newAccounts) { | ||
setAccounts(newAccounts); | ||
} | ||
if (MetaMaskOnboarding.isMetaMaskInstalled()) { | ||
window.ethereum.request({ method: 'eth_requestAccounts' }) | ||
.then(handleNewAccounts); | ||
window.ethereum.on('accountsChanged', handleNewAccounts) | ||
return () => { | ||
window.ethereum.off('accountsChanged', handleNewAccounts) | ||
} | ||
} | ||
}, []); | ||
|
||
const onClick = () => { | ||
if (MetaMaskOnboarding.isMetaMaskInstalled()) { | ||
window.ethereum.request({ method: 'eth_requestAccounts' }) | ||
.then(newAccounts => setAccounts(newAccounts)); | ||
} else { | ||
onboarding.current.startOnboarding(); | ||
} | ||
} | ||
return ( | ||
<button disabled={isDisabled} onClick={onClick}>{buttonText}</button> | ||
) | ||
} | ||
``` | ||
|
||
### Using TypeScript | ||
We ship our TypeScript types with `@metamask/onboarding`. Modifying the above example to get type safety when using the onboarding library is simple: | ||
|
||
```jsx | ||
-const onboarding = React.useRef(); | ||
+const onboarding = React.useRef<MetaMaskOnboarding>(); | ||
``` | ||
|
||
Doing this step will give you editor auto-completion for the methods exposed by the library, and helpful documentation. | ||
|
||
![Editor Highlighting](https://user-images.githubusercontent.com/4448075/85584481-ccc7ec00-b604-11ea-9b74-49c76ee0bf22.png) | ||
|
||
|
||
### Using Vanilla Javascript + HTML | ||
```html | ||
<html> | ||
<head> | ||
<meta charset="UTF-8"> | ||
</head> | ||
<body> | ||
<h1>Sample Dapp</h1> | ||
<button id='onboard'>Loading...</button> | ||
<script type="text/javascript" src="./metamask-onboarding.bundle.js"></script> | ||
<script type="text/javascript"> | ||
window.addEventListener('DOMContentLoaded', () => { | ||
const onboarding = new MetamaskOnboarding() | ||
const onboardButton = document.getElementById('onboard') | ||
let accounts | ||
const updateButton = () => { | ||
if (!MetamaskOnboarding.isMetaMaskInstalled()) { | ||
onboardButton.innerText = 'Click here to install MetaMask!' | ||
onboardButton.onclick = () => { | ||
onboardButton.innerText = 'Onboarding in progress' | ||
onboardButton.disabled = true | ||
onboarding.startOnboarding() | ||
} | ||
} else if (accounts && accounts.length > 0) { | ||
onboardButton.innerText = 'Connected' | ||
onboardButton.disabled = true | ||
onboarding.stopOnboarding() | ||
} else { | ||
onboardButton.innerText = 'Connect' | ||
onboardButton.onclick = async () => { | ||
await window.ethereum.request({ | ||
method: 'eth_requestAccounts' | ||
}) | ||
} | ||
} | ||
} | ||
updateButton() | ||
if (MetamaskOnboarding.isMetaMaskInstalled()) { | ||
window.ethereum.on('accountsChanged', (newAccounts) => { | ||
accounts = newAccounts | ||
updateButton() | ||
}) | ||
} | ||
}) | ||
</script> | ||
</body> | ||
</html> | ||
``` | ||
|
||
|
||
## Onboarding Diagram | ||
Here is a diagram of the interactions between the onboarding library, the forwarder, and the extension: | ||
|
||
![Onboarding Library Diagram](https://user-images.githubusercontent.com/2459287/67541693-439c9600-f6c0-11e9-93f8-112a8941384a.png) |