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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@jmezo/multicall

v0.12.0

Published

A blockchain state management library for dapps.

Downloads

3

Readme

Multicall.js

npm version

Multicall.js is a lightweight JavaScript library for interacting with the multicall smart contract.

Multicall allows multiple smart contract constant function calls to be grouped into a single call and the results aggregated into a single result. This reduces the number of separate JSON RPC requests that need to be sent over the network if using a remote node like Infura, and provides the guarantee that all values returned are from the same block. The latest block number is also returned along with the aggregated results.

Summary

  • Get the return value(s) of multiple smart contract function calls in a single call
  • Guarantee that all values are from the same block
  • Use watchers to poll for multiple blockchain state variables/functions
  • Get updates when a watcher detects state has changed
  • Results from out of sync nodes are automatically ignored
  • Get new block updates

Installation

yarn add @makerdao/multicall

Usage

import { createWatcher } from '@makerdao/multicall';

// Contract addresses used in this example
const MKR_TOKEN = '0xaaf64bfcc32d0f15873a02163e7e500671a4ffcd';
const MKR_WHALE = '0xdb33dfd3d61308c33c63209845dad3e6bfb2c674';
const MKR_FISH = '0x2dfcedcb401557354d0cf174876ab17bfd6f4efd';

// Preset can be 'mainnet', 'kovan', 'rinkeby', 'goerli' or 'xdai'
const config = { preset: 'kovan' };

// Create watcher
const watcher = createWatcher(
  [
    {
      target: MKR_TOKEN,
      call: ['balanceOf(address)(uint256)', MKR_WHALE],
      returns: [['BALANCE_OF_MKR_WHALE', val => val / 10 ** 18]]
    }
  ],
  config
);

// Subscribe to state updates
watcher.subscribe(update => {
console.log(`Update: ${update.type} = ${update.value}`);
});

// Subscribe to batched state updates
watcher.batch().subscribe(updates => {
  // Handle batched updates here
  // Updates are returned as { type, value } objects, e.g:
  // { type: 'BALANCE_OF_MKR_WHALE', value: 70000 }
});

// Subscribe to new block number updates
watcher.onNewBlock(blockNumber => {
  console.log('New block:', blockNumber);
});

// Start the watcher polling
watcher.start();
// The JSON RPC URL and multicall contract address can also be specified in the config:
const config = {
  rpcUrl: 'https://kovan.infura.io',
  multicallAddress: '0xc49ab4d7de648a97592ed3d18720e00356b4a806'
};
// Update the watcher calls using tap()
const fetchWaiter = watcher.tap(calls => [
  // Pass back existing calls...
  ...calls,
  // ...plus new calls
  {
    target: MKR_TOKEN,
    call: ['balanceOf(address)(uint256)', MKR_FISH],
    returns: [['BALANCE_OF_MKR_FISH', val => val / 10 ** 18]]
  }
]);
// This promise resolves when the first fetch completes
fetchWaiter.then(() => {
  console.log('Initial fetch completed');
});
// Recreate the watcher with new calls and config (allowing the network to be changed)
const config = { preset: 'mainnet' };
watcher.recreate(
  [
    {
      target: MKR_TOKEN,
      call: ['balanceOf(address)(uint256)', MKR_WHALE],
      returns: [['BALANCE_OF_MKR_WHALE', val => val / 10 ** 18]]
    }
  ],
  config
);

Helper Functions

Special variables and functions (e.g. addr.balance, block.blockhash, block.timestamp) can be accessed by calling their corresponding helper function. To call these helper functions simply omit the target property (and it will default to multicall's contract address).

const watcher = createWatcher(
  [
    {
      call: [
        'getEthBalance(address)(uint256)', 
        '0x72776bb917751225d24c07d0663b3780b2ada67c'
      ],
      returns: [['ETH_BALANCE', val => val / 10 ** 18]]
    },
    {
      call: ['getBlockHash(uint256)(bytes32)', 11482494],
      returns: [['SPECIFIC_BLOCK_HASH_0xFF4DB']]
    },
    {
      call: ['getLastBlockHash()(bytes32)'],
      returns: [['LAST_BLOCK_HASH']]
    },
    {
      call: ['getCurrentBlockTimestamp()(uint256)'],
      returns: [['CURRENT_BLOCK_TIMESTAMP']]
    },
    {
      call: ['getCurrentBlockDifficulty()(uint256)'],
      returns: [['CURRENT_BLOCK_DIFFICULTY']]
    },
    {
      call: ['getCurrentBlockGasLimit()(uint256)'],
      returns: [['CURRENT_BLOCK_GASLIMIT']]
    },
    {
      call: ['getCurrentBlockCoinbase()(address)'],
      returns: [['CURRENT_BLOCK_COINBASE']]
    }
  ],
  { preset: 'kovan' }
);

Examples

Check out this CodePen example for a working front-end example.

To run the example in the project, first clone this repo:

git clone https://github.com/makerdao/multicall.js

Then install the dependencies:

yarn

Finally run the example script (examples/es-example.js):

yarn example

Test

To run tests use:

yarn test