How to Add Custom Rally Login into an Ethereum Wallet Modal
Tags: blockchain, javascript
Published: 2021-10-06 02:46:09

This article outlines how to add [Rally.io](https://rally.io/) login to Onboard.js, a modal integration that allows users to login into decentralized apps using various Ethereum wallets.

Since Rally is not an Ethereum Virtual Machine (EVM) compatible blockchain, developers must separate the Rally and Ethereum wallet authentications on their dapps. 

However, [Onboard.js](https://docs.blocknative.com/onboard) simplifies the UI and allows dapps to easily add new Ethereum wallets and custom logins as user login options. 

To learn more about the key differences between Rally and Ethereum, check out this article [here](https://dev.to/jkim_tran/how-is-rally-different-from-ethereum-mainnet-248a). 

## Getting Started

### Step 1: Set up Onboard.js (if you have not already)
You will need to add the Onboard.js as a package and initialize the library in your Javascript project.

You can follow the documentation to add Onboard.js to your project [here](https://docs.blocknative.com/onboard). 

As noted in the docs, to initialize the built-in wallet modules, you must pass an array of wallet initialization objects to the walletSelect.wallets parameter of the Onboard initialization object.

### Step 2: Create a Rally.io login module
Create a new Javascript module. In the module, you will need to add the following:

An constant variable that stores the Rally starlight logo SVG:

```
const rallySVG = `<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
.st1{clip-path:url(#SVGID_2_);}
</style>
<g>
<path class="st0" d="M57.52,63.66"/>
<path class="st0" d="M72.92,35.95c0.33,0,0.6,0.27,0.6,0.6c0,14.02,8.64,24.87,25.39,25.22c0.33,0,0.6,0.27,0.6,0.6
 s-0.27,0.6-0.6,0.6C82.15,63.3,73.51,74.15,73.51,88.17c0,0.33-0.27,0.6-0.6,0.6c-0.33,0-0.6-0.27-0.6-0.6
 c0-14.02-8.64-24.87-25.39-25.22c-0.33,0-0.6-0.27-0.6-0.6s0.27-0.6,0.6-0.6c16.75-0.34,25.39-11.19,25.39-25.22
 C72.32,36.22,72.59,35.95,72.92,35.95z"/>
<g>
 <g>
   <defs>
     <path id="SVGID_1_" d="M46.93,62.96c16.75,0.34,25.39,11.19,25.39,25.22c0,0.33-0.27,0.6-0.6,0.6H1.1c-0.33,0-0.6-0.27-0.6-0.6
       V11.83c0-0.33,0.27-0.6,0.6-0.6h45.78c13.96,0.29,25.44,11.29,25.44,25.32s-8.64,24.87-25.39,25.22c-0.33,0-0.6,0.27-0.6,0.6
       S46.6,62.96,46.93,62.96z"/>
   </defs>
   <clipPath id="SVGID_2_">
     <use xlink:href="#SVGID_1_"  style="overflow:visible;"/>
   </clipPath>
   <g class="st1">
     <g>
       <defs>
         <rect id="SVGID_3_" x="-4.5" y="6.23" width="81.82" height="87.54"/>
       </defs>
       <clipPath id="SVGID_4_">
         <use xlink:href="#SVGID_3_"  style="overflow:visible;"/>
       </clipPath>
       <g style="clip-path:url(#SVGID_4_);">
         
           <image style="overflow:visible;" width="172" height="184" xlink:href="data:image/jpeg;base64,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
Ox+w5PN+V1d2tz87sn//2Q==" transform="matrix(0.48 0 0 0.48 -4.8 5.76)">
         </image>
       </g>
     </g>
   </g>
 </g>
</g>
</g>
</svg>`
```

Create an export module that will direct the user to the callback that you stored the Rally.io login logic to. 

**Note**: You will still need to add backend logic that will handle the Rally.io login. To learn more about how to set up Rally.io login, review the docs [here](https://api-docs.rally.io/) or subscribe to my account for upcoming articles! 

```
export const customRallyLogin = {
  name: 'Rally', //display name of the wallet
  preferred: true, //lists Rally login as a top login option
  svg: rallySVG,
  wallet: async helpers => {
    window.location.href = 'yourcallback';
    await new Promise(resolve => setTimeout(resolve, 10000));
    return null;
  },
  desktop: true,
  mobile: true
}
```
### Step 3: Import the Rally Login module to Onboard.js
Import the Rally Login module into the Onboard initialization.

For example:

```
import { customRallyLogin } from "../../utils/logins/Rally";
```

Add the module name under the walletSelect.wallets parameter of the Onboard initialization object, alongside the other wallet integrations.

For example:

```
    { walletName: "metamask", preferred: true },
    { walletName: "torus", preferred: true },
    { walletName: "coinbase", preferred: true }, 
    customRallyLogin
```

### Step 4: End Result
Once you add the wallet model to an onClick method to a Login button, the Onboard.js module will popup and Rally is listed as a login option.

![Rally Login on Onboard.js module](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wxa7dj9z4syut8kg7yys.png)