alchemy-sdk-js
alchemy-sdk-js copied to clipboard
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
@BZhelev Would the getNtMetadataBatch endpoint help? This way, you can call getNftsForOwner(address, contractAddress) to get all the owned nfts for the single contract you're interested in, and then pass the ones you'd like. Is your concern mainly the amount of Network IO you go through within a single contract?
Hey there thank you for the reply. Yes my concern is the amount of requests needed to find a single NFT for a given Owner. Keep in mind that some details are obscured since it's a project in BETA and I cannot share that many details.
I experimented a bit and found that getNtMetadataBatch:
- Does not include token balance as seen from below response, made with fetch with the following options
Options:
const options = {
method: 'POST',
headers: {
accept: 'application/json',
'content-type': 'application/json',
},
body: JSON.stringify({
tokens: [
{
contractAddress:
'ADDRESS',
tokenId: '7',
},
],
}),
};
fetch(
'https://polygon-mumbai.g.alchemy.com/nft/v2/{API_KEY}/getNFTMetadataBatch',
options,
)
.then(response => response.json())
.then(response => console.log('from API', response))
.catch(err => console.error(err));
Response:
[
{
"contract": {
"address": "ADDRESS"
},
"id": {
"tokenId": "7",
"tokenMetadata": {
"tokenType": "ERC1155"
}
},
"title": "TITLE",
"description": "A placeholder NFT",
"tokenUri": {
"raw": "URI",
"gateway": "URI"
},
"media": [
{
"raw": "",
"gateway": ""
}
],
"metadata": {
"externalUrl": "URL",
"tokenId": "7",
"contract": {
"name": "NAME",
"description": "DESCRIPTION",
"externalUrl": "URL",
"id": 2,
"imageUrl": "IMG_URL"
},
"description": "DESC",
"type": "placeholder",
"imageUrl": "IMG_URL",
"name": "NAME",
"contractId": 2,
"attributes": [],
"id": 6,
"rarity": "rare"
},
"timeLastUpdated": "2022-09-26T06:52:52.067Z",
"contractMetadata": {
"tokenType": "ERC1155",
"openSea": {
"lastIngestedAt": "2022-11-05T13:10:09.000Z"
}
}
}
]
2 ) I'm not sure that getNtMetadataBatch is included in the JS-SDK since in the docs it refers you to alchemy.nft.getNftMetadata:

3 ) On the other hand alchemy.nft.getNftMetadata does not return balance as well:
Options:
const res = await alchemyProvider.nft.getNftMetadata(
address,
tokenId,
);
Response:
{
"contract": {
"address": "ADDRESS",
"tokenType": "ERC1155"
},
"tokenId": "7",
"tokenType": "ERC1155",
"title": "TITLE",
"description": "DESC",
"timeLastUpdated": "2022-09-26T06:52:52.067Z",
"rawMetadata": {
"externalUrl": "URL",
"tokenId": "7",
"contract": {
"name": "NAME",
"description": "DESC",
"externalUrl": "URL",
"id": 2,
"imageUrl": "URL"
},
"description": "A placeholder NFT",
"type": "placeholder",
"imageUrl": "IMG_URL",
"name": "NAME",
"contractId": 2,
"attributes": [],
"id": 6,
"rarity": "rare"
},
"tokenUri": {
"raw": "URL",
"gateway": "URL"
},
"media": []
}
4 ) This is the response I'm looking for Options:
const fromOwner = await alchemyProvider.nft.getNftsForOwner(
userAddress,
{
pageSize: 1,
},
);
Owner Response:
{
"ownedNfts": [
{
"contract": {
"address": "ADDRESS",
"tokenType": "ERC1155"
},
"tokenId": "7",
"tokenType": "ERC1155",
"title": "TITLE",
"description": "DESC",
"timeLastUpdated": "2022-09-26T06:52:52.067Z",
"rawMetadata": {
"externalUrl": "URL",
"tokenId": "7",
"contract": {
"name": "NAME",
"description": "DESC",
"externalUrl": "URL",
"id": 2,
"imageUrl": "URL"
},
"description": "A placeholder NFT",
"type": "placeholder",
"imageUrl": "IMG",
"name": "NAME",
"contractId": 2,
"attributes": [],
"id": 6,
"rarity": "rare"
},
"tokenUri": {
"raw": "URL",
"gateway": "URL"
},
"media": [],
"balance": 9 // This is what I need, how many tokens does the user hold for this TokenId
}
],
"pageKey": "MHg0NTVhODFjZWJjNWNlZTljZmZiOTlhYmVkMzY4MDhmNzFiMTZhODE3OjB4MDc6ZmFsc2U=",
"totalCount": 9
}
To summarize, I need a convenient way in which I can fetch a single NFT for a given owner along with it's balance for that given owner. So basically an endpoint that will return me a single OwnedNft Response rather than the standard Nft one.
At the moment the only way in which I can do so is to loop thru the pages returned from alchemy.nft.getNftsForOwner.
My use case for this is that we're building a marketplace and in that marketplace you could navigate to a page for a given NFT and if you own that NFT then you can sell it. However in order to sell it you need to say how much of it you want to sell, and in order to know that you need a OwnedNft response.
The API I'm hoping for is one of two.
First option:
const fromOwner = await alchemyProvider.nft.getNftsForOwner(
userAddress,
{
pageSize: 1,
contractAddresses: [
'ADDRESS',
],
tokenIds: [
'TOKEN_ID'
]
},
);
Response:
{
"ownedNfts": [
{
"contract": {
"address": "ADDRESS",
"tokenType": "ERC1155"
},
"tokenId": "7",
"tokenType": "ERC1155",
"title": "TITLE",
"description": "DESC",
"timeLastUpdated": "2022-09-26T06:52:52.067Z",
"rawMetadata": {
"externalUrl": "URL",
"tokenId": "7",
"contract": {
"name": "NAME",
"description": "DESC",
"externalUrl": "URL",
"id": 2,
"imageUrl": "URL"
},
"description": "A placeholder NFT",
"type": "placeholder",
"imageUrl": "IMG",
"name": "NAME",
"contractId": 2,
"attributes": [],
"id": 6,
"rarity": "rare"
},
"tokenUri": {
"raw": "URL",
"gateway": "URL"
},
"media": [],
"balance": 9 // This is what I need, how many tokens does the user hold for this TokenId
}
],
"pageKey": "MHg0NTVhODFjZWJjNWNlZTljZmZiOTlhYmVkMzY4MDhmNzFiMTZhODE3OjB4MDc6ZmFsc2U=",
"totalCount": 9
}
So basically adding another field to filter by.
Second option is to provide a new endpoint as alchemy.nft.getSingleNftForOwner.
Second Option:
const fromOwner = await alchemyProvider.nft.getSingleNftForOwner(
userAddress,
'ADDRESS',
'TOKEN_ID'
);
Response:
{
"contract": {
"address": "ADDRESS",
"tokenType": "ERC1155"
},
"tokenId": "7",
"tokenType": "ERC1155",
"title": "TITLE",
"description": "DESC",
"timeLastUpdated": "2022-09-26T06:52:52.067Z",
"rawMetadata": {
"externalUrl": "URL",
"tokenId": "7",
"contract": {
"name": "NAME",
"description": "DESC",
"externalUrl": "URL",
"id": 2,
"imageUrl": "URL"
},
"description": "A placeholder NFT",
"type": "placeholder",
"imageUrl": "IMG",
"name": "NAME",
"contractId": 2,
"attributes": [],
"id": 6,
"rarity": "rare"
},
"tokenUri": {
"raw": "URL",
"gateway": "URL"
},
"media": [],
"balance": 9 // This is what I need, how many tokens does the user hold for this TokenId
}
All of the above are made with latest alchemy-sdk version 2.2.1
@BZhelev I'll keep this feature request open, and we'll prioritize this if there's sufficient developer demand. In the meantime, you can reduce the payload size by specifying omitMetadata: true in the method options. This will return only the contract address, token id, and balance and you can filter from there.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs
Hi @thebrianchen. I'm looking for an issue to contribute. Is this available?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs