Get access to Alchemy for free here.
Introduction
Alchemy Web3 is a wrapper around Web3.js, providing enhanced API methods and other crucial benefits listed below. It is designed to require minimal configuration so you can start using it in your app right away.
⚠️ MAINTENANCE MODE ⚠️
As of July 2022, this repo is now in maintenance mode. The new Alchemy SDK based on Ethers.js is now available. It has feature parity with this library as well as better typing, more abstractions, and more documentation.
You can access the Alchemy SDK here:
Alchemy SDK QuickstartGoing 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.
Benefits:
- Effortless integration - Alchemy Web3 is an extension of Web3.js. If you're already using Web3, then you can start using Alchemy Web3 with a one-line change.
- Enhanced Alchemy APIs - The client exposes methods to call Alchemy's exclusive features.
- Automatic Retries - If Alchemy returns a 429 response (rate limited), automatically retry after a short delay. This behavior is configurable.
- Upgraded WebSockets - which don't miss events if the WebSocket needs to be reconnected.
- Seamless provider handling - Most requests will be sent through Alchemy, but requests involving signing and sending transactions are sent via a browser provider like Metamask or Trust Wallet if the user has it installed or via a custom provider specified in options.
Sturdier WebSockets
WebSocket connections are ephemeral by nature, which makes it necessary for clients to engineer non-trivial mechanisms around reconnects and backfills of missed events.
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 handles 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:
- Unlike standard Web3, you will not permanently miss events that arrive while the backing WebSocket is temporarily down. Instead, you will receive these events as soon as the connection is reopened. Note that if the connection is down for more than 120 blocks (approximately 20 minutes), you may still miss some events that were not part of the most recent 120 blocks.
- Compared to standard Web3, lowered rate of failure when sending requests over the WebSocket while the connection is down. Alchemy Web3 will attempt to send the requests once the connection is reopened. Note that it is still possible, with a lower likelihood, for outgoing requests to be lost, so you should still have error handling as with any network request.
Installation
With a package manager
Navigate to your project directory and run:
With Yarn:
yarn add @alch/alchemy-web3
With NPM:
npm install @alch/alchemy-web3
With a CDN in the browser
Add the following script tag to your webpage:
<script src="https://cdn.jsdelivr.net/npm/@alch/alchemy-web3@latest/dist/alchemyWeb3.min.js"></script>
When using this option, you can create Alchemy-Web3 instances using the global variable AlchemyWeb3.createAlchemyWeb3
.
Usage
Basic Usage
Create the client by importing the function createAlchemyWeb3
and then passing it your Alchemy app's URL and optionally a configuration object.
Using HTTPS:
const { createAlchemyWeb3 } = require("@alch/alchemy-web3");
// Using HTTPS
const web3 = createAlchemyWeb3("https://eth-mainnet.g.alchemy.com/<api-key>");
Using WebSockets:
const { createAlchemyWeb3 } = require("@alch/alchemy-web3");
// Using WebSockets
const web3 = createAlchemyWeb3(
"wss://eth-mainnet.ws.g.alchemy.com/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 => {
/* … */
});
web3.eth
.getMaxPriorityFeePerGas().then(console.log);
web3.eth
.getFeeHistory(4, "latest", [25, 50, 75]).then(console.log);
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 Metamask, you must call ethereum.enable()
. Here's an example:
if (window.ethereum) {
window.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 this will display a Metamask dialog to the user if they have not already seen it and accepted, so you might want to wait before enabling Metamask until the user is about to perform an action that 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.
Enhanced API Calls
Alchemy offers several enhanced API methods on top of the existing web3.js calls.
web3.alchemy.getTokenAllowance({contract, owner, spender})
Returns the amount which the spender is allowed to withdraw from the owner.
Parameters:
An object with the following fields:
contract
: The address of the token contract.owner
: The address of the token owner.spender
: The address of the token spender.
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:
address
: The address for which token balances will be checked.contractAddresses
: An array of contract addresses, or the string "DEFAULT_TOKENS" to fetch all tokens.
Returns:
An object with the following fields:
address
: The address for which token balances were checked.tokenBalances
: An array of token balance objects. Each object contains:contractAddress
: The address of the contract.tokenBalance
: The balance of the contract, as a string representing a base-10 number.error
: An error string. One of this ortokenBalance
will benull
.
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:
name
: The token's name.null
if not defined in the contract and not available from other sources.symbol
: The token's symbol.null
if not defined in the contract and not available from other sources.decimals
: The token's decimals.null
if not defined in the contract and not available from other sources.logo
: URL of the token's logo image.null
if not available.
web3.alchemy.getAssetTransfers({fromBlock, toBlock, fromAddress, toAddress, contractAddresses, excludeZeroValue, maxCount, category, pageKey})
Returns an array of asset transfers based on the specified parameters.
Parameters:
- Parameters:
- Object - An object with the following fields (required):
fromBlock
: in hex string or "latest". optional (default to latest)toBlock
: in hex string or "latest". optional (default to latest)fromAddress
: in hex string. optionaltoAddress
: in hex string. optional.contractAddresses
: list of hex strings. optional.category
: list of any combination ofexternal
,token
. optional, if blank, would include both.excludeZeroValue:
aBoolean
. optional (defaulttrue
)maxCount
: max number of results to return per call. optional (default1000)
pageKey
: for pagination. optional
- Object - An object with the following fields (required):
fromBlock
andtoBlock
are inclusive. Both default tolatest
if not specified.fromAddress
andtoAddress
will beAND
ed together when filtering. If left blank, will indicate a wildcard (any address).contractAddresses
only applies totoken
category transfers (eth log events). The list of addresses areOR
ed together. This filter will beAND
ed withfromAddress
andtoAddress
for eth log events. If empty, or unspecified, it will be taken as a wildcard (any contract addresses).category
:external
for primary level eth transfers,token
for contract event transfers.excludeZeroValue:
an optionalBoolean
to exclude asset transfers with a value field of zero (defaults totrue
)maxCount
: The maximum number of results to return per call. Default and max will be 1000.pageKey
: If left blank, will return the first 1000 ormaxCount
number of results. If more results are available, a uuid pageKey will be returned in the response. Pass that uuid intopageKey
to fetch the next 1000 or maxCount. See section on pagination.
EIP 1559
web3.eth.getFeeHistory(blockRange, startingBlock, percentiles[])
web3.eth.getFeeHistory(blockRange, startingBlock, percentiles[])
Fetches the fee history for the given block range as per the eth spec.
Parameters
blockRange
: The number of blocks for which to fetch historical fees. Can be an integer or a hex string.startingBlock
: The block to start the search. The result will look backwards from here. Can be a hex string or a predefined block string e.g. "latest".percentiles
: (Optional) An array of numbers that define which percentiles of reward values you want to see for each block.
Returns
An object with the following fields:
oldestBlock
: The oldest block in the range that the fee history is being returned for.baseFeePerGas
: An array of base fees for each block in the range that was looked up. These are the same values that would be returned on a block for theeth_getBlockByNumber
method.gasUsedRatio
: An array of the ratio of gas used to gas limit for each block.reward
: Only returned if a percentiles parameter was provided. Each block will have an array corresponding to the percentiles provided. Each element of the nested array will have the tip provided to miners for the percentile given. So if you provide [50, 90] as the percentiles then each block will have a 50th percentile reward and a 90th percentile reward.
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()
web3.eth.getMaxPriorityFeePerGas()
Returns a quick estimate for maxPriorityFeePerGas
in EIP 1559 transactions. Rather than using eth_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