GithubHelp home page GithubHelp logo

alchemyplatform / alchemy-sdk-js Goto Github PK

View Code? Open in Web Editor NEW
380.0 28.0 164.0 7.15 MB

The easiest way to connect your dApp to the blockchain.

Home Page: https://www.alchemy.com/sdk

License: MIT License

JavaScript 0.63% TypeScript 99.36% Shell 0.01%

alchemy-sdk-js's Introduction

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:

  • Ethereum: Mainnet, Goerli, Sepolia
  • Polygon: Mainnet, Mumbai, Amoy
  • Optimism: Mainnet, Goerli, Kovan, Sepolia
  • Arbitrum: Mainnet, Goerli, Rinkeby, Sepolia
  • Astar: Mainnet
  • PolygonZKEVM: Mainnet, Testnet
  • Base: Mainnet, Goerli, Sepolia
  • Zksync: Mainnet, Sepolia

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:

  • core: All commonly-used Ethers.js Provider methods and Alchemy Enhanced API methods
  • nft: All Alchemy NFT API methods
  • ws: All WebSockets methods
  • transact: All Alchemy Transaction API methods
  • notify: CRUD endpoints for modifying Alchemy Notify Webhooks
  • debug: Methods to inspect and replay transactions and blocks

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:

  • Utils: Equivalent to ethers.utils, this provides a number of common Ethers.js utility methods for developers.
    • Interface: Found in Utils.Interface, this class abstracts the encoding and decoding required to interact with contracts on the Ethereum network.
  • Contract: An abstraction for smart contract code deployed to the blockchain.
  • ContractFactory: Allows developers to build a Contract object.
  • Wallet: An implementation of Signer that can sign transactions and messages using a private key as a standard Externally Owned Account.

Alchemy Settings

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

  • apiKey: API key that can be found in the Alchemy dashboard. Defaults to demo: a rate-limited public key.
  • network: Name of the network. Defaults to Network.ETH_MAINNET
  • maxRetries: The maximum number of retries to attempt if a request fails. Defaults to 5.
  • url: Optional URL endpoint to use for all requests. Setting this field will override the URL generated by the network andapiKey fields.
  • authToken: Alchemy auth token required to use the Notify API. This token can be found in the Alchemy Dashboard on the Notify tab.
  • batchRequests: Optional setting that automatically batches and sends json-rpc requests for higher throughput and reduced network IO. Defaults to false.
  • requestTimeout: Optional setting that sets the timeout for requests in milliseconds for the NFT and Notify namespaces. Defaults to no timeout.

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:

  • getTokenMetadata(): Get the metadata for a token contract address.
  • getTokenBalances(): Gets the token balances for an owner given a list of contracts.
  • getAssetTransfers(): Get transactions for specific addresses.
  • getTransactionReceipts(): Gets all transaction receipts for a given block.

You will also find the following utility methods:

  • findContractDeployer(): Find the contract deployer and block number for a given contract address.
  • getTokensForOwner(): Get all token balances and metadata for a given owner address

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:

  • Resilient event delivery: Unlike standard Web3.js or Ethers.js, you will not permanently miss events which 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.
  • Lowered rate of failure: Compared to standard Web3.js or Ethers.js, there are fewer failures when sending requests over the WebSocket while the connection is down. The Alchemy SDK 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.

Alchemy Transact

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

  • sendPrivateTransaction(): Send a private transaction through Flashbots.
  • cancelPrivateTransaction(): Cancel a private transaction sent with Flashbots.
  • simulateAssetChanges(): Simulate a transaction and get a list of asset changes.
  • simulateExecution(): Simulate a transaction and get a full list of internal transactions, logs, ABI decoded results and more.
  • simulateAssetChangesBundle(): Simulate a list of transactions in sequence and get a list of asset changes.
  • simulateExecutionBundle(): Simulate a list of transactions in sequence and get a full list of internal transactions, logs, ABI decoded results and more.

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

  • getTransaction(): Returns the transaction for the given transaction hash.
  • sendTransaction(): Sends a standard transaction to the network to be mined.
  • waitForTransaction(): Waits for a transaction to be mined and returns the transaction receipt.

Alchemy NFT API

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

  • getNftMetadata(): Get the NFT metadata for an NFT contract address and tokenId.
  • getNftMetadataBatch(): Get the NFT metadata for multiple NFT contract addresses/token id pairs.
  • getContractMetadata(): Get the metadata associated with an NFT contract
  • getContractMetadataBatch(): Get the metadata associated with multiple NFT contracts in a single request.
  • getContractsForOwner(): Get all NFT contracts that the provided owner address owns.
  • getNftsForOwner(): Get NFTs for an owner address.
  • getNftsForOwnerIterator(): Get NFTs for an owner address as an async iterator (handles paging automatically).
  • getNftsForContract(): Get all NFTs for a contract address.
  • getNftsForContractIterator(): Get all NFTs for a contract address as an async iterator (handles paging automatically).
  • getOwnersForNft(): Get all the owners for a given NFT contract address and a particular token ID.
  • getOwnersForContract(): Get all the owners for a given NFT contract address.
  • getMintedNfts(): Get all the NFTs minted by the owner address.
  • getTransfersForOwner(): Get all the NFT transfers for a given owner address.
  • getTransfersForContract(): Get all the NFT transfers for a given NFT contract address.
  • verifyNftOwnership(): Check whether the provided owner address owns the provided NFT contract addresses.
  • isSpamContract(): Check whether the given NFT contract address is a spam contract as defined by Alchemy (see the NFT API FAQ)
  • getSpamContracts(): Returns a list of all spam contracts marked by Alchemy.
  • reportSpam(): Report feedback that a given NFT contract address is a spam contract as defined by Alchemy.
  • isAirdropNft(): Check whether the given NFT token is marked as an airdrop or not. Airdrops are defined as NFTs that were minted to a user address in a transaction sent by a different address.
  • refreshNftMetadata(): Refresh the cached NFT metadata for a contract address and a single tokenId.
  • refreshContract(): Enqueues the specified contract address to have all token ids' metadata refreshed.
  • getFloorPrice(): Return the floor prices of a NFT contract by marketplace.
  • computeRarity(): Get the rarity of each attribute of an NFT.
  • getNftSales(): Returns NFT sales that have happened through on-chain marketplaces.
  • summarizeNftAttributes(): Get the summary of attribute prevalence for all NFTs in a contract.
  • searchContractMetadata(): Search for a keyword across metadata of all ERC-721 and ERC-1155 smart contracts.

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:

  • Methods referencing Collection have been renamed to use the name Contract for greater accuracy: e.g. getNftsForContract.
  • Some methods have different naming that the REST API counterparts in order to provide a consistent API interface ( e.g. getNftsForOwner() is alchemy_getNfts, getOwnersForNft() is alchemy_getOwnersForToken).
  • SDK standardizes to omitMetadata parameter (vs. withMetadata).
  • Standardization to pageKey parameter for pagination (vs. nextToken/startToken)
  • Empty TokenUri fields are omitted.
  • Token ID is always normalized to an integer string on BaseNft and Nft.
  • Some fields omitted in the REST response are included in the SDK response in order to return an Nft object.
  • Some fields in the SDK's Nft object are named differently than the REST response.

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:

  • getAllWebhooks(): Get all webhooks on your team.
  • getAddresses(): Get all addresses tracked for the provided Address Activity Webhook.
  • getNftFilters(): Get all NFT filters tracked for the provided NFT Activity Webhook.
  • createWebhook(): Create a new webhook.
  • updateWebhook(): Update an existing webhook's active status or tracked addresses and NFT filters.
  • deleteWebhook(): Delete the provided webhook.

Alchemy Debug

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

Methods include:

  • traceCall(): Run an eth_call with the context of the provided block execution using the final state of the parent block as the base.
  • traceTransaction(): Run the transaction in the exact same manner as it was executed on the network. It will replay any transaction that may have been executed prior to this one before it and will then attempt to execute the transaction that corresponds to the given hash.
  • traceBlock(): Replay a block that has already been mined.

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.

alchemy-sdk-js's People

Contributors

59023g avatar abbaskt avatar ahan-alchemy avatar alex-miao avatar andrewkw1122 avatar avasisht23 avatar ayang-rkjs avatar bmoyroud avatar cocojr avatar dependabot[bot] avatar deric-alchemy avatar dphilipson avatar florrdv avatar j05u3 avatar joshzhang5 avatar kunal365roy avatar leonacostaok avatar mokok123 avatar mpsq avatar nirmit1509 avatar oceja avatar omahs avatar rambhask avatar rob-alchemy avatar sahilaujla avatar stoyand avatar thebrianchen avatar xeno097 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

alchemy-sdk-js's Issues

SDK core method call() does not support EIP-1898

Environment

  • Browser version: N/A (Node.js 16.x)
  • Alchemy SDK version: 2.2.1

Problem description

The SDK Core endpoint call does not support the syntax {"blockHash": "0x<some-hash>"} as second parameter though the docs explicitely mention it:

NOTE: the parameter is an object instead of a string and should be specified as: {"blockHash": "0x"}

cf. https://docs.alchemy.com/reference/sdk-call

How to reproduce:

const { Alchemy, Network } = require('alchemy-sdk');
const settings = {
  apiKey: "demo",
  network: Network.MATIC_MAINNET,
};

const alchemy = new Alchemy(settings);

const result = await alchemy.core.call({
    to: '0x02D158f550dd434526E0BC4a65F7DD50DDB9afEE',
    from: '0x9dA2192C820C5cC37d26A3F97d7BcF1Bc04232A3',
    data: '0x406f7f6f000000000000000000000000000000000000000000000000000000001460883c0000000000000000000000000000000000000000000000000000000003154b3a00000000000000000000000000000000000000000056da9d67d20d77090000000000000000000000000000000000000000000000000000000000000064920c48000000000000000000000000d01587ecd64504851e181b36153ef4d93c2bf93900000000000000000000000000000000000000001d471783ac9f1aea98bda2a6',
  }, { blockHash: '0xf1ade8878a02fa378129cb9444bb409c11e5f89b94444b5785b370a810268ee6' });

The following error is thrown:

Error: invalid blockTag
    at Formatter.blockTag (/Users/egoubely/projects/poc-alchemy/node_modules/@ethersproject/providers/lib/formatter.js:221:15)
    at AlchemyProvider.<anonymous> (/Users/egoubely/projects/poc-alchemy/node_modules/@ethersproject/providers/lib/base-provider.js:2252:66)
    at step (/Users/egoubely/projects/poc-alchemy/node_modules/@ethersproject/providers/lib/base-provider.js:48:23)
    at Object.next (/Users/egoubely/projects/poc-alchemy/node_modules/@ethersproject/providers/lib/base-provider.js:29:53)
    at fulfilled (/Users/egoubely/projects/poc-alchemy/node_modules/@ethersproject/providers/lib/base-provider.js:20:58)

Note: it works if you Formatter.blockTag function from @ethersproject/providers to accept this format. It seems the fix has to be made on their side.

WebSocketNamespace constructor error

[REQUIRED] Environment

  • Browser version:
  • Alchemy SDK version: v2.2.3

[REQUIRED] Describe the problem

WebSocketNamespace constructor failed to save config

How to reproduce:

create an instance of Alchemy and then try to listen to some alchemy event

Relevant code or sample repro:

Contract info not saturated for CryptoKitties

Environment

Node.js with Alchemy SDK 2.2.4

Problem

Calling getNftMetadata() on a Cryptokitty (0x06012c8cf97BEaD5deAe237070F9587f8E7A266d) returns no contract in the contract information. Example:

const { Alchemy } = require('alchemy-sdk');
const alchemy = new Alchemy({
  /* YOUR API KEY AND STUFF */
});
alchemy.nft.getNftMetadata(
  '0x06012c8cf97BEaD5deAe237070F9587f8E7A266d',
  '633961',
).then(response => {
  console.log(response);
}).catch(err => {
});

Result:

{
...<snip>...
  contract: {
    address: '0x06012c8cf97bead5deae237070f9587f8e7a266d',
    name: '',
    symbol: '',
    totalSupply: '',
    tokenType: 'ERC721'
  },
...<snip>...
}

Etherscan seems to show the name correctly.

FR: Add support for batched requests

Implement JsonRpcBatchProvider into the existing provider to facilitate making batch requests. This will unblock adding syntactic sugar on top of existing methods to make it easier to combine responses from different endpoints into a single one.

getNftsForOwner discrepencies between docs, actual results, and typings

[REQUIRED] Environment

  • Browser version: N/A (Node)
  • Alchemy SDK version: 2.2.3

[REQUIRED] Describe the problem

The docs for getNft (renamed getNftsForOwner) show that, when metadata is enabled, the response should contain an object with keys ownedNfts (this is correct), which is an array of objects with properties like metadata and media.

When running the examples in the docs this is indeed the result that is returned.

However, when running the sdk (2.2.3), the returned result has the following format:

{
      contract: [Object],
      tokenId: '9089',
      tokenType: 'ERC721',
      title: '',
      description: '',
      timeLastUpdated: '2022-11-22T18:34:44.342Z',
      metadataError: 'Malformed token uri, do not retry',
      rawMetadata: [Object],
      tokenUri: [Object],
      media: [],
      spamInfo: undefined,
      balance: 1
},

As you can see, there's no metadata key at all. However there is an undocumented rawMetadata key.
This property contains { metadata: [], attributes: [] }, which is incorrect, because there's no metadata property in the typings for rawMetadata:

export interface NftMetadata extends Record<string, any> {
    /** Name of the NFT asset. */
    name?: string;
    /** A human-readable description of the NFT asset. */
    description?: string;
    /** URL to the NFT asset image. */
    image?: string;
    /**
     * The image URL that appears along the top of the NFT asset page. This tends
     * to be the highest resolution image.
     */
    external_url?: string;
    /** Background color of the NFT item. Usually defined as a 6 character hex string. */
    background_color?: string;
    /** The traits, attributes, and characteristics for the NFT asset. */
    attributes?: Array<Record<string, any>>;
}

Long story short: none of these 3 things actually line up properly which makes using the API incredibly difficult.

How to reproduce:

Implement the alchemy-sdk in a Node environment, and do a query on Goerli for an owner.
The response is not the same as described in the docs and it certainly isn't the same as the result in the docs tool .

Relevant code or sample repro:

https://stackblitz.com/edit/github-1wqbue-s658mx?file=example.js

Just run npm run example and you'll see my test wallet being used to retrieve a bunch of NFT's (most are "empty").
As you can see, none of them return metadata, all of them return the undocumented rawMetadata, some of them return populated media (this seems to be the most "reliable" property to check.

getContractMetadata API vs SDK

[REQUIRED] Environment

  • Browser version: Chrome 106
  • Alchemy SDK version: 2.2.0

[REQUIRED] Describe the problem

The getContractMetadata API returns useful openSea data that the SDK does not currently include.

getNftMetadata triggers NUMERIC_FAULT

[REQUIRED] Environment

  • Browser version: N/A (NodeJS 16.18.0)
  • Alchemy SDK version: ^2.0.0

[REQUIRED] Describe the problem

There seems to be an error when the library attempts to construct a BigNumer in getNftMetadata.

2022-10-18T11:38:48.370800+00:00 app[worker.1]: /app/node_modules/alchemy-sdk/node_modules/@ethersproject/logger/lib/index.js:233
2022-10-18T11:38:48.370829+00:00 app[worker.1]: var error = new Error(message);
2022-10-18T11:38:48.370830+00:00 app[worker.1]: ^
2022-10-18T11:38:48.370830+00:00 app[worker.1]:
2022-10-18T11:38:48.370833+00:00 app[worker.1]: Error: overflow [ See: https://links.ethers.org/v5-errors-NUMERIC_FAULT-overflow ] (fault="overflow", operation="BigNumber.from", value=3.824409351190545e+75, code=NUMERIC_FAULT, version=bignumber/5.6.2)
2022-10-18T11:38:48.370833+00:00 app[worker.1]: at Logger.makeError (/app/node_modules/alchemy-sdk/node_modules/@ethersproject/logger/lib/index.js:233:21)
2022-10-18T11:38:48.370834+00:00 app[worker.1]: at Logger.throwError (/app/node_modules/alchemy-sdk/node_modules/@ethersproject/logger/lib/index.js:242:20)
2022-10-18T11:38:48.370834+00:00 app[worker.1]: at throwFault (/app/node_modules/alchemy-sdk/node_modules/@ethersproject/bignumber/lib/bignumber.js:303:19)
2022-10-18T11:38:48.370835+00:00 app[worker.1]: at Function.BigNumber.from (/app/node_modules/alchemy-sdk/node_modules/@ethersproject/bignumber/lib/bignumber.js:206:17)
2022-10-18T11:38:48.370850+00:00 app[worker.1]: at NftNamespace.<anonymous> (/app/node_modules/alchemy-sdk/dist/cjs/index-04a23af4.js:611:46)
2022-10-18T11:38:48.370850+00:00 app[worker.1]: at Generator.next (<anonymous>)
2022-10-18T11:38:48.370851+00:00 app[worker.1]: at /app/node_modules/alchemy-sdk/dist/cjs/index-04a23af4.js:108:71
2022-10-18T11:38:48.370851+00:00 app[worker.1]: at new Promise (<anonymous>)
2022-10-18T11:38:48.370852+00:00 app[worker.1]: at __awaiter (/app/node_modules/alchemy-sdk/dist/cjs/index-04a23af4.js:104:12)
2022-10-18T11:38:48.370852+00:00 app[worker.1]: at NftNamespace.getNftMetadata (/app/node_modules/alchemy-sdk/dist/cjs/index-04a23af4.js:608:16) {
2022-10-18T11:38:48.370852+00:00 app[worker.1]: reason: 'overflow',
2022-10-18T11:38:48.370853+00:00 app[worker.1]: code: 'NUMERIC_FAULT',
2022-10-18T11:38:48.370853+00:00 app[worker.1]: fault: 'overflow',
2022-10-18T11:38:48.370854+00:00 app[worker.1]: operation: 'BigNumber.from',
2022-10-18T11:38:48.370854+00:00 app[worker.1]: value: 3.824409351190545e+75
2022-10-18T11:38:48.370854+00:00 app[worker.1]: }

How to reproduce:

It happened whilst tracking sales for the ENS asset.

Relevant code or sample repro:

https://github.com/KodexLabs/ethereum-nft-sales-bot

FR: getSingleOwnedNft

Is your feature request related to a problem? Please describe.
There are a few instances in which fetching a single OwnedNft would be immensely helpful
Navigating directly to a "nft" page.
Showcasing how many Nfts you have so you know how much you can put on sale.
These are just a few instances in which this feature would be helpful.

Describe the solution you'd like
Either a new endpoint like getNftForOwner(address, tokenId, contractAddress) that will return a single OwnedNft. Or reuse current getNftsForOwner to have a { tokenIds?: string[] } filter option.

Describe alternatives you've considered
The alternative I have right now it to use getNftMetadata or go thru all pages of getNftsForOwner and find the item I need.
Since I need to display the balance of a given Nft.

Additional context
Ditto

OpenSea metadata not always returning from get*Metadata()

Environment

Node.js with alchemy-sdk 2.2.4

Describe the problem

getNFTMetadata and getContractMetadata both return an openSea payload... but only for some NFTs. It's unclear when it's supposed to appear and when it's not.

For example, I would very much expect that any collections under the OpenSea Shared Storefront contract (0x495f947276749ce646f68ac8c248420045cb7b5e) would return OpenSea metadata! But they don't seem to.

How to reproduce:

Using example above, I'm grabbing the metadata for Skateboarding: Culture in Motion # 47:

const { Alchemy } = require('alchemy-sdk');
const alchemy = new Alchemy({ /* YOUR API KEY AND STUFF */ });
alchemy.nft.getNftMetadata(
  '0x495f947276749Ce646f68AC8c248420045cb7b5e',
  '103337611933110337448161440806560268112476320183319594419260887108754088132609',
).then(response => {
   console.log(response);
}).catch(err => {
});

but the response has no openSea object on it!

FR: Support multiple `excludeFilters` in `getNftsForOwner()`

I'm not sure of the conditions required to detect an airdrop, but using the 2.1.1 SDK with the NftExcludeFilters.AIRDROPS exclude filter doesn't seem to filter out airdropped NFTs.

Using this code:

alchemy.nft.getNftsForOwner(address, {
   excludeFilters: [NftExcludeFilters.SPAM, NftExcludeFilters.AIRDROPS],
});

I am still seeing airdropped NFTs in the returned list.

Axios request incorrectly sets Accept-Encoding header when browser is detected

[REQUIRED] Environment

  • Browser version: Chrome Version 107.0.5304.87
  • Alchemy SDK version: 2.2.0

[REQUIRED] Describe the problem

When alchemy.nft.getNftsForOwnerIterator(...) is called, the request fails with Refused to set unsafe header "Accept-Encoding".

How to reproduce:

Call any function that uses sendAxiosRequest.

Relevant code or sample repro:

This commit flips the boolean logic of whether to include this header in requests. I don't even think reproducing this is worth your time, you can just look at the change and see that it's incorrect.

summarizeNftAttributes endpoint not implemented

The endpoint described at this link:
https://docs.alchemy.com/reference/summarizenftattributes

doesn't seem to exist in the typescript client SDK, and I'd really like to use it please :)

The endpoint does seem to work on the docs page when I use your awesome "Try It!" functionality, and so I implemented my front-end component based on the data I received there, but then found the endpoint missing when I tried to hook it up to live data using the api client library

Network Error trying to use Notify Endpoints

[REQUIRED] Environment

  • Browser version: N/A
  • Alchemy SDK version: 2.2.3

[REQUIRED] Describe the problem

When trying to use the documented way to call alchemy.notify.getAllWebhooks(), you receive the following error:

Uncaught (in promise) Error: Network Error

No further information is provided by the SDK. This same error occurs when trying to use other notify endpoints such as updateWebhook()

How to reproduce:

See code below.

Relevant code or sample repro:

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

const settings = {
  authToken: "xxx", // I am using the AUTH TOKEN found in my Alchemy Dashboard under the Notify tab, upper right hand corner
  network: Network.ETH_MAINNET,
};

const alchemy = new Alchemy(settings);

alchemy.notify.getAllWebhooks().then(console.log);

FR: Add support to subscribe to `newHeads` directly

Environment

  • Browser version: Node v16.13
  • Alchemy SDK version: 2.2.3

Describe the problem

It's impossible to subscribe to newHeads websocket event via sdk methods. Subscription to block event only returns block number.

How to reproduce:

Method 1:

alchemy.ws.on('newHeads', (data) => {
   console.log(data);
});

// result:
unhandled: Event {
  tag: 'newheads',
  listener: [Function (anonymous)],
  once: false,
  _lastBlockNumber: -2,
  _inflight: false
}

no further events

Method 2:

alchemy.ws.on({ method: 'newHeads' }, (data) => {
   console.log(data);
});

// Unhandled rejection Error: Invalid method name newHeads. Accepted method names: alchemy_pendingTransactions,alchemy_minedTransactions

Relevant code or sample repro:

Event callback doesn't happen when specifying Alchemy API key on setting

Hello,
I wrote the code below to subscribe to the contract PositionChanged event on Arbitrum with Typechain Ethers-v5.
This code works as expected when no API key is given to setting, but when Alchemy API key is given, no callback happens.
I'd like to use an Alchemy private endpoint to avoid throttle by specifying API key.

import { Network, Alchemy } from 'alchemy-sdk';
const main = async()=> {
    const settings = {
            apiKey: "My API Key", 
            network Network.ARB_MAINNET,
    };
    const alchemy = new Alchemy(settings);
    const provider = await alchemy.config.getProvider();
    const signer = new Wallet(privateKey, provider);
    const { clearingHouse } = await getContracts(signer); // clearingHouse is Contract 
    const filter = clearingHouse.filters.PositionChanged();
    this.clearingHouse.on(filter, (accountId, poolId, vTokenAmountOut, vQuoteAmountOut, sqrtPriceX96Start, sqrtPriceX96End) => {
        console.log(accountId); // no callback happen when Alchemy API Key is specified.
    });
};
main();

How do I instantiate a Contract object using alchemy-sdk just like with ethers.js?

None of these seem to work:

  • const baycContract = new alchemy.Contract(baycAddress, baycABI, provider);
  • const baycContract = new alchemy.core.Contract(baycAddress, baycABI, provider);
  • const baycContract = new alchemy.ethers.Contract(baycAddress, baycABI, provider);

I get

TypeError: alchemy.Contract is not a constructor

or

TypeError: Cannot read properties of undefined (reading 'Contract')

I can’t find the Contract constructor in any of the namespaces 🤔

the documentation says:

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

Ethers.js documentation has this API:

new ethers.Contract( _address_ , _abi_ , _signerOrProvider_ )

so I’d expect this to work:

const ethers = alchemy.core;
const baycContract = new ethers.Contract(baycAddress, baycABI, provider);

but I get this error:

file:///Users/thatguyintech/Documents/co/Alchemy-Hacker-Handbook/evm_snippets/LoadContract/load-contract.js:20
const baycContract = new ethers.Contract(baycAddress, baycABI, provider);
                     ^

TypeError: ethers.Contract is not a constructor
    at file:///Users/thatguyintech/Documents/co/Alchemy-Hacker-Handbook/evm_snippets/LoadContract/load-contract.js:20:22

Any tips?

Contract object missing?

Hi,

I am not able to instantiate a Contract object the same way I would do with ethers.js (with the contract ABI to then be able to call methods) and can't find a doc explaining how to do it.
If you could point me in the right direction that would be great.

I see it here: https://github.com/alchemyplatform/alchemy-sdk-js/blob/10e96ee8b01aff0058158abd580afb38efb151f7/test/unit/contract.test.ts
but if I do:
const { Alchemy, Network, Wallet, Utils, Contract } = require("alchemy-sdk");
Contract is the only object not recognized, and I can't add methods

thanks

FR: Support Moonbase

hi, the SDK currently supports the following chains

  • Ethereum: Mainnet, Goerli
  • Polygon: Mainnet, Mumbai
  • Optimism: Mainnet, Goerli, Kovan
  • Arbitrum: Mainnet, Goerli, Rinkeby
  • Astar: Mainnet

I want to support moonbase chain as well😂

Error while backfilling "newHeads" subscription

[REQUIRED] Environment

Alchemy SDK, Node JS

[REQUIRED] Describe the problem

Alchemy SDK hangs after an internal exception during websocket "blocks" subscription event. The SDK tries to convert a non BigNumber value to BigNumber and crashes at Object.fromHex (.../node_modules/alchemy-sdk/dist/cjs/index-7d6928ec.js:229:32). After this crash, websocket subscriptions won't get any new events.

How to reproduce:

Subscribe to new "blocks" subscription (alchemy.ws.on("block", (blockNumber)) using alchemy SDK. New block events will be received normally as expected till it receives a server response with non hexadecimal/number value. In my experience this event occurs at least once every 12 hours.

Relevant code or sample repro:

Code:

alchemy.ws.on("block", (blockNumber) => {
    try {
      if (blockNumber != undefined) {
        latestBlockNumber = Number(blockNumber);
      }
    } catch (error) {
      console.log("block err: ", error.toString());
    }
  });

Stack:

Error while backfilling "newHeads" subscription. Some events may be missing. Error: invalid BigNumber value (argument="value", value=undefined, code=INVALID_ARGUMENT, version=bignumber/5.7.0)
at Logger.makeError (/var/app/current/node_modules/@ethersproject/logger/lib/index.js:238:21)
at Logger.throwError (/var/app/current/node_modules/@ethersproject/logger/lib/index.js:247:20)
at Logger.throwArgumentError (/var/app/current/node_modules/@ethersproject/logger/lib/index.js:250:21)
at Function.BigNumber.from (/var/app/current/node_modules/@ethersproject/bignumber/lib/bignumber.js:239:23)
at Object.fromHex (/var/app/current/node_modules/alchemy-sdk/dist/cjs/index-7d6928ec.js:229:32)
at getNewHeadsBlockNumber (/var/app/current/node_modules/alchemy-sdk/dist/cjs/alchemy-websocket-provider-94a351b4.js:1251:18)
at addToPastEventsBuffer (/var/app/current/node_modules/alchemy-sdk/dist/cjs/alchemy-websocket-provider-94a351b4.js:1274:32)
at AlchemyWebSocketProvider.rememberEvent (/var/app/current/node_modules/alchemy-sdk/dist/cjs/alchemy-websocket-provider-94a351b4.js:1002:9)
at AlchemyWebSocketProvider.emitAndRememberEvent (/var/app/current/node_modules/alchemy-sdk/dist/cjs/alchemy-websocket-provider-94a351b4.js:986:14)
at AlchemyWebSocketProvider.emitNewHeadsEvent (/var/app/current/node_modules/alchemy-sdk/dist/cjs/alchemy-websocket-provider-94a351b4.js:972:14)
at /var/app/current/node_modules/alchemy-sdk/dist/cjs/alchemy-websocket-provider-94a351b4.js:949:54
at Array.forEach (<anonymous>)
at AlchemyWebSocketProvider.<anonymous> (/var/app/current/node_modules/alchemy-sdk/dist/cjs/alchemy-websocket-provider-94a351b4.js:949:32)
at Generator.next (<anonymous>)
at fulfilled (/var/app/current/node_modules/alchemy-sdk/dist/cjs/index-7d6928ec.js:175:58)
at runMicrotasks (<anonymous>) {
reason: 'invalid BigNumber value',
code: 'INVALID_ARGUMENT',
argument: 'value',
value: undefined
}

Unable to use getTokenBalances

[REQUIRED] Environment

  • Alchemy SDK version: 2.2.0

[REQUIRED] Describe the problem:

I have a react-native project where we are building a wallet.

I am attempting to get all erc20 balances in a users wallet using the following line of code:
const balances = await alchemy.core.getTokenBalances(address, 'erc20')

When this code runs, however, I get the following error:

"invalid 2nd argument: contract_addresses was not a valid contract address array, string literals 'DEFAULT_TOKENS' or 'erc20', or a valid options object.\"

I've tried using 'DEFAULT_TOKENS' as well and get the same error.

How to reproduce:

Set up a react-native project and attempt to get all token balances using the following line of code:

const balances = await alchemy.core.getTokenBalances(address, 'erc20')

Run the project with a valid wallet address and observe the error.

Relevant code or sample repro:

import 'react-native-get-random-values';
import '@ethersproject/shims';

import { Network, Alchemy, Wallet } from 'alchemy-sdk';
import {ETHERS_NETWORK, ALCHEMY_API_KEY} from '@env';

const settings = {
    apiKey: ALCHEMY_API_KEY,
    network: Network.ETH_GOERLI
};
const alchemy = new Alchemy(settings);

export const getAllBalances = async (address) => {
    try {
        const balances = await alchemy.core.getTokenBalances(address, 'erc20');
        return balances;
    } catch (err) {
        console.log(err.message);
    }
}

`getNftsForOwner` fails for some tokens with no token ID

Hello! Not sure if this is a backend issue or an issue with this SDK, but posting here since the SDK is where we're seeing the error.

If there's a better place, happy to move this elsewhere.

Environment

Alchemy SDK version: 2.2.1

Describe the problem

For certain wallet addresses, the getNftsForOwner call fails. If this is user error, a more helpful error related to the cause of the issue would help. This error appears to be due to token metadata not being available.

How to reproduce:

Run the following:

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

const alchemy = new Alchemy({
  apiKey: '...',
  network: Network.ETH_MAINNET,
});
alchemy.nft.getNftsForOwner('0x477c2087f3d6e49b1be5c790a33b3a025a4fa569')

...which results in the following error:

Error: invalid BigNumber value (argument="value", value=undefined, code=INVALID_ARGUMENT, version=bignumber/5.7.0)
    at Logger.makeError (...node_modules/alchemy-sdk/node_modules/@ethersproject/logger/src.ts/index.ts:269:28)
    at Logger.throwError (...node_modules/alchemy-sdk/node_modules/@ethersproject/logger/src.ts/index.ts:281:20)
    at Logger.throwArgumentError (...node_modules/alchemy-sdk/node_modules/@ethersproject/logger/src.ts/index.ts:285:21)
    at Function.BigNumber.from (...node_modules/alchemy-sdk/node_modules/@ethersproject/bignumber/src.ts/bignumber.ts:289:23)
    at parseNftTokenId (...node_modules/alchemy-sdk/src/util/util.ts:131:20)
    at getNftFromRaw (...node_modules/alchemy-sdk/src/util/util.ts:105:14)
    at nftFromGetNftResponse (...node_modules/alchemy-sdk/src/internal/nft-api.ts:485:10)
    at getNftsForOwnerIterator_1 (...node_modules/alchemy-sdk/src/internal/nft-api.ts:122:4)
    at getNftsForOwnerIterator_1.next (<anonymous>)
    at resume (...node_modules/alchemy-sdk/dist/cjs/index-53a13ded.js:245:44) {
  reason: 'invalid BigNumber value',
  code: 'INVALID_ARGUMENT',
  argument: 'value',
  value: undefined
}

Add settings to control request timeout

When using alchemy-sdk in my project, sometimes the call just stuck there for a long time, I'd like a setting for timeout seconds, so I can have better control on it with timeout & maxRetries

Breaks Jest tests

[REQUIRED] Environment

  • Browser version: no browser
  • Alchemy SDK version: 2.2.1

[REQUIRED] Describe the problem

Alchemy SDK breaks our Jest tests:

    Details:

    /home/runner/work/..../node_modules/alchemy-sdk/dist/esm/index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import * as utils from './api/utils';
                                                                                      ^^^^^^

    SyntaxError: Cannot use import statement outside a module

How to reproduce:

Use the SDK with Jest.

Relevant code or sample repro:

lchemySubscription.PENDING_TRANSACTIONS, fromAddress/toAddress can not use string[]

[REQUIRED] Environment

  • Browser version:
  • Alchemy SDK version: 2.2.5

const settings = {
  apiKey: "xxxx", // Replace with your Alchemy API Key.
  network: Network.ETH_MAINNET,
};

const alchemy = new Alchemy(settings);

const followArray: string[] = [
  "0xde29d060d45901fb19ed6c6e959eb22d8626708e",
  "0xf25A027b01ec26AFdAb45963794007A91Aad9838",
];

// Subscription for Alchemy's pendingTransactions API
alchemy.ws.on(
  {
    method: AlchemySubscription.PENDING_TRANSACTIONS,
    toAddress: followArray,
  },
  (tx) => console.log(tx)
);

error:

F:\xxxx\node_modules\alchemy-sdk\dist\cjs\index-e8114eb4.js:276
    return new (P || (P = Promise))(function (resolve, reject) {
           ^
TypeError: Cannot read properties of undefined (reading 'config')
    at F:\xxxx\node_modules\alchemy-sdk\src\api\websocket-namespace.ts:194:33
    at Generator.next (<anonymous>)
    at F:\xxxx\node_modules\alchemy-sdk\dist\cjs\index-e8114eb4.js:280:71
    at new Promise (<anonymous>)
    at __awaiter (F:\xxxx\node_modules\alchemy-sdk\dist\cjs\index-e8114eb4.js:276:12)
    at _resolveNameOrError (F:\xxxx\node_modules\alchemy-sdk\dist\cjs\index-e8114eb4.js:2961:16)
    at Array.map (<anonymous>)
    at WebSocketNamespace.<anonymous> (F:\xxxx\node_modules\alchemy-sdk\src\api\websocket-namespace.ts:176:33)
    at Generator.next (<anonymous>)
    at F:\xxxx\node_modules\alchemy-sdk\dist\cjs\index-e8114eb4.js:280:71

why can't use alchemy_filteredNewFullPendingTransactions?

I need to monitor the transaction information of to and from field at the specified address.
but I use alchemy.ws.on({method: "alchemy_filteredNewFullPendingTransactions", address: '0x...'}) is monitor full pending transaction.

And I use alchemy.ws.on({method: "alchemy_pendingTransactions"}), it just can monitor to or from field address....

SDK not exposing the raw meta data properly from the response

In the response when you query with withMetadata: true, it returns the contract symbol and the contract name.

For example,

[
     {
...
      "contractMetadata": {
        "name": "Genuine Undead",
        "symbol": "GU",
        "totalSupply": "8",
        "tokenType": "ERC721"
      }
...
}
]

In the data structure returned by the SDK, all the names or titles include the token ID. I only want the contract name and/or symbol.

For example,

rawMetadata: {
  attributes: (4) [{}, {}, {}, {}],
  date: 1654355106928,
  description: "RISE AND SHINE",
  dna: "52de95bd3f07d9130621fa51d30e70fb9e831e35",
  edition: 156,
  image: "ipfs://QmVUgP9fnFh9R6HF3eMP3ro2fxvv76fQsrBud7yyPDAMdQ/156.png",
  name: "GENUINE UNDEAD #156",
}

I am looking for just the string Genuine Undead

Throws when NFT description is an object

return typeof description === 'string' ? description : description.join(' ');

This throws a type error when the description is an object because .join(' ') can only be called on an array.

Specifically, when I'm trying to call .getNftsForOwner(address) and there's an NFT where description:{...}

One NFT will prevent the rest from fetching.

Cannot find variable atob in react-native

[REQUIRED] Environment

  • Browser version: Chrome

  • Alchemy SDK version: 2.2.0

[REQUIRED] Describe the problem:

Whenever I try to import Alchemy from 'alchemy-sdk' I get the error stating that the variable 'atob' cannot be found.

How to reproduce:

In the terminal:
$ yarn add achemy-sdk
$ yarn

In the code:
import { Alchemy} from 'alchemy-sdk'

Etc:
Run project in expo

Receive error message

Relevant code or sample repro:

ReferenceError: Can't find variable: atob
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:95:17 in reportException
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:141:19 in handleException
at node_modules/react-native/Libraries/Core/setUpErrorHandling.js:24:39 in handleError
at node_modules/expo/build/errors/ExpoErrorManager.js:25:19 in errorHandler
at node_modules/expo/build/errors/ExpoErrorManager.js:30:24 in
at node_modules/expo-error-recovery/build/ErrorRecovery.fx.js:12:21 in ErrorUtils.setGlobalHandler$argument_0

getNftsForOwner() pageSize not working for RINKEBY network.

Calling the method getNftsForOwner() with a pageSize different from "100" (default) is not working for RINKEBY but it works fine on MAINNET.

I cannot find any warning in the documentation about this limitation, it is a bug?

Steps to reproduce:

  1. Instantiate the SDK with the RINKEBY network:
const alchemy = new Alchemy({
    apiKey: 'your api key'
    network: Network.ETH_RINKEBY
});
  1. Call the getNftsForOwner method with pageSize different from 100. The "walletAddress" of the example has 117 NFTs:
const nfts =  await alchemy.nft.getNftsForOwner(walletAddress, { pageSize: 50 });

The response of the code above is returning 100 NFTs.

EthersEvent not defined (typescript)

I'm trying to convert some javascript that uses the Alchemy SDK into TypeScript. It seems the typescript files in the project are malformed, making the library unusable with TypeScript. When I try to import the module, it fails. (This is 1.0.8)

This is my entire test script, it's one line:

import { initializeAlchemy } from "@alch/alchemy-sdk";

This results in

node_modules/@alch/alchemy-sdk/dist/src/api/alchemy-websocket-provider.d.ts:3:10 - error TS2305: Module '"../internal/internal-types"' has no exported member 'EthersEvent'.

3 import { EthersEvent } from '../internal/internal-types';
           ~~~~~~~~~~~

node_modules/@alch/alchemy-sdk/dist/src/internal/internal-types.d.ts:10:12 - error TS2304: Cannot find name 'EthersEvent'.

10     event: EthersEvent;
              ~~~~~~~~~~~

node_modules/@alch/alchemy-sdk/dist/src/internal/internal-types.d.ts:45:64 - error TS2304: Cannot find name 'SubscriptionEvent'.

45 export declare type WebSocketMessage = SingleOrBatchResponse | SubscriptionEvent;
                                                                  ~~~~~~~~~~~~~~~~~


Found 3 errors.

If I look at the code, it really doesn't have a definition for EthersEvent. I'm not a TypeScript expert nor an Alchemy expert, but I don't see how this code could ever work and I'm not sure what to do to go about fixing it.

method getNftMetadata doesn't return totalSupply for erc1155 token

[REQUIRED] Environment

  • Browser version:
  • Alchemy SDK version: 2.2.4

[REQUIRED] Describe the problem

method getNftMetadata doesn't return amount for erc1155 token. But if I call getNftsForOwner, it returns balance which is equals to amount. Tried different networks(polygon testnet, eth mainnet)

How to reproduce:

call the method with any multi token

Relevant code or sample repro:

await this.alchemySDK.nft.getNftMetadata(contractAddress, tokenId)
RES:
  contract: {
    address: '0xe08919ff2353da4168d1b338d89010f37ca11af2',
    name: undefined,
    symbol: undefined,
    totalSupply: undefined,
    tokenType: 'ERC1155'
  },
  tokenId: '6',
  tokenType: 'ERC1155',
  title: 'Susanoo',
  description: 'test descr',
  timeLastUpdated: '2022-12-15T16:34:14.026Z',
  metadataError: undefined,
  rawMetadata: {
    name: 'Susanoo',
    description: 'test descr',
    image: 'ipfs://QmdZusq12j7NyX1a8YpcCCs4E5PcVnwYdUaEgnS5eeAawR',
    attributes: []
  },
  tokenUri: {
    raw: 'ipfs://QmPA1GJY3rN9S1mmGqEmDDh4GPn49c5wcHsY7t1uF8gd59',
    gateway: 'https://alchemy.mypinata.cloud/ipfs/QmPA1GJY3rN9S1mmGqEmDDh4GPn49c5wcHsY7t1uF8gd59'
  },
  media: [
    {
      raw: 'ipfs://QmdZusq12j7NyX1a8YpcCCs4E5PcVnwYdUaEgnS5eeAawR',
      gateway: 'https://ipfs.io/ipfs/QmdZusq12j7NyX1a8YpcCCs4E5PcVnwYdUaEgnS5eeAawR'
    }
  ],
  spamInfo: undefined
}

FR: Add effective fee (or fee data) to getAssetTransfers

Hello.

Is your feature request related to a problem? Please describe.
(effective) Fee data is vital for any serious implementation of transaction history. Is there any chance it could be added to the alchemy_getAssetTransfers method?

Otherwise, for each transaction, getTransactionReceipt has to be called, which basically re-fetches already known data with the addition of fees and would massively bloat necessary request count.

Describe the solution you'd like
Along with other fields, effective fee amount would be returned.

Thanks

`Error: read ECONNRESET` and `504: Gateway Timeout`

Hey, testing out alchemy on an AWS EC2 instance. Running into a few errors with connecting to the Alchemy SDK.

9/10 times Alchemy and our app works fine, but these connection bugs have been happening sporadically. As soon as the ECONNRESET throws, 504 Gateway Timeout throws exactly 9 times.

Here's my alchemy setup v1.0.8

const settings = {
    apiKey: process.env.ALCHEMY_API_KEY,
    network: Network.ETH_GOERLI,
    maxRetries: 10
}
const alchemy = initializeAlchemy(settings);

Error: read ECONNRESET

Error: read ECONNRESET
    at TLSWrap.onStreamRead (node:internal/stream_base_commons:211:20) {
  errno: -104,
  code: 'ECONNRESET',
  syscall: 'read',
  config: {
    transitional: {
      silentJSONParsing: true,
      forcedJSONParsing: true,
      clarifyTimeoutError: false
    },
    adapter: [Function: httpAdapter],
    transformRequest: [ [Function: transformRequest] ],
    transformResponse: [ [Function: transformResponse] ],
    timeout: 0,
    xsrfCookieName: 'XSRF-TOKEN',
    xsrfHeaderName: 'X-XSRF-TOKEN',
    maxContentLength: -1,
    maxBodyLength: -1,
    validateStatus: [Function: validateStatus],
    headers: {
      Accept: 'application/json, text/plain, */*',
      'Alchemy-Ethers-Sdk-Version': '1.0.7',
      'Accept-Encoding': 'gzip',
      'User-Agent': 'axios/0.26.1'
    },
    method: 'get',
    url: 'https://eth-goerli.g.alchemy.com/nft/v2/{api key}/getNFTs',
    params: {
      contractAddresses: undefined,
      pageKey: undefined,
      filters: undefined,
      owner: '{address}',
      withMetadata: true
    },
    data: undefined
  },
  request: <ref *1> Writable {
    _writableState: WritableState {
      objectMode: false,
      highWaterMark: 16384,
      finalCalled: false,
      needDrain: false,
      ending: false,
      ended: false,
      finished: false,
      destroyed: false,
      decodeStrings: true,
      defaultEncoding: 'utf8',
      length: 0,
      writing: false,
      corked: 0,
      sync: true,
      bufferProcessing: false,
      onwrite: [Function: bound onwrite],
      writecb: null,
      writelen: 0,
      afterWriteTickInfo: null,
      buffered: [],
      bufferedIndex: 0,
      allBuffers: true,
      allNoop: true,
      pendingcb: 0,
      constructed: true,
      prefinished: false,
      errorEmitted: false,
      emitClose: true,
      autoDestroy: true,
      errored: null,
      closed: false,
      closeEmitted: false,
      [Symbol(kOnFinished)]: []
    },
    _events: [Object: null prototype] {
      response: [Function: handleResponse],
      error: [Function: handleRequestError],
      socket: [Function: handleRequestSocket]
    },
    _eventsCount: 3,
    _maxListeners: undefined,
    _options: {
      maxRedirects: 21,
      maxBodyLength: 10485760,
      protocol: 'https:',
      path: '/nft/v2/{api key}/getNFTs?owner={address}&withMetadata=true',
      method: 'GET',
      headers: [Object],
      agent: undefined,
      agents: [Object],
      auth: undefined,
      hostname: 'eth-goerli.g.alchemy.com',
      port: null,
      nativeProtocols: [Object],
      pathname: '/nft/v2/{api key}/getNFTs',
      search: '?owner={address}&withMetadata=true'
    },
    _ended: true,
    _ending: true,
    _redirectCount: 0,
    _redirects: [],
    _requestBodyLength: 0,
    _requestBodyBuffers: [],
    _onNativeResponse: [Function (anonymous)],
    _currentRequest: ClientRequest {
      _events: [Object: null prototype],
      _eventsCount: 7,
      _maxListeners: undefined,
      outputData: [],
      outputSize: 0,
      writable: true,
      destroyed: false,
      _last: true,
      chunkedEncoding: false,
      shouldKeepAlive: false,
      maxRequestsOnConnectionReached: false,
      _defaultKeepAlive: true,
      useChunkedEncodingByDefault: false,
      sendDate: false,
      _removedConnection: false,
      _removedContLen: false,
      _removedTE: false,
      _contentLength: 0,
      _hasBody: true,
      _trailer: '',
      finished: true,
      _headerSent: true,
      _closed: false,
      socket: [TLSSocket],
      _header: 'GET /nft/v2/{api key}/getNFTs?owner={address}&withMetadata=true HTTP/1.1\r\n' +
        'Accept: application/json, text/plain, */*\r\n' +
        'Alchemy-Ethers-Sdk-Version: 1.0.7\r\n' +
        'Accept-Encoding: gzip\r\n' +
        'User-Agent: axios/0.26.1\r\n' +
        'Host: eth-goerli.g.alchemy.com\r\n' +
        'Connection: close\r\n' +
        '\r\n',
      _keepAliveTimeout: 0,
      _onPendingData: [Function: nop],
      agent: [Agent],
      socketPath: undefined,
      method: 'GET',
      maxHeaderSize: undefined,
      insecureHTTPParser: undefined,
      path: '/nft/v2/{api key}/getNFTs?owner={address}&withMetadata=true',
      _ended: false,
      res: null,
      aborted: false,
      timeoutCb: null,
      upgradeOrConnect: false,
      parser: null,
      maxHeadersCount: null,
      reusedSocket: false,
      host: 'eth-goerli.g.alchemy.com',
      protocol: 'https:',
      _redirectable: [Circular *1],
      [Symbol(kCapture)]: false,
      [Symbol(kNeedDrain)]: false,
      [Symbol(corked)]: 0,
      [Symbol(kOutHeaders)]: [Object: null prototype]
    },
    _currentUrl: 'https://eth-goerli.g.alchemy.com/nft/v2/{api key}/getNFTs?owner={address}&withMetadata=true',
    [Symbol(kCapture)]: false
  },
  response: undefined,
  isAxiosError: true,
  toJSON: [Function: toJSON]
}

Error: 504 Gateway Timeout (as html doc)

Error 504
Ray ID: { variable } • 2022-07-19 19:18:20 UTC
Gateway time-out
You
Browser
Working
Ashburn
Cloudflare
Working
eth-goerli.g.alchemy.com
Host
Error
What happened?
The web server reported a gateway time-out error.

What can I do?
Please try again in a few minutes.

Was this page helpful? Yes No
Thank you for your feedback!
Cloudflare Ray ID: { variable }

getNftsForOwner media flag for image vs video

Would it be possible to add a flag in the media array from the getNftsForOwner response to distinguish if the media is an image or video? The gateway variable could either be an image, which you would set the src of an image tag as this variable or a video. If it is a short mp4 instead of an image (so a video html tag), there is no way to tell.

getNftsForContract totally broken

[REQUIRED] Environment

  • Browser version: Chrome (latest)
  • Alchemy SDK version: 2.2.3

[REQUIRED] Describe the problem

The endpoint for requesting Contract NFTs getNFTsForCollection is not working properly. No matter what I do, I get demo response in return. Changing the contractAddress value doesn't reveal the real data. The limit option property is changed to pageSize, but it is also limited to max 100 NFT Metadata. The pageKey option property isn't documented on the page (instead you get to see startToken which looks like deprecated): https://docs.alchemy.com/reference/getnftsforcollection.

How to reproduce:

https://eth-mainnet.g.alchemy.com/nft/v2/YOUR_API_KEY/getNFTsForCollection?contractAddress=0x60E4d786628Fea6478F785A6d7e704777c86a7c6

Response:
{"nfts":[{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000000"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000001"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000002"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000003"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000004"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000005"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000006"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000007"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000008"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000009"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000000a"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000000b"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000000c"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000000d"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000000e"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000000f"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000010"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000011"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000012"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000013"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000014"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000015"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000016"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000017"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000018"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000019"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000001a"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000001b"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000001c"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000001d"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000001e"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000001f"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000020"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000021"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000022"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000023"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000024"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000025"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000026"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000027"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000028"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000029"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000002a"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000002b"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000002c"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000002d"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000002e"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000002f"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000030"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000031"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000032"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000033"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000034"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000035"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000036"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000037"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000038"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000039"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000003a"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000003b"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000003c"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000003d"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000003e"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000003f"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000040"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000041"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000042"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000043"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000044"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000045"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000046"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000047"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000048"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000049"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000004a"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000004b"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000004c"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000004d"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000004e"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000004f"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000050"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000051"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000052"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000053"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000054"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000055"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000056"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000057"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000058"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000059"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000005a"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000005b"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000005c"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000005d"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000005e"}},{"id":{"tokenId":"0x000000000000000000000000000000000000000000000000000000000000005f"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000060"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000061"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000062"}},{"id":{"tokenId":"0x0000000000000000000000000000000000000000000000000000000000000063"}}],"nextToken":"0x0000000000000000000000000000000000000000000000000000000000000064"}

websocket filtering not working

alchemy.ws.on(
{
method: 'logs',
address: "xxxxxx",
},
res => console.log(res)
);

the filtering is not functioning, all kinds of tx coming out

The nft endpoint is returning a token URI error even though the token URI is valid

On the goerli testnet, the nft endpoint is returning a token URI error even though the token URI is valid:

const { pageKey, ownedNfts } = await alchemy.nft.getNftsForOwner(
  "0xE70989f0A6b50E3c8Ef6Df57e994E99AA79EbD27",
  { contractAddresses: [""0xe47463a0b8fd39286d7a72ca8e334795779e2f77""], }
);

Results in the following error:

"Contract returned a broken token uri, do not retry"

Screenshot 2022-11-02 at 12 20 16

But the token URI is correct and valid so why is it giving me this error?

See correct data returned from the token URI:
https://wrappedpunks.com:3000/api/punks/metadata/1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.