Skip to main content

Connect your Starknet account to MetaMask

To connect your dapp to the Starknet network in MetaMask, you can use the get-starknet library. This library simplifies the process of connecting to the Starknet Snap, allowing you to interact with users' Starknet accounts in MetaMask. get-starknet also enables dapps to interact with other wallets in the Starknet ecosystem.

Prerequisites

Connect using get-starknet

1. Add get-starknet to your project

Add the get-starknet version 3.3.0 library and the version 6.11.0 of the starknet.js library to your project's dependencies:

yarn add get-starknet@3.3.0 starknet@6.11.0

2. Connect to the Snap

Create a new file named WalletConnectButton.js in your project's src/components folder. Create this folder if it doesn't exist. Add the following code to the file:.

import React, { useState } from 'react';
import { connect, disconnect } from 'get-starknet';
import { encode } from "starknet";
function WalletConnectButton() {
const [walletAddress, setWalletAddress] = useState("");
const [walletName, setWalletName] = useState("");
const [wallet, setWallet] = useState("");
const handleDisconnect = async () => {
await disconnect({clearLastWallet: true});
setWallet("");
setWalletAddress("");
setWalletName("")
}
const handleConnect = async () => {
try{
const getWallet = await connect({ modalMode: "alwaysAsk", modalTheme: "light" });
await getWallet?.enable({ starknetVersion: "v5" });
setWallet(getWallet);
const addr = encode.addHexPrefix(encode.removeHexPrefix(getWallet?.selectedAddress ?? "0x").padStart(64, "0"));
setWalletAddress(addr);
setWalletName(getWallet?.name || "")
}
catch(e){
// handle user rejection to install metamask / snaps here.
console.log(e)
}
};
return (
<div>
{!walletAddress && (
<button onClick={handleConnect}>
Connect Wallet
</button>
)}
{walletAddress && (
<div>
<button onClick={handleDisconnect}>
Disconnect Wallet
</button>
<div>
<p>Wallet Name: {walletName}</p>
<p>Wallet Address: {walletAddress}</p>
</div>
</div>
)}
</div>
);
}
export default WalletConnectButton;

This code handles the connection to Starknet Snap using the get-starknet library and includes a button for users to initiate the wallet connection.

note

To connect to Starknet, the dapp user must ensure the Starknet Snap is added to MetaMask.

3. Start the dapp

Start the dapp, which allow users to click Connect Wallet and interact with the Starknet network using MetaMask:

yarn start

Connect using wallet_invokeSnap

1. Connect to the Snap

Alternatively, you can manage the Snap invocation manually. Use the wallet_invokeSnap method to directly interact with the Starknet Snap. This method does not requires additional dependencies.

note

To connect to Starknet, the dapp user must ensure the Starknet Snap is added to MetaMask.

In the src/utils/snapHelper.js file add the connect function and the callSnap helper function. This file handles the interactions with the Starknet Snap.

src/utils/snapHelper.js
const snapId = 'npm:starknet-snap';

export async function connect() {
await ethereum.request({
method: 'wallet_requestSnaps',
params: {
[snapId]: {},
},
});
}

export async function callSnap(method, params) {
try {
const response = await ethereum.request({
method: 'wallet_invokeSnap',
params: {
snapId,
request: {
method,
params,
},
},
});
console.log(`${method} response:`, response);
return response;
} catch (err) {
console.error(`${method} error:`, err);
alert(`${method} error: ${err.message || err}`);
throw err;
}
}

2. Call a specific Snap method

To call a specific Snap method, for example createAccount use the following:

const deploy = false; // Set to true to deploy the actual account
const addressIndex = 0; // Specify which address to derive
const chainId = "0x534e5f5345504f4c4941"; // Specify which chain to use (Sepolia testnet)
// For mainnet, use: "0x534e5f4d41494e"

const accountInfo = await callSnap('starkNet_createAccount', { addressIndex, deploy, chainId });

Example in HTML and JavaScript (Vanilla JS)

<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Connect Starknet Snap</title>
</head>
<body>
<button id="connectButton">Connect Starknet Wallet</button>
<p id="accountInfo"></p>
<script>
async function connect(snapId) {
await ethereum.request({
method: 'wallet_requestSnaps',
params: {
[snapId]: {},
},
});
}
async function callSnap(snapId, method, params) {
try {
const response = await ethereum.request({
method: 'wallet_invokeSnap',
params: {
snapId,
request: {
method,
params,
},
},
});
return response;
} catch (err) {
console.error(`${method} problem happened:`, err);
alert(`${method} problem happened: ${err.message || err}`);
}
}
document.getElementById('connectButton').addEventListener('click', async () => {
try {
const snapId = 'npm:@consensys/starknet-snap'; // Snap ID
await connect(snapId);
const deploy = false; // whether to deploy the actual account
const addressIndex = 0; // which address to derive
const chainId = "0x534e5f5345504f4c4941"; // which chain to use mainnet id "0x534e5f4d41494e", sepolia id "0x534e5f5345504f4c4941"
const account = await callSnap(snapId, 'starkNet_createAccount', { addressIndex, deploy, chainId });
console.log(account)
document.getElementById('accountInfo').innerText = `Connected Starknet Account: ${account.address}`;
} catch (error) {
console.error('Error connecting to Starknet Snap:', error);
}
});
</script>
</body>
</html>

Example in a React component

import React, { useState } from 'react';
const ConnectWallet = () => {
const [accountInfo, setAccountInfo] = useState('');
const connect = async (snapId) => {
try {
await window.ethereum.request({
method: 'wallet_requestSnaps',
params: {
[snapId]: {},
},
});
} catch (err) {
console.error('Snap connection error:', err);
alert(`Error connecting to Snap: ${err.message || err}`);
}
};
const callSnap = async (snapId, method, params) => {
try {
const response = await window.ethereum.request({
method: 'wallet_invokeSnap',
params: {
snapId,
request: {
method,
params,
},
},
});
return response;
} catch (err) {
console.error(`${method} problem happened:`, err);
alert(`${method} problem happened: ${err.message || err}`);
}
};
const handleConnectClick = async () => {
try {
const snapId = 'npm:@consensys/starknet-snap'; // Snap ID
await connect(snapId);
const deploy = false; // whether to deploy the actual account
const addressIndex = 0; // which address to derive
const chainId = '0x534e5f5345504f4c4941'; // chain (sepolia)
const account = await callSnap(snapId, 'starkNet_createAccount', { addressIndex, deploy, chainId });
setAccountInfo(`Connected Starknet Account: ${account.address}`);
} catch (error) {
console.error('Error connecting to Starknet Snap:', error);
}
};
return (
<div>
<button onClick={handleConnectClick}>Connect Starknet Wallet</button>
<p>{accountInfo}</p>
</div>
);
};
export default ConnectWallet;