alchemyplatform / alchemy-sdk-js

The easiest way to connect your dApp to the blockchain.
https://www.alchemy.com/sdk
MIT License
392 stars 172 forks source link

Alchemy SDK for Javascript

The Alchemy SDK is the most comprehensive, stable, and powerful Javascript SDK available today to interact with the blockchain.

It supports the exact same syntax and functionality of the Ethers.js AlchemyProvider and WebSocketProvider, making it a 1:1 mapping for anyone using the Ethers.js Provider. However, it adds a significant amount of improved functionality on top of Ethers, such as easy access to Alchemy’s Enhanced and NFT APIs, robust WebSockets, and quality-of-life improvements such as automated retries.

The SDK leverages Alchemy's hardened node infrastructure, guaranteeing best-in-class node reliability, scalability, and data correctness, and is undergoing active development by Alchemy's engineers.

🙋‍♀️ FEATURE REQUESTS:

We'd love your thoughts on what would improve your web3 dev process the most! If you have 5 minutes, tell us what you want on our Feature Request feedback form, and we'd love to build it for you.

The SDK currently supports the following chains (chains with '(d)' after are deprecated):

You can find per-method documentation of the Alchemy SDK endpoints at the Alchemy Docs linked in the sidebar.

Getting started

npm install alchemy-sdk

After installing the app, you can then import and use the SDK:

import { Alchemy, Network } from 'alchemy-sdk';

// Optional config object, but defaults to the API key 'demo' and Network 'eth-mainnet'.
const settings = {
  apiKey: 'demo', // Replace with your Alchemy API key.
  network: Network.ETH_MAINNET // Replace with your network.
};

const alchemy = new Alchemy(settings);

ℹ️ Creating a unique Alchemy API Key

The public "demo" API key may be rate limited based on traffic. To create your own API key, sign up for an Alchemy account here and use the key created on your dashboard for the first app.

The Alchemy object returned by new Alchemy() provides access to the Alchemy API. An optional config object can be passed in when initializing to set your API key, change the network, or specify the max number of retries.

Using the Alchemy SDK

The Alchemy SDK currently supports the following namespaces:

If you are already using Ethers.js, you should be simply able to replace the Ethers.js Provider object with alchemy.core and it should work properly.

ℹ️ ENS Name Resolution

The Alchemy SDK now supports ENS names (e.g. vitalik.eth) for every parameter where you can pass in a Externally Owned Address, or user address (e.g. 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045).

import { Alchemy, AlchemySubscription } from 'alchemy-sdk';

// Using default settings - pass in a settings object to specify your API key and network
const alchemy = new Alchemy();

// Access standard Ethers.js JSON-RPC node request
alchemy.core.getBlockNumber().then(console.log);

// Access Alchemy Enhanced API requests
alchemy.core
  .getTokenBalances('0x3f5CE5FBFe3E9af3971dD833D26bA9b5C936f0bE')
  .then(console.log);

// Access the Alchemy NFT API
alchemy.nft.getNftsForOwner('vitalik.eth').then(console.log);

// Access WebSockets and Alchemy-specific WS methods
alchemy.ws.on(
  {
    method: AlchemySubscription.PENDING_TRANSACTIONS
  },
  res => console.log(res)
);

The Alchemy SDK also supports a number of Ethers.js objects that streamline the development process:

Alchemy Settings

An AlchemySettings object can be passed on instantiation to the Alchemy object, with the following optional parameters:

Alchemy Core

The core namespace contains all commonly-used Ethers.js Provider methods. If you are already using Ethers.js, you should be simply able to replace the Ethers.js Provider object with alchemy.core when accessing provider methods and it should just work.

It also includes the majority of Alchemy Enhanced APIs, including:

You will also find the following utility methods:

Accessing the full Ethers.js Provider

To keep the package clean, we don't support certain uncommonly-used Ethers.js Provider methods as top-level methods in the Alchemy core namespace - for example, provider.formatter. If you'd like to access these methods, simply use the alchemy.config.getProvider() function to configure the Ethers.js Provider AlchemyProvider and return it.

import { Alchemy } from 'alchemy-sdk';

const alchemy = new Alchemy();

async function runAlchemy() {
  const ethersProvider = await alchemy.config.getProvider();
  console.log(ethersProvider.formatter);
}
runAlchemy();

Alchemy WebSockets

In addition to the built-in Ethers.js listeners, the Alchemy SDK includes support for Alchemy's Subscription API. This allows you to subscribe to events and receive updates as they occur.

The alchemy.ws instance can be used like the standard Ethers.js WebSocketProvider to add listeners for Alchemy events:

import { Alchemy, AlchemySubscription } from 'alchemy-sdk';

const alchemy = new Alchemy();

// Listen to all new pending transactions.
alchemy.ws.on('block', res => console.log(res));

// Listen to only the next transaction on the USDC contract.
alchemy.ws.once(
  {
    method: AlchemySubscription.PENDING_TRANSACTIONS,
    toAddress: 'vitalik.eth'
  },
  res => console.log(res)
);

// Remove all listeners.
alchemy.ws.removeAllListeners();

The SDK 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. The Alchemy SDK automatically handles these failures with no configuration necessary. The main benefits are:

Alchemy Transact

The transact namespace contains methods used for simulating and sending transactions. The unique methods to the transact namespace are:

The transact namespace also aliases over several commonly used methods from the core namespace for convenience:

Alchemy NFT API

The SDK currently supports the following NFT API endpoints under the alchemy.nft namespace:

Pagination

The Alchemy NFT endpoints return 100 results per page. To get the next page, you can pass in the pageKey returned by the previous call. To simplify paginating through all results, the SDK provides the getNftsIterator() and getNftsForContractIterator() functions that automatically paginate through all NFTs and yields them via an AsyncIterable.

Here's an example of how to paginate through all the NFTs in Vitalik's ENS address:

import { Alchemy } from 'alchemy-sdk';

const alchemy = new Alchemy();

async function main() {
  const ownerAddress = 'vitalik.eth';
  for await (const nft of alchemy.nft.getNftsForOwnerIterator(ownerAddress)) {
    console.log('ownedNft:', nft);
  }
}

main();

SDK vs API Differences

The NFT API in the SDK standardizes response types to reduce developer friction, but note this results in some differences compared to the Alchemy REST endpoints:

Alchemy Notify

The Alchemy Notify API helps developers set up webhooks in their apps. The namespace provides methods to programmatically create, read, update, and delete your webhooks along with typings for the different webhooks. To learn more about Webhooks, please refer to the Alchemy documentation.

Methods on the NotifyNamespace can be accessed via alchemy.notify. To use the methods, you must include your team's auth token in the authToken field of AlchemySettings when instantiating the SDK. The auth token can be found on the Alchemy Dashboard in the Notify Tab.

Methods include:

Alchemy Debug

Methods on the DebugNamespace can be accessed via alchemy.debug. These methods are used for inspecting and debugging transactions.

Methods include:

Documentation

The SDK is documented via tsdoc comments in the source code. The generated types and documentation are included when using an IDE. To browse the documentation separately, you can view the generated API interfaces in etc/alchemy-sdk.api.md. You can view generated Markdown files for each endpoint in the docs-md directory, or as a webpage by opening docs/index.html in your browser.

Usage Examples

Below are a few usage examples.

ℹ️ More Examples

You can also go here: Examples Using the Alchemy SDK.

Getting the NFTs owned by an address

import { Alchemy, NftExcludeFilters } from 'alchemy-sdk';

const alchemy = new Alchemy();

// Get how many NFTs an address owns.
alchemy.nft.getNftsForOwner('vitalik.eth').then(nfts => {
  console.log(nfts.totalCount);
});

// Get all the image urls for all the NFTs an address owns.
async function main() {
  for await (const nft of alchemy.nft.getNftsForOwnerIterator('vitalik.eth')) {
    console.log(nft.media);
  }
}

main();

// Filter out spam NFTs.
alchemy.nft
  .getNftsForOwner('vitalik.eth', {
    excludeFilters: [NftExcludeFilters.SPAM]
  })
  .then(console.log);

Getting all the owners of the BAYC NFT

import { Alchemy } from 'alchemy-sdk';

const alchemy = new Alchemy();

// Bored Ape Yacht Club contract address.
const baycAddress = '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D';

async function main() {
  for await (const nft of alchemy.nft.getNftsForContractIterator(baycAddress, {
    // Omit the NFT metadata for smaller payloads.
    omitMetadata: true
  })) {
    await alchemy.nft
      .getOwnersForNft(nft.contract.address, nft.tokenId)
      .then(response =>
        console.log('owners:', response.owners, 'tokenId:', nft.tokenId)
      );
  }
}

main();

Get all outbound transfers for a provided address

import { Alchemy } from 'alchemy-sdk';

const alchemy = new Alchemy();

alchemy.core.getTokenBalances('vitalik.eth').then(console.log);

Questions and Feedback

If you have any questions, issues, or feedback, please file an issue on GitHub, or drop us a message on our Discord channel for the SDK.