Home

Awesome

Alchemy Web3

Web3 client extended with Alchemy and browser provider integration.

⚠️ MAINTENANCE MODE ⚠️

As of July 2022, this repo is now in maintenance mode. The new SDK based on ethers.js is now available on GitHub or NPM. It has feature parity with this library as well as better typing, more abstractions, and more documentation.

Going forward, updates to this library will be made on a best-effort basis. If you see a bug or have a feature request, please open an issue or pull request on the Github issues section.

Introduction

Alchemy Web3 provides website authors with a drop-in replacement for the web3.js Ethereum API client. It produces a client matching that of web3.js, but brings multiple advantages to make use of Alchemy API:

Alchemy Web3 is designed to require minimal configuration so you can start using it in your app right away.

Installation

With a package manager

With Yarn:

yarn add @alch/alchemy-web3

Or with NPM:

npm install @alch/alchemy-web3

With a CDN in the browser

Alternatively, add one of the following script tags to your page:

<!-- Minified -->
<script src="https://cdn.jsdelivr.net/npm/@alch/alchemy-web3@latest/dist/alchemyWeb3.min.js"></script>
<!-- Unminified -->
<script src="https://cdn.jsdelivr.net/npm/@alch/alchemy-web3@latest/dist/alchemyWeb3.js"></script>

When using this option, you can create Alchemy-Web3 instances using the global variable AlchemyWeb3.createAlchemyWeb3.

Usage

Basic Usage

You will need an Alchemy account to access the Alchemy API. If you don't have one yet, sign up here.

Create the client by importing the function createAlchemyWeb3 and then passing it your Alchemy app's URL and optionally a configuration object.

import { createAlchemyWeb3 } from "@alch/alchemy-web3";

// Using HTTPS
const web3 = createAlchemyWeb3(
  "https://eth-mainnet.alchemyapi.io/v2/<api-key>",
);

or

// Using WebSockets
const web3 = createAlchemyWeb3(
  "wss://eth-mainnet.ws.alchemyapi.io/ws/<api-key>",
);

You can use any of the methods described in the web3.js API and they will send requests to Alchemy:

// Many web3.js methods return promises.
web3.eth.getBlock("latest").then((block) => {
  /* … */
});

web3.eth
  .estimateGas({
    from: "0xge61df…",
    to: "0x087a5c…",
    data: "0xa9059c…",
    gasPrice: "0xa994f8…",
  })
  .then((gasAmount) => {
    /* … */
  });

With a Browser Provider

If the user has a provider in their browser available at window.ethereum, then any methods which involve user accounts or signing will automatically use it. This provider might be injected by Metamask, Trust Wallet or other browsers or browser extensions if the user has them installed. For example, the following will use a provider from the user's browser:

web3.eth.getAccounts().then((accounts) => {
  web3.eth.sendTransaction({
    from: accounts[0],
    to: "0x6A823E…",
    value: "1000000000000000000",
  });
});

Note on using Metamask

As just discussed, Metamask will automatically be used for accounts and signing if it is installed. However, for this to work you must first request permission from the user to access their accounts in Metamask. This is a security restriction required by Metamask: details can be found here.

To enable the use of Metamask, you must call ethereum.enable(). An example of doing so is as follows:

if (window.ethereum) {
  ethereum
    .enable()
    .then((accounts) => {
      // Metamask is ready to go!
    })
    .catch((reason) => {
      // Handle error. Likely the user rejected the login.
    });
} else {
  // The user doesn't have Metamask installed.
}

Note that doing so will display a Metamask dialog to the user if they have not already seen it and accepted, so you may choose to wait to enable Metamask until the user is about to perform an action which requires it. This is also why Alchemy Web3 will not automatically enable Metamask on page load.

With a custom provider

You may also choose to bring your own provider for writes rather than relying on one being present in the browser environment. To do so, use the writeProvider option when creating your client:

const web3 = createAlchemyWeb3(ALCHEMY_URL, { writeProvider: provider });

Your provider should expose at least one of sendAsync() or send(), as specified in EIP 1193.

You may swap out the custom provider at any time by calling the setWriteProvider() method:

web3.setWriteProvider(provider);

You may also disable the write provider entirely by passing a value of null.

Automatic Retries

If Alchemy Web3 encounters a rate limited response, it will automatically retry the request after a short delay. This behavior can be configured by passing the following options when creating your client. To disable retries, set maxRetries to 0.

maxRetries

The number of times the client will attempt to resend a rate limited request before giving up. Default: 3.

retryInterval

The minimum time waited between consecutive retries, in milliseconds. Default: 1000.

retryJitter

A random amount of time is added to the retry delay to help avoid additional rate errors caused by too many concurrent connections, chosen as a number of milliseconds between 0 and this value. Default: 250.

Sturdier WebSockets

Alchemy Web3 brings multiple improvements to ensure correct WebSocket behavior in cases of temporary network failure or dropped connections. As with any network connection, you should not assume that a WebSocket will remain open forever without interruption, but correctly handling dropped connections and reconnection by hand can be challenging to get right. Alchemy Web3 automatically adds handling for these failures with no configuration necessary.

If you use your WebSocket URL when initializing, then when you create subscriptions using web3.eth.subscribe(), Alchemy Web3 will bring the following advantages over standard Web3 subscriptions:

Alchemy's Transfers API

The produced client also grants easy access to Alchemy's transfer API.

web3.alchemy.getAssetTransfers({fromBlock, toBlock, fromAddress, toAddress, contractAddresses, excludeZeroValue, maxCount, category, pageKey})

Returns an array of asset transfers based on the specified parameters.

Parameters:

An object with the following fields:

Returns:

An object with the following fields:

Alchemy's Enhanced API

The produced client also grants easy access to Alchemy's enhanced API.

web3.alchemy.getTokenAllowance({contract, owner, spender})

Returns token balances for a specific address given a list of contracts.

Parameters:

An object with the following fields:

Returns:

The allowance amount, as a string representing a base-10 number.

web3.alchemy.getTokenBalances(address, contractAddresses)

Returns token balances for a specific address given a list of contracts.

Parameters:

  1. address: The address for which token balances will be checked.
  2. contractAddresses: An optional array of contract addresses. Not specifying this will return all token balances.

Returns:

An object with the following fields:

web3.alchemy.getTokenMetadata(address)

Returns metadata (name, symbol, decimals, logo) for a given token contract address.

Parameters:

address: The address of the token contract.

Returns:

An object with the following fields:

web3.alchemy.getNfts({owner, pageKey, contractAddresses})

Parameters:

An object with the following fields:

Returns:

When metadata is included, the returned object has the following fields:

If metadata is omitted, an object with the following fields is returned:

web3.alchemy.getNftMetadata({contractAddress, tokenId, tokenType})

Parameters:

An object with the following fields:

Returns:

An object with the following fields:

web3.alchemy.getTransactionReceipts({blockNumber | blockHash})

Fetches all transaction receipts for a block number or a block hash.

Parameters:

Note that either blockNumber or blockHash can be set.

Returns:

The returned object is a list of transaction receipts for each transaction in this block. See eth_getTransactionReceipt for the payload of an individual transaction receipt.

web3.eth.subscribe("alchemy_fullPendingTransactions")

Subscribes to pending transactions, similar to the standard Web3 call web3.eth.subscribe("pendingTransactions"), but differs in that it emits full transaction information rather than just transaction hashes.

Note that the argument passed to this function is permitted to be either of "alchemy_fullPendingTransactions" or "alchemy_newFullPendingTransactions", which have the same effect. The latter is the string used in raw eth_subscribe JSON-RPC calls, while the former is consistent with the existing Web3.js subscription APIs (for example, web3.eth.subscribe("pendingTransactions") corresponds to the raw JSON-RPC call of type newPendingTransactions). While this is unfortunately confusing, supporting both strings attempts to balance consistency and convenience.

web3.eth.subscribe("alchemy_filteredFullPendingTransactions", options)

Like an alchemy_fullPendingTransactions subscription, but also allows passing an options argument containing an address field to filter the returned transactions to those from or to the specified address. The options argument is as described in the documentation here.

Similar to the previous point, note that the argument passed to this function may be either of "alchemy_filteredFullPendingTransactions" or "alchemy_filteredNewPendingTransactions".

<br/>

Copyright © 2019 Alchemy Insights Inc.

EIP 1559

web3.eth.getFeeHistory(blockRange, startingBlock, percentiles[])

Fetches the fee history for the given block range as per the eth spec.

Parameters

Returns

An object with the following fields:

Example

Method call

web3.eth.getFeeHistory(4, "latest", [25, 50, 75]).then(console.log);

Logged response

{
  oldestBlock: 12930639,
  reward: [
    [ '0x649534e00', '0x66720b300', '0x826299e00' ],
    [ '0x649534e00', '0x684ee1800', '0x7ea8ed400' ],
    [ '0x5ea8dd480', '0x60db88400', '0x684ee1800' ],
    [ '0x59682f000', '0x5d21dba00', '0x5d21dba00' ]
  ],
  baseFeePerGas: [ '0x0', '0x0', '0x0', '0x0', '0x0' ],
  gasUsedRatio: [ 0.9992898398856537, 0.9999566454373825, 0.9999516, 0.9999378 ]
}

web3.eth.getMaxPriorityFeePerGas()

Returns a quick estimate for maxPriorityFeePerGas in EIP 1559 transactions. Rather than using feeHistory and making a calculation yourself you can just use this method to get a quick estimate. Note: this is a geth-only method, but Alchemy handles that for you behind the scenes.

Parameters

None!

Returns

A hex, which is the maxPriorityFeePerGas suggestion. You can plug this directly into your transaction field.

Example

Method call

web3.eth.getMaxPriorityFeePerGas().then(console.log);

Logged response

0x560de0700