# How to Connect MetaMask for Identity in Internet Computer Applications?

**URL:** <https://forum.dfinity.org/t/how-to-connect-metamask-for-identity-in-internet-computer-applications/43920>\
**Category:** Developers\
**Created:** [April 16, 2025, 7:40am UTC](https://forum.dfinity.org/t/how-to-connect-metamask-for-identity-in-internet-computer-applications/43920 "2025-04-16T07:40:29Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![AliSci](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/alisci/32/33799_2.png) [@AliSci](https://forum.dfinity.org/u/AliSci)\
**Post date:** [April 16, 2025, 7:40am UTC](https://forum.dfinity.org/t/how-to-connect-metamask-for-identity-in-internet-computer-applications/43920/1 "2025-04-16T07:40:29Z")

</div>

I’m developing a dapp on the Internet Computer and want to implement MetaMask login functionality similar to OpenChat’s simple one-button approach. I need help with:

## Current Goal

I need to connect MetaMask and obtain an identity that can be used with the Agent:

```typescript
const agent = new HttpAgent({
    identity: fetchIdentity(MetaMaskToken),
    host,
});

```

**Where my backend can catch that in `caller()`**

## What I’ve Tried

- Looked at ic-swi example but found it overly complex, it requires user to preform two steps and I want them to do it in just one click
- Tried to navigate OpenChat’s codebase but it’s quite large and difficult to extract just the MetaMask integration part

## What I Need

- A simpler implementation with a single button for MetaMask connection
- The correct way to get the `identity` from MetaMask that works with HttpAgent
- Ensure that `caller()` returns the MetaMask ID when the user is authenticated
- Can I just use

```js
const newAccounts = await window.ethereum.request({
         method: 'eth_requestAccounts'
       });

```

?  
Has anyone implemented a clean solution for this or can point me to relevant code examples? Ideally looking for something more straightforward than the existing examples.

---

<div class="post-metadata">

**Author:** ![C-B-Elite](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/c-b-elite/32/34356_2.png) [@C-B-Elite](https://forum.dfinity.org/u/C-B-Elite)\
**Post date:** [April 17, 2025, 3:30am UTC](https://forum.dfinity.org/t/how-to-connect-metamask-for-identity-in-internet-computer-applications/43920/2 "2025-04-17T03:30:39Z")

</div>

It seems that the one most widely used in the community is the SIWE developed by Astrox.

I once developed an application that allowed users to log in using MetaMask. The flow was simple: the frontend would prompt MetaMask to sign a message (which could be customized), and after signing just once, users could log into the IC directly.

This mechanism uses a Delegation Identity flow similar to Internet Identity. It’s a bit complex to explain, but not too difficult to implement or use.

I didn’t package it as a public infrastructure library at the time, but I can show you how to implement the functionality you’re looking for—you’ll just need to adapt the code I provide. If you’re interested, I’d be happy to walk you through it.

---

<div class="post-metadata">

**Author:** ![C-B-Elite](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/c-b-elite/32/34356_2.png) [@C-B-Elite](https://forum.dfinity.org/u/C-B-Elite)\
**Post date:** [April 17, 2025, 3:39am UTC](https://forum.dfinity.org/t/how-to-connect-metamask-for-identity-in-internet-computer-applications/43920/3 "2025-04-17T03:39:35Z")

</div>

I think it’s time for me to reorganize this repository and create a simple, lightweight crate along with an npm package for the frontend.

---

<div class="post-metadata">

**Author:** ![AliSci](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/alisci/32/33799_2.png) [@AliSci](https://forum.dfinity.org/u/AliSci)\
**Post date:** [April 18, 2025, 2:13pm UTC](https://forum.dfinity.org/t/how-to-connect-metamask-for-identity-in-internet-computer-applications/43920/4 "2025-04-18T14:13:51Z")

</div>

I tried ic\_siws it does not work there are some bugs in it  
check this out : [Announcing ic-siwe: Use Ethereum wallets to login to IC - #37 by AliSci](https://forum.dfinity.org/t/announcing-ic-siwe-use-ethereum-wallets-to-login-to-ic/27450/37)

---

<div class="post-metadata">

**Author:** ![ohsalmeron](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/ohsalmeron/32/30099_2.png) [@ohsalmeron](https://forum.dfinity.org/u/ohsalmeron)\
**Post date:** [April 18, 2025, 6:38pm UTC](https://forum.dfinity.org/t/how-to-connect-metamask-for-identity-in-internet-computer-applications/43920/5 "2025-04-18T18:38:14Z")

</div>

Check this out

I have an auth.js/ts that handles the whole process

> <https://github.com/cosmicrafts/cosmicrafts-dao/blob/d76a464c3a8b67efaf3ac1a607249aedfabd2227/src/frontend/src/stores/auth.js>

with this you can add any wallet you want, the process is exactly the same

Sign in with the wallet → UniqueMessage → Create seed → Create keys out of seed → Create identity/agent ready to sign calls

It’s all one-click solution with seed recovery method integrated

---

<div class="post-metadata">

**Author:** ![AliSci](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/alisci/32/33799_2.png) [@AliSci](https://forum.dfinity.org/u/AliSci)\
**Post date:** [April 19, 2025, 6:43am UTC](https://forum.dfinity.org/t/how-to-connect-metamask-for-identity-in-internet-computer-applications/43920/6 "2025-04-19T06:43:58Z")

</div>

So, just to make sure I understand

```js
class MetaMaskService {
  async isMetaMaskInstalled() {
    const isInstalled = typeof window.ethereum !== 'undefined';
    return isInstalled;
  }

  async getEthereumAddress() {
    console.log('Getting Ethereum address...');
    if (!(await this.isMetaMaskInstalled())) {
      alert('MetaMask is not installed.');
      throw new Error('MetaMask is not installed');
    }

    let accounts = await window.ethereum.request({ method: 'eth_accounts' });

    // If accounts are empty, prompt user to unlock MetaMask
    if (accounts.length === 0) {
      accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });
    }

    if (accounts.length === 0) {
      alert('Metamask is locked.');
      throw new Error('Metamask is locked.');
    }

    console.log('Ethereum address:', accounts[0]);
    return accounts[0]; // Returns the first account
  }

  async signMessage(message) {
    console.log('Signing message...');
    if (!(await this.isMetaMaskInstalled())) {
      alert('MetaMask is not installed.');
      throw new Error('MetaMask is not installed');
    }

    const ethereumAddress = await this.getEthereumAddress();

    const signature = await window.ethereum.request({
      method: 'personal_sign',
      params: [message, ethereumAddress],
    });
    //console.log('Signature:', signature);
    return signature; // Returns the signature
  }
}

export default new MetaMaskService();

async loginWithMetaMask() {
      try {
        // Show loading state in the store
        this.authenticated = false;
        this.registered = false;
        this.player = null;

        // Unique message for signature to create deterministic seed
        const uniqueMessage = 'Sign this message to log in with your Ethereum wallet';
        
        console.log('Requesting MetaMask signature...');
        const signature = await MetaMaskService.signMessage(uniqueMessage);
        console.log('MetaMask Signature received');
        
        if (!signature) {
          throw new Error('Failed to sign with MetaMask.');
        }
        
        // Generate seed phrase from signature
        console.log('Generating seed phrase from signature...');
        const seedPhrase = await generateSeedPhrase(signature);
        
        // Wait for this to fully complete before continuing
        console.log('Initializing login flow with seed phrase...');
        await this.handleLoginFlow(seedPhrase, { source: 'metamask', retry: true });
        
        return { success: true };
      } catch (error) {
        console.error('MetaMask login error:', error);
        throw new Error(`MetaMask login failed: ${error.message}`);
      }
    }

```

- I just inject that in my code and that is it ?
- I think there should be providers to wrapp my app with it?  
`<ContextProviders ><Myapp/> <ContextProviders/>`
- What about `fetchIdentity(MetaMaskToken)`

```rs
const agent = new HttpAgent({
    identity: fetchIdentity(MetaMaskToken),
    host,
});

```

---

<div class="post-metadata">

**Author:** ![ohsalmeron](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/ohsalmeron/32/30099_2.png) [@ohsalmeron](https://forum.dfinity.org/u/ohsalmeron)\
**Post date:** [April 19, 2025, 12:27pm UTC](https://forum.dfinity.org/t/how-to-connect-metamask-for-identity-in-internet-computer-applications/43920/7 "2025-04-19T12:27:19Z")

</div>

Yes so the Wallet/Metamask service is just a helper to call the extension on the browser, and get the signature, and get the 0x address

The auth will handle the rest which is to create your ICP wallet/identity

Including seed phrase, private/public key, principal id, agent to sign calls and it even has utilities to get AccountIDs out of your principal.

if confused, copy paste the code to an LLM it’ll know what to do

---

<div class="post-metadata">

**Author:** ![AliSci](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/alisci/32/33799_2.png) [@AliSci](https://forum.dfinity.org/u/AliSci)\
**Post date:** [April 19, 2025, 2:35pm UTC](https://forum.dfinity.org/t/how-to-connect-metamask-for-identity-in-internet-computer-applications/43920/8 "2025-04-19T14:35:21Z")

</div>

I just tried it. I got

```jsx
import { AuthClient } from "@dfinity/auth-client";
const createAuthClient = await AuthClient.create();
const client = await createAuthClient();
let identity = await client?.getIdentity()
  console.log({identity})

```

it was working fine but with metamsk now just nothing

```auto
{
    "identity": {}
}

```

---

<div class="post-metadata">

**Author:** ![AliSci](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/alisci/32/33799_2.png) [@AliSci](https://forum.dfinity.org/u/AliSci)\
**Post date:** [May 5, 2025, 8:39am UTC](https://forum.dfinity.org/t/how-to-connect-metamask-for-identity-in-internet-computer-applications/43920/9 "2025-05-05T08:39:16Z")

</div>

i made mini version of it here

> **[ICP Ninja](https://icp.ninja/i?s=wZXVj)**
>
> ICP Ninja is a browser IDE for creating Internet Computer (ICP) smart contracts. Write and deploy entire applications directly onchain from the browser. Choose from a gallery of example projects to get started.

but How to get the identity in the backend

```js
let metaMaskId = ....
const agent = new HttpAgent({
    identity: metaMaskId,
    host,
  });

```

---

<div class="post-metadata">

**Author:** ![ohsalmeron](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/ohsalmeron/32/30099_2.png) [@ohsalmeron](https://forum.dfinity.org/u/ohsalmeron)\
**Post date:** [May 5, 2025, 2:17pm UTC](https://forum.dfinity.org/t/how-to-connect-metamask-for-identity-in-internet-computer-applications/43920/10 "2025-05-05T14:17:10Z")

</div>

the identity remains in the frontend so the user can manage it, what I’d do is encrypt it with an user password for extra security, but you can even add more 2FAs methods like passkeys or Google Auth

```auto
try {
        // Generate the identity from seed phrase and index
        const { identity: newIdentity } = deriveAddressFromSeedPhrase(
          this.seedPhrase, 
          addressIndex
        );
        
        // Update the global identity
        identity = newIdentity;
        this.currentAddressIndex = addressIndex;
        
        // Save state
        this.saveStateToLocalStorage();
        
        return true;
      } catch (error) {
        console.error('Error switching address:', error);
        return false;
      }
    }

```

so you just let the “handleLoginFlow” method to take care of everything else, I did that with chatGPT but Claude, DeepSeek and Gemini 2.5 should do it.

Just prompt to use the copy pasted code based on your requirements, but give it full context that is another project and you want only the part of the auth.js that handles the identities

---

<div class="post-metadata">

**Author:** ![AliSci](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/alisci/32/33799_2.png) [@AliSci](https://forum.dfinity.org/u/AliSci)\
**Post date:** [May 8, 2025, 8:38am UTC](https://forum.dfinity.org/t/how-to-connect-metamask-for-identity-in-internet-computer-applications/43920/11 "2025-05-08T08:38:25Z")

</div>

I am still tring @ohsalmeron @kristofer can u guys just build it here [ICP Ninja](https://icp.ninja/editor?s=wZXVj)  
maybe without wagmi ?

```tsx
// Import the backend actor
      import { canisterId, idlFactory } from 'declarations/backend';
      //TODO const metaMaskIdentity = ""??
      const agent = new HttpAgent({
          identity:metaMaskIdentity,
          host:"https://ic0.app",
        });

      const backend = return Actor.createActor<_SERVICE>(idlFactory, {
        agent,
        canisterId,
      });

```

---

<div class="post-metadata">

**Author:** ![ohsalmeron](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/ohsalmeron/32/30099_2.png) [@ohsalmeron](https://forum.dfinity.org/u/ohsalmeron)\
**Post date:** [May 8, 2025, 12:49pm UTC](https://forum.dfinity.org/t/how-to-connect-metamask-for-identity-in-internet-computer-applications/43920/12 "2025-05-08T12:49:29Z")

</div>

I wouldn’t use ICP Ninja for that, also a standalone index.html for a full dapp won’t get you far

How about you create an opensource Github repo for testing purposes, use a JS framework like react/vue/svelte and then you should be good make it work.

Also don’t hurt yourself writing code manually, AI is here to stay just learn the frameworks so you can make better decisions.

Cursor is now free for students and is very powerful or you can get a 15-day trial, Caffeine AI is on its way so you can get started and prepare for it.
