npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

evm-provider-anukul

v6.0.4

Published

`evm-provider` implements a web3 provider which can interact with the [Reef chain EVM](https://github.com/reef-defi/reef-chain).

Downloads

246

Readme

@reef-chain/evm-provider

evm-provider implements a web3 provider which can interact with the Reef chain EVM.

If you only care about developing Solidity contracts on the Reef chain, @reef-chain/evm-provider is used in our Hardhat Reef environment. The environment simplifies and abstracts all the low-level intricacies, so you can only focus on the Solidity part. See hardhat-reef-examples repo for more examples.

If you need more control, then it can also be used as a Substrate provider to query or to interact with the Reef chain using the same calls as in the Polkadot.js.

Installation

Install dependencies with yarn see issue.

Yarn

yarn add @reef-chain/evm-provider

Getting started

To create a Provider instance, use the following code:

import {
  TestAccountSigningKey,
  Provider,
  Signer,
} from "@reef-chain/evm-provider";
import { WsProvider, Keyring } from "@polkadot/api";
import { createTestPairs } from "@polkadot/keyring/testingPairs";
import { KeyringPair } from "@polkadot/keyring/types";

const WS_URL = process.env.WS_URL || "ws://127.0.0.1:9944";
const seed = process.env.SEED;

const setup = async () => {
  const provider = new Provider({
    provider: new WsProvider(WS_URL),
  });

  await provider.api.isReady;

  let pair: KeyringPair;
  if (seed) {
    const keyring = new Keyring({ type: "sr25519" });
    pair = keyring.addFromUri(seed);
  } else {
    const testPairs = createTestPairs();
    pair = testPairs.alice;
  }

  const signingKey = new TestAccountSigningKey(provider.api.registry);
  signingKey.addKeyringPair(pair);

  const signer = new Signer(provider, pair.address, signingKey);

  // Claim default account
  if (!(await signer.isClaimed())) {
    console.log(
      "No claimed EVM account found -> claimed default EVM account: ",
      await signer.getAddress()
    );
    await signer.claimDefaultAccount();
  }

  return {
    signer,
    provider,
  };
};

export default setup;

with this object you can interact with the Substrate chain.

If you want to interact with injected sources (e.g. from Polkadot{.js}) you can do the following:

import { Provider, Signer, } from "@reef-chain/evm-provider";
import { WsProvider } from "@polkadot/api";
import { web3Accounts, web3Enable } from "@polkadot/extension-dapp";

const WS_URL = process.env.WS_URL || "ws://127.0.0.1:9944";
const seed = process.env.SEED;

const setup = async () => {
  
  // Return an array of all the injected sources
  // (this needs to be called first)
  const allInjected = await web3Enable('your dapp');

  const injected;
  if (allInjected[0] && allInjected[0].signer) {
    injected = allInjected[0].signer;
  }

  // Return an array of { address, meta: { name, source } }
  // (meta.source contains the name of the extension)
  const allAccounts = await web3Accounts();

  let account;
  if (allAccounts[0] && allAccounts[0].address) {
    account = allAccounts[0].address;
  }

  const provider = new Provider({
    provider: new WsProvider(WS_URL)
  });

  await provider.api.isReady;

  const signer = new Signer(provider, account, injected);

  // Claim default account
  if (!(await signer.isClaimed())) {
    console.log(
      "No claimed EVM account found -> claimed default EVM account: ",
      await signer.getAddress()
    );
    await signer.claimDefaultAccount();
  }

  return {
    signer,
    provider,
  };
};

export default setup;

EVM interaction

Most, but not all, of evm-provider API is compatible with ethers.js. If you are not familiar with ethers.js, you can start by looking at its documentation. See our Reefswap example on how it uses the above setup script to deploy and interact with the EVM.

Get EVM address

// ethers
let accounts = await this.provider.listAccounts();
let selectedAccount = accounts[0];

// evm-provider
let selectedAccount = await this.signer.queryEvmAddress();

Claim EVM address

If you would like to inject an evm address that you already own you can do so via the claimAccount extrinsic. The script below illustrates how this can be done.

import { Keyring, WsProvider } from '@polkadot/api';
import { ethers } from 'ethers';
import { createClaimEvmSignature } from './utils';
import { Provider } from '.';

const WS_URL = process.env.WS_URL || 'ws://127.0.0.1:9944';
// reef address - 5H728gLgx4yuCSVEwGCAfLo3RtzTau9F6cTNqNJtrqqjACWq
const reefPrivKeyRaw = process.env.REEF_PRIV_KEY || "0x0000000000000000000000000000000000000000000000000000000000000000";
const ethPrivKey = process.env.ETH_PRIV_KEY || "0x81376b9868b292a46a1c486d344e427a3088657fda629b5f4a647822d329cd6a";

const main = async (): Promise<void> =>  {
    const provider = new Provider({
        provider: new WsProvider(WS_URL)
    });
    await provider.api.isReady;

    const keyring = new Keyring({ type: 'sr25519' });
    const reefKey = keyring.addFromUri(reefPrivKeyRaw);
    const ethKey = new ethers.Wallet(ethPrivKey);

    const msg = createClaimEvmSignature(reefKey.address);
    let signature = await ethKey.signMessage(msg);

    await provider.api.tx.evmAccounts.claimAccount(
        ethKey.address,
        signature
    ).signAndSend(reefKey);

    process.exit();
};

main();

Build payload, sign and send transaction

This example illustrates how to build a payload to be signed with an EVM account. Once signed, the signature is added to the extrinsic and sent to the chain.


import { PopulatedTransaction } from "ethers";
import { ethers } from "ethers";
import { Provider } from '.';
import { buildPayload, sendSignedTransaction } from './utils';

const buildSignAndSend = async (provider: Provider, signerAddress: string): Promise<void> =>  {
    const contract = new ethers.Contract(
      flipperContractAddress,
      FlipperAbi,
      provider as any
    );

    const tx: PopulatedTransaction = await contract.populateTransaction.flip();

    const { payload, extrinsic } = await buildPayload(provider, signerAddress, tx);

    // (...) Add logic to send payload to signer and receive signature

    extrinsic.addSignature(signerAddress, signature, payload);

    const txResult = await sendSignedTransaction(
      provider,
      signerAddress,
      tx,
      payload,
      extrinsic,
      signature
    );
};

Provider

The Provider provides an API for interacting with nodes and is an instance of ethers.js AbstractProvider.

Signer

The Signer class can sign transactions and messages using a private key. When using the wallet for the first time, make sure to always claim the EVM account for the wallet you are using:

signer.claimDefaultAccount();

before performing any EVM calls otherwise it may lead to InsufficientBalance errors.

Gas limit and storage limit

In addition to the gas limit (processing), the Reef chain also charges a storage fee. When you interact with the EVM, Reef chain will estimate both fees and as such the fees will be invisible to the user. This should work in 99% of cases. It assumes you have at least 60 REEF tokens on the signing account. However, sometimes the heuristics (usually for more complex contracts) are wrong. In this case you can force the values of gasLimit and storageLimit by adding them to the options dictionary at the end of every call, for example:

await factory.deploy(<contract_args>, {
  gasLimit: 1000000,
  customData: { storageLimit: 1000000 }
});

If you require maximum flexibility evm-provider exports maximum gas and storage limit:

import { MAX_GAS_LIMIT, MAX_STORAGE_LIMIT } from "@reef-chain/evm-provider";

which default to U64MAX and U32MAX respectively.

Which API can I use to query by transaction hash?

There is no such API. Substrate does not expose a "query-by-tx-hash" RPC, nor are transactions indexed by hash on the Substrate node. The reason for this is that transaction hashes are non-unique across the chain, although they will generally be unique inside a block.

Please use GraphQL for this purpose.

How to query EVM events and logs?

See above.

Versions

  • versions 1.*.* work from Reef v8 chain onwards
  • versions 0.*.* work from Reef v0 to v7

Changelog