Connect MetaMask via ethers.js

You can also connect MetaMask programmatically using ethers.

Sample Code

import { ethers } from 'ethers';

export const LUNTRA_NETWORK_PARAMS = {
  chainId: '0x34F820', // 3470144 in hexadecimal
  chainName: 'Luntra Network',
  rpcUrls: ['https://rpc.luntrainfrastructure.com/http'],
  nativeCurrency: {
    name: 'Ether',
    symbol: 'ETH',
    decimals: 18,
  },
  blockExplorerUrls: ['https://explorer.luntrainfrastructure.com/'],
};

export async function connectMetaMask() {
  if (typeof window.ethereum === 'undefined') {
    alert('MetaMask not installed!');
    return;
  }

  const provider = new ethers.providers.Web3Provider(window.ethereum);

  try {
    await window.ethereum.request({
      method: 'wallet_addEthereumChain',
      params: [LUNTRA_NETWORK_PARAMS],
    });

    await provider.send('eth_requestAccounts', []);
    const signer = provider.getSigner();
    const address = await signer.getAddress();

    console.log('Connected address:', address);
    return { provider, signer, address };
  } catch (err) {
    console.error('MetaMask connection failed:', err);
  }
}

Using ethers.js to interact with your smart contract

Sample code

Counter contract ABI:

// abi/counterAbi.ts
[
	{
		"anonymous": false,
		"inputs": [
			{
				"indexed": true,
				"internalType": "address",
				"name": "sender",
				"type": "address"
			},
			{
				"indexed": false,
				"internalType": "string",
				"name": "reason",
				"type": "string"
			}
		],
		"name": "UserRevert",
		"type": "event"
	},
	{
		"anonymous": false,
		"inputs": [
			{
				"indexed": true,
				"internalType": "address",
				"name": "sender",
				"type": "address"
			},
			{
				"indexed": false,
				"internalType": "uint256",
				"name": "newValue",
				"type": "uint256"
			}
		],
		"name": "ValueSet",
		"type": "event"
	},
	{
		"inputs": [],
		"name": "increment",
		"outputs": [],
		"stateMutability": "nonpayable",
		"type": "function"
	},
	{
		"inputs": [],
		"name": "number",
		"outputs": [
			{
				"internalType": "uint256",
				"name": "",
				"type": "uint256"
			}
		],
		"stateMutability": "view",
		"type": "function"
	},
	{
		"inputs": [
			{
				"internalType": "uint256",
				"name": "newNumber",
				"type": "uint256"
			}
		],
		"name": "setNumber",
		"outputs": [],
		"stateMutability": "nonpayable",
		"type": "function"
	},
	{
		"inputs": [
			{
				"internalType": "string",
				"name": "reason",
				"type": "string"
			}
		],
		"name": "userRevert",
		"outputs": [],
		"stateMutability": "nonpayable",
		"type": "function"
	}
]

Contract Interaction Example:

import { ethers } from 'ethers'
import { LUNTRA_NETWORK_PARAMS } from './config' // From separate file
import { counterAbi } from './abi/counterAbi'

// Replace with your deployed contract address
const contractAddress = '0xYourContractAddressHere'

async function connectAndInteract() {
  if (!window.ethereum) {
    alert('MetaMask is not installed!')
    return
  }

  // Request Luntra Network be added to MetaMask
  await window.ethereum.request({
    method: 'wallet_addEthereumChain',
    params: [
      {
        chainId: LUNTRA_NETWORK_PARAMS.chainHex,
        chainName: LUNTRA_NETWORK_PARAMS.chainName,
        rpcUrls: [LUNTRA_NETWORK_PARAMS.rpcUrl],
        nativeCurrency: LUNTRA_NETWORK_PARAMS.nativeCurrency,
        blockExplorerUrls: [LUNTRA_NETWORK_PARAMS.blockExplorer],
      },
    ],
  })

  const provider = new ethers.providers.Web3Provider(window.ethereum)
  await provider.send('eth_requestAccounts', [])
  const signer = provider.getSigner()
  const userAddress = await signer.getAddress()
  console.log('Connected as:', userAddress)

  // Contract instance
  const contract = new ethers.Contract(contractAddress, counterAbi, signer)

  // Send transaction to increment
  const tx = await contract.increment()
  console.log('Transaction sent:', tx.hash)

  const receipt = await tx.wait()
  console.log('Transaction mined in block:', receipt.blockNumber)
}

connectAndInteract().catch(console.error)

Last updated