Skip to content

Commit e7d62cf

Browse files
committed
added getch NFT per collection/name
1 parent b3d89ec commit e7d62cf

8 files changed

+127
-56
lines changed

client/package-lock.json

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

client/package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
]
4040
},
4141
"devDependencies": {
42-
"@babel/plugin-transform-private-property-in-object": "^7.23.4"
42+
"@babel/plugin-transform-private-property-in-object": "^7.23.4",
43+
"@babel/plugin-proposal-private-property-in-object": ""
4344
}
44-
}
45+
}

package-lock.json

+16
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@
3939
},
4040
"author": "Mari K. Ma",
4141
"license": "MIT",
42+
"dependencies": {
43+
"dotenv": "^8.2.0"
44+
},
4245
"bugs": {
4346
"url": "https://github.com/DraconMarius/nftapi-demo/issues"
4447
},

server/controllers/api.js

+98-51
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,30 @@
11
const router = require("express").Router();
22
const { Alchemy } = require('alchemy-sdk');
3+
const axios = require('axios')
4+
5+
const Key = process.env.ALCHEMY_API_KEY
36

47
// Configuration settings for each network
58
const configs = {
69
Eth: {
7-
apiKey: process.env.ALCHEMY_API_KEY,
10+
apiKey: Key,
811
network: 'eth-mainnet',
912
},
1013
Polygon: {
11-
apiKey: process.env.ALCHEMY_API_KEY,
14+
apiKey: Key,
1215
network: 'polygon-mainnet'
1316
},
1417
Aritrum: {
15-
apiKey: process.env.ALCHEMY_API_KEY,
18+
apiKey: Key,
1619
network: "arbitrum-mainnet"
1720
},
1821
Optimism: {
19-
apiKey: process.env.ALCHEMY_API_KEY,
22+
apiKey: Key,
2023
network: "optimism-mainnet"
2124
}
2225
};
2326

27+
2428
// // testing
2529
// router.get('/testing/:address', async (req, res) => {
2630
// console.log('===test===')
@@ -81,27 +85,47 @@ router.get('/nft/wallet/:address', async (req, res) => {
8185
console.log('==============/NFT/wallet==============')
8286
const address = req.params.address
8387

88+
// const fetchNFTperNetwork = async (net, config, address) => {
89+
// const alchemy = new Alchemy(config);
90+
// let options = {
91+
// omitMetadata: true
92+
// }
93+
// try {
94+
// // use interator version to get back all nfts with paging
95+
// const nftsIterator = alchemy.nft.getNftsForOwnerIterator(address, options);
96+
// let nfts = [];
97+
// //for each entry push to array
98+
// for await (const item of nftsIterator) {
99+
// nfts.push(item);
100+
// }
101+
102+
// console.log(`completed ${net}`)
103+
// console.log(`total item in ${net}, ${nfts.length}`)
104+
// return { [net]: nfts };
105+
// } catch (err) {
106+
// console.error(`Failed to fetch NFT for ${net} network`)
107+
// return { [net]: { error: `Failed to fetch NFT for ${net} network`, details: err.message } }
108+
// };
109+
// };
110+
84111
const fetchNFTperNetwork = async (net, config, address) => {
85112
const alchemy = new Alchemy(config);
86-
let options = {
87-
omitMetadata: true
88-
}
113+
console.log(config);
89114
try {
90-
// use interator version to get back all nfts with paging
91-
const nftsIterator = alchemy.nft.getNftsForOwnerIterator(address, options);
92-
let nfts = [];
93-
//for each page push to array
94-
for await (const item of nftsIterator) {
95-
nfts.push(item);
96-
}
97-
98-
console.log(`completed ${net}`)
99-
console.log(`total item in ${net}, ${nfts.length}`)
100-
return { [net]: nfts };
115+
const nfts = await alchemy.nft.getNftsForOwner(address);
116+
console.log(`completed ${net}, totalCount: ${nfts.totalCount}`);
117+
//returning an object for each network, including res, pulled out totalCount and pageKey for easier access
118+
return {
119+
[net]: {
120+
nfts,
121+
"totalCount": nfts.totalCount,
122+
"pageKey": nfts.pageKey
123+
}
124+
};
101125
} catch (err) {
102-
console.error(`Failed to fetch NFT for ${net} network`)
103-
return { [net]: { error: `Failed to fetch NFT for ${net} network`, details: err.message } }
104-
};
126+
console.error(`Failed to fetch NFT for ${net} network`);
127+
return { [net]: { error: `Failed to fetch NFT for ${net} network`, details: err.message } };
128+
}
105129
};
106130

107131
try {
@@ -113,6 +137,7 @@ router.get('/nft/wallet/:address', async (req, res) => {
113137
);
114138
// Combine the results into a single array
115139
const combinedResults = results.reduce((acc, result) => ({ ...acc, ...result }), {});
140+
116141
res.json([combinedResults]);
117142
} catch (err) {
118143
console.log(err);
@@ -122,41 +147,63 @@ router.get('/nft/wallet/:address', async (req, res) => {
122147

123148

124149

125-
// router.get('nft/collection:contractAdd?:slug?', async (req, res) => {
126-
// console.log('==============/NFT/collection==============')
127-
128-
// const contractAdd = req.params.contractAdd
129-
// const slug = req.params.slug
150+
router.get('/nft/collection/:net', async (req, res) => {
151+
console.log('==============/NFT/collection==============')
152+
console.log(` network selcted: ${req.params.net} `)
130153

131-
// const fetchNFTperNetwork = async (net, config, address) => {
132-
// const alchemy = new Alchemy(config);
133-
// try {
134-
// const nfts = await alchemy.nft.getNftsForOwner(address);
135-
// console.log(`completed ${net}`)
136-
// return { [net]: nfts };
137-
// } catch (err) {
138-
// console.error(`Failed to fetch NFT for ${net} network`)
139-
// return { [net]: { error: `Failed to fetch NFT for ${net} network`, details: err.message } }
140-
// };
141-
// };
142-
143-
// // check to make sure that only 1 optional param is passed
144-
// //please see https://docs.alchemy.com/reference/getnftsforcollection-v3
145-
// //if both slug name and address is provided, return 400 error
146-
// if ((contractAdd && slug) || (!contractAdd) && (!slug)) {
147-
// return res.status(400).json({ err: 'Please provide only contract OR slug' })
148-
// }
149-
150-
// try {
151-
// if (contractAdd) {
152-
// nfts = await alchemy.nft.get
153-
// }
154-
// }
154+
//use query param to pass thru
155+
// api/nft/collection/eth?contractAdd=x&slug=y
155156

157+
const input = {
158+
contractAdd: req.query.contractAdd,
159+
slug: req.query.slug
160+
}
161+
console.log(input)
162+
163+
const fetchNFTCollection = async (net, configs, input) => {
164+
//using the network param passed to decide which setting to use
165+
const config = { ...configs[net] }
166+
console.log(config)
167+
168+
let finalInput = input.contractAdd ?
169+
`contractAddress=${input.contractAdd}` :
170+
`collectionSlug=${input.slug}`;
171+
172+
//sdk doesn't support slug name? using axios to fetch the collection endpoint which support slug names
173+
const options = {
174+
method: 'GET',
175+
url: `https://${config.network}.g.alchemy.com/nft/v3/${Key}/getNFTsForContract?` +
176+
`${finalInput}` + `&withMetadata=true`,
177+
headers: { accept: 'application/json' }
178+
};
156179

180+
try {
181+
console.log('url', options.url)
182+
const nfts = await axios.request(options);
183+
console.log(`completed ${net}`)
184+
console.log(`total item in Collection - ${finalInput}, ${nfts.data.nfts.length}`)
185+
return { ...nfts.data }
186+
} catch (err) {
187+
console.error(`Failed to fetch NFT for ${finalInput} for ${net} network`)
188+
return { error: `Failed to fetch NFT for ${net} network`, details: err.message }
189+
};
190+
};
191+
//check to make sure that only 1 optional param is passed
192+
//please see https://docs.alchemy.com/reference/getnftsforcollection-v3
193+
//if both slug name and address is provided, return 400 error
194+
if ((input.contractAdd && input.slug) || (!input.contractAdd) && (!input.slug)) {
195+
return res.status(400).json({ err: 'Please provide only contract OR slug' })
196+
}
197+
try {
198+
const results = await fetchNFTCollection(req.params.net, configs, input)
157199

158200

201+
res.json(results);
202+
} catch (err) {
203+
console.log(err);
204+
res.status(500).json(err);
205+
};
159206

160-
// })
207+
})
161208

162209
module.exports = router;

server/package-lock.json

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/package.json

+4-3
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@
1010
"author": "",
1111
"license": "MIT",
1212
"dependencies": {
13-
"express": "^4.17.1",
1413
"alchemy-sdk": "^3.2.0",
15-
"dotenv": "^8.2.0"
14+
"axios": "^1.6.8",
15+
"dotenv": "^8.2.0",
16+
"express": "^4.17.1"
1617
},
1718
"devDependencies": {
1819
"nodemon": "^2.0.6"
1920
}
20-
}
21+
}

server/server.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
require('dotenv').config();
12
const express = require('express');
23
const path = require('path');
34
const app = express();

0 commit comments

Comments
 (0)