@xyo-network/crypto-nft-witness-wallet-plugin 2.77.20 → 2.78.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/index.cjs +169 -37
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.js +172 -40
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/lib/getNftCollectionMetadata.d.cts +6 -0
- package/dist/browser/lib/getNftCollectionMetadata.d.cts.map +1 -0
- package/dist/browser/lib/getNftCollectionMetadata.d.mts +6 -0
- package/dist/browser/lib/getNftCollectionMetadata.d.mts.map +1 -0
- package/dist/browser/lib/getNftCollectionMetadata.d.ts +6 -0
- package/dist/browser/lib/getNftCollectionMetadata.d.ts.map +1 -0
- package/dist/browser/lib/getNftFields.d.cts +11 -0
- package/dist/browser/lib/getNftFields.d.cts.map +1 -0
- package/dist/browser/lib/getNftFields.d.mts +11 -0
- package/dist/browser/lib/getNftFields.d.mts.map +1 -0
- package/dist/browser/lib/getNftFields.d.ts +11 -0
- package/dist/browser/lib/getNftFields.d.ts.map +1 -0
- package/dist/browser/lib/getNftsOwnedByAddress.d.cts.map +1 -1
- package/dist/browser/lib/getNftsOwnedByAddress.d.mts.map +1 -1
- package/dist/browser/lib/getNftsOwnedByAddress.d.ts.map +1 -1
- package/dist/browser/lib/getProvider.d.cts +3 -0
- package/dist/browser/lib/getProvider.d.cts.map +1 -0
- package/dist/browser/lib/getProvider.d.mts +3 -0
- package/dist/browser/lib/getProvider.d.mts.map +1 -0
- package/dist/browser/lib/getProvider.d.ts +3 -0
- package/dist/browser/lib/getProvider.d.ts.map +1 -0
- package/dist/node/index.js +169 -38
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +172 -41
- package/dist/node/index.mjs.map +1 -1
- package/dist/node/lib/getNftCollectionMetadata.d.cts +6 -0
- package/dist/node/lib/getNftCollectionMetadata.d.cts.map +1 -0
- package/dist/node/lib/getNftCollectionMetadata.d.mts +6 -0
- package/dist/node/lib/getNftCollectionMetadata.d.mts.map +1 -0
- package/dist/node/lib/getNftCollectionMetadata.d.ts +6 -0
- package/dist/node/lib/getNftCollectionMetadata.d.ts.map +1 -0
- package/dist/node/lib/getNftFields.d.cts +11 -0
- package/dist/node/lib/getNftFields.d.cts.map +1 -0
- package/dist/node/lib/getNftFields.d.mts +11 -0
- package/dist/node/lib/getNftFields.d.mts.map +1 -0
- package/dist/node/lib/getNftFields.d.ts +11 -0
- package/dist/node/lib/getNftFields.d.ts.map +1 -0
- package/dist/node/lib/getNftsOwnedByAddress.d.cts.map +1 -1
- package/dist/node/lib/getNftsOwnedByAddress.d.mts.map +1 -1
- package/dist/node/lib/getNftsOwnedByAddress.d.ts.map +1 -1
- package/dist/node/lib/getProvider.d.cts +3 -0
- package/dist/node/lib/getProvider.d.cts.map +1 -0
- package/dist/node/lib/getProvider.d.mts +3 -0
- package/dist/node/lib/getProvider.d.mts.map +1 -0
- package/dist/node/lib/getProvider.d.ts +3 -0
- package/dist/node/lib/getProvider.d.ts.map +1 -0
- package/package.json +10 -11
- package/src/lib/getNftCollectionMetadata.ts +60 -0
- package/src/lib/getNftFields.ts +90 -0
- package/src/lib/getNftsOwnedByAddress.ts +52 -39
- package/src/lib/getProvider.ts +17 -0
package/dist/browser/index.cjs
CHANGED
|
@@ -22,7 +22,7 @@ var src_exports = {};
|
|
|
22
22
|
__export(src_exports, {
|
|
23
23
|
CryptoWalletNftWitness: () => CryptoWalletNftWitness,
|
|
24
24
|
CryptoWalletNftWitnessPlugin: () => CryptoWalletNftWitnessPlugin,
|
|
25
|
-
checkIpfsUrl: () =>
|
|
25
|
+
checkIpfsUrl: () => checkIpfsUrl2,
|
|
26
26
|
default: () => src_default,
|
|
27
27
|
getErc1155MetadataUri: () => getErc1155MetadataUri,
|
|
28
28
|
getErc721MetadataUri: () => getErc721MetadataUri,
|
|
@@ -43,10 +43,8 @@ var import_abstract_witness = require("@xyo-network/abstract-witness");
|
|
|
43
43
|
var import_crypto_nft_payload_plugin2 = require("@xyo-network/crypto-nft-payload-plugin");
|
|
44
44
|
|
|
45
45
|
// src/lib/getNftsOwnedByAddress.ts
|
|
46
|
-
var
|
|
47
|
-
var
|
|
48
|
-
var import_crypto_nft_payload_plugin = require("@xyo-network/crypto-nft-payload-plugin");
|
|
49
|
-
var import_open_zeppelin_typechain = require("@xyo-network/open-zeppelin-typechain");
|
|
46
|
+
var import_axios2 = require("@xyo-network/axios");
|
|
47
|
+
var import_open_zeppelin_typechain3 = require("@xyo-network/open-zeppelin-typechain");
|
|
50
48
|
|
|
51
49
|
// src/lib/getInfuraProvider.ts
|
|
52
50
|
var import_providers = require("@ethersproject/providers");
|
|
@@ -65,7 +63,57 @@ var getInfuraProviderConfig = () => {
|
|
|
65
63
|
return { projectId, projectSecret };
|
|
66
64
|
};
|
|
67
65
|
|
|
68
|
-
// src/lib/
|
|
66
|
+
// src/lib/getNftFields.ts
|
|
67
|
+
var import_axios = require("@xyo-network/axios");
|
|
68
|
+
var import_crypto_nft_payload_plugin = require("@xyo-network/crypto-nft-payload-plugin");
|
|
69
|
+
var import_open_zeppelin_typechain2 = require("@xyo-network/open-zeppelin-typechain");
|
|
70
|
+
|
|
71
|
+
// src/lib/getNftCollectionMetadata.ts
|
|
72
|
+
var import_open_zeppelin_typechain = require("@xyo-network/open-zeppelin-typechain");
|
|
73
|
+
var import_ethers = require("ethers");
|
|
74
|
+
function getInterfaceID(contractInterface) {
|
|
75
|
+
let interfaceID = import_ethers.constants.Zero;
|
|
76
|
+
const functions = Object.keys(contractInterface.functions);
|
|
77
|
+
for (let i = 0; i < functions.length; i++) {
|
|
78
|
+
interfaceID = interfaceID.xor(contractInterface.getSighash(functions[i]));
|
|
79
|
+
}
|
|
80
|
+
return interfaceID.toHexString();
|
|
81
|
+
}
|
|
82
|
+
var getNftCollectionMetadata = async (contractAddress, provider) => {
|
|
83
|
+
try {
|
|
84
|
+
const contract721 = import_open_zeppelin_typechain.ERC721Enumerable__factory.connect(contractAddress, provider);
|
|
85
|
+
const contract1155 = import_open_zeppelin_typechain.ERC1155__factory.connect(contractAddress, provider);
|
|
86
|
+
let name = "";
|
|
87
|
+
try {
|
|
88
|
+
name = await contract721.name();
|
|
89
|
+
} catch (ex) {
|
|
90
|
+
const error = ex;
|
|
91
|
+
console.log(`name: ${error.message}`);
|
|
92
|
+
}
|
|
93
|
+
let symbol = "";
|
|
94
|
+
try {
|
|
95
|
+
symbol = await contract721.symbol();
|
|
96
|
+
} catch (ex) {
|
|
97
|
+
const error = ex;
|
|
98
|
+
console.log(`symbol: ${error.message}`);
|
|
99
|
+
}
|
|
100
|
+
let is1155 = false;
|
|
101
|
+
try {
|
|
102
|
+
is1155 = await contract1155.supportsInterface(getInterfaceID(import_open_zeppelin_typechain.ERC1155__factory.getInterface(import_open_zeppelin_typechain.ERC1155__factory.abi)));
|
|
103
|
+
} catch (ex) {
|
|
104
|
+
const error = ex;
|
|
105
|
+
console.log(`is1155: ${error.message}`);
|
|
106
|
+
is1155 = false;
|
|
107
|
+
}
|
|
108
|
+
return { address: contractAddress, chainId: provider.network.chainId, name, symbol, type: is1155 ? "ERC1155" : "ERC721" };
|
|
109
|
+
} catch (ex) {
|
|
110
|
+
const error = ex;
|
|
111
|
+
console.error(`getNftCollectionMetadata: ${error.message}`);
|
|
112
|
+
throw ex;
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// src/lib/getNftFields.ts
|
|
69
117
|
var ipfsGateway = "5d7b6582.beta.decentralnetworkservices.com";
|
|
70
118
|
var checkIpfsUrl = (urlToCheck, ipfsGateway2) => {
|
|
71
119
|
const url = new URL(urlToCheck);
|
|
@@ -83,9 +131,81 @@ var checkIpfsUrl = (urlToCheck, ipfsGateway2) => {
|
|
|
83
131
|
return urlToCheck;
|
|
84
132
|
}
|
|
85
133
|
};
|
|
134
|
+
var getNftFields = async (contractAddress, provider, tokenId) => {
|
|
135
|
+
const axios = new import_axios.AxiosJson({ timeout: 500 });
|
|
136
|
+
const storage = import_open_zeppelin_typechain2.ERC721URIStorage__factory.connect(contractAddress, provider);
|
|
137
|
+
const supply1155 = import_open_zeppelin_typechain2.ERC1155Supply__factory.connect(contractAddress, provider);
|
|
138
|
+
const { type: nftType } = await getNftCollectionMetadata(contractAddress, provider);
|
|
139
|
+
let supply;
|
|
140
|
+
try {
|
|
141
|
+
supply = nftType === (0, import_crypto_nft_payload_plugin.toTokenType)("ERC1155") ? (await supply1155.totalSupply(tokenId)).toHexString() : "0x01";
|
|
142
|
+
} catch (ex) {
|
|
143
|
+
const error = ex;
|
|
144
|
+
console.error(`supply: ${error.message}`);
|
|
145
|
+
}
|
|
146
|
+
let metaDataUri;
|
|
147
|
+
try {
|
|
148
|
+
metaDataUri = await storage.tokenURI(tokenId);
|
|
149
|
+
} catch (ex) {
|
|
150
|
+
const error = ex;
|
|
151
|
+
console.error(`metaDataUri: ${error.message}`);
|
|
152
|
+
}
|
|
153
|
+
const checkedMetaDataUri = metaDataUri ? checkIpfsUrl(metaDataUri, ipfsGateway) : metaDataUri;
|
|
154
|
+
let metadata = void 0;
|
|
155
|
+
try {
|
|
156
|
+
metadata = checkedMetaDataUri ? (await axios.get(checkedMetaDataUri)).data : void 0;
|
|
157
|
+
} catch (ex) {
|
|
158
|
+
const error = ex;
|
|
159
|
+
console.error(`metadata: ${error.message}`);
|
|
160
|
+
}
|
|
161
|
+
const info = {
|
|
162
|
+
address: contractAddress,
|
|
163
|
+
chainId: provider.network.chainId,
|
|
164
|
+
metaDataUri,
|
|
165
|
+
metadata,
|
|
166
|
+
schema: import_crypto_nft_payload_plugin.NftSchema,
|
|
167
|
+
supply: supply ?? "1",
|
|
168
|
+
tokenId,
|
|
169
|
+
type: nftType
|
|
170
|
+
};
|
|
171
|
+
return info;
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
// src/lib/getProvider.ts
|
|
175
|
+
var import_providers2 = require("@ethersproject/providers");
|
|
176
|
+
var getProviderFromEnv = (chainId = "homestead") => {
|
|
177
|
+
const infuraWssUri = process.env.INFURA_WSS_URI;
|
|
178
|
+
const infuraProvider = new import_providers2.InfuraProvider("homestead", {
|
|
179
|
+
projectId: process.env.INFURA_PROJECT_ID,
|
|
180
|
+
projectSecret: process.env.INFURA_PROJECT_SECRET
|
|
181
|
+
});
|
|
182
|
+
const infuraWebsocketProvider = infuraWssUri ? new import_providers2.WebSocketProvider(infuraWssUri, chainId) : void 0;
|
|
183
|
+
const quickNodeUri = process.env.QUICKNODE_WSS_URI;
|
|
184
|
+
const quickNodeProvider = quickNodeUri ? new import_providers2.WebSocketProvider(quickNodeUri, chainId) : void 0;
|
|
185
|
+
const provider = infuraWebsocketProvider ?? infuraProvider ?? infuraWebsocketProvider ?? quickNodeProvider ?? infuraProvider;
|
|
186
|
+
return provider;
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
// src/lib/getNftsOwnedByAddress.ts
|
|
190
|
+
var checkIpfsUrl2 = (urlToCheck, ipfsGateway2) => {
|
|
191
|
+
const url = new URL(urlToCheck);
|
|
192
|
+
let protocol = url.protocol;
|
|
193
|
+
let host = url.host;
|
|
194
|
+
let path = url.pathname;
|
|
195
|
+
const query = url.search;
|
|
196
|
+
if (protocol === "ipfs:") {
|
|
197
|
+
protocol = "https:";
|
|
198
|
+
host = ipfsGateway2;
|
|
199
|
+
path = url.host === "ipfs" ? `ipfs${path}` : `ipfs/${url.host}${path}`;
|
|
200
|
+
const root = `${protocol}//${host}/${path}`;
|
|
201
|
+
return query?.length > 0 ? `${root}?${query}` : root;
|
|
202
|
+
} else {
|
|
203
|
+
return urlToCheck;
|
|
204
|
+
}
|
|
205
|
+
};
|
|
86
206
|
var getErc721MetadataUri = async (address, tokenId) => {
|
|
87
207
|
try {
|
|
88
|
-
const contract =
|
|
208
|
+
const contract = import_open_zeppelin_typechain3.ERC721__factory.connect(address, getInfuraProvider());
|
|
89
209
|
return [await contract.tokenURI(tokenId), void 0];
|
|
90
210
|
} catch (ex) {
|
|
91
211
|
return [void 0, ex];
|
|
@@ -93,7 +213,7 @@ var getErc721MetadataUri = async (address, tokenId) => {
|
|
|
93
213
|
};
|
|
94
214
|
var getErc1155MetadataUri = async (address, tokenId) => {
|
|
95
215
|
try {
|
|
96
|
-
const contract =
|
|
216
|
+
const contract = import_open_zeppelin_typechain3.ERC1155__factory.connect(address, getInfuraProvider());
|
|
97
217
|
return [await contract.uri(tokenId), void 0];
|
|
98
218
|
} catch (ex) {
|
|
99
219
|
return [void 0, ex];
|
|
@@ -104,40 +224,52 @@ var getNftMetadataUri = async (address, tokenId) => {
|
|
|
104
224
|
return results[0][0] ?? results[1][0];
|
|
105
225
|
};
|
|
106
226
|
var getNftsOwnedByAddress = async (publicAddress, chainId, privateKey, maxNfts = 1e3, timeout = 2e3) => {
|
|
107
|
-
const
|
|
227
|
+
const axios = new import_axios2.AxiosJson();
|
|
108
228
|
const nfts = [];
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
return await Promise.all(
|
|
125
|
-
nfts.map(async (nft) => {
|
|
126
|
-
const metaDataUri = await getNftMetadataUri(nft.address, nft.tokenId);
|
|
127
|
-
if (metaDataUri) {
|
|
128
|
-
nft.metaDataUri = metaDataUri;
|
|
129
|
-
const cookedUri = checkIpfsUrl(metaDataUri, ipfsGateway);
|
|
130
|
-
try {
|
|
131
|
-
nft.metadata = (await axios.get(cookedUri, { timeout }))?.data;
|
|
132
|
-
} catch (ex) {
|
|
133
|
-
console.log(`failed to get NTF metadata [${cookedUri}] [${ex}]`);
|
|
229
|
+
const provider = getProviderFromEnv();
|
|
230
|
+
const qnUri = "https://api.quicknode.com/graphql";
|
|
231
|
+
const result = await axios.post(qnUri, {
|
|
232
|
+
query: `query Query {
|
|
233
|
+
ethereum {
|
|
234
|
+
walletByAddress(address: "${publicAddress}") {
|
|
235
|
+
walletNFTs {
|
|
236
|
+
edges {
|
|
237
|
+
node {
|
|
238
|
+
nft {
|
|
239
|
+
contractAddress
|
|
240
|
+
tokenId
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
134
244
|
}
|
|
135
|
-
} else {
|
|
136
|
-
console.log("failed to get NTF metadata URI");
|
|
137
245
|
}
|
|
138
|
-
|
|
246
|
+
}
|
|
247
|
+
}`,
|
|
248
|
+
variables: {}
|
|
249
|
+
});
|
|
250
|
+
const nftResult = await Promise.all(
|
|
251
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
252
|
+
Object.values(result.data.data.ethereum.walletByAddress.walletNFTs.edges).map(async (nft) => {
|
|
253
|
+
try {
|
|
254
|
+
const { contractAddress, tokenId } = nft.node.nft;
|
|
255
|
+
const { supply, type } = await getNftFields(contractAddress, provider, tokenId);
|
|
256
|
+
const fields = {
|
|
257
|
+
address: contractAddress,
|
|
258
|
+
chainId,
|
|
259
|
+
supply,
|
|
260
|
+
tokenId,
|
|
261
|
+
type
|
|
262
|
+
};
|
|
263
|
+
return fields;
|
|
264
|
+
} catch (ex) {
|
|
265
|
+
const error = ex;
|
|
266
|
+
console.error(`Error: ${error.message}`);
|
|
267
|
+
console.error(`${error.stack}`);
|
|
268
|
+
throw ex;
|
|
269
|
+
}
|
|
139
270
|
})
|
|
140
271
|
);
|
|
272
|
+
return nftResult;
|
|
141
273
|
};
|
|
142
274
|
|
|
143
275
|
// src/Witness.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts","../../src/Plugin.ts","../../src/Witness.ts","../../src/lib/getNftsOwnedByAddress.ts","../../src/lib/getInfuraProvider.ts"],"sourcesContent":["import { CryptoWalletNftWitnessPlugin } from './Plugin'\n\nexport * from './lib'\nexport * from './Witness'\n\nexport { CryptoWalletNftWitnessPlugin }\n\n// eslint-disable-next-line import/no-default-export\nexport default CryptoWalletNftWitnessPlugin\n","import { NftSchema } from '@xyo-network/crypto-nft-payload-plugin'\nimport { PayloadSetSchema } from '@xyo-network/payload-model'\nimport { createPayloadSetWitnessPlugin } from '@xyo-network/payloadset-plugin'\n\nimport { CryptoWalletNftWitness } from './Witness'\n\nexport const CryptoWalletNftWitnessPlugin = () =>\n createPayloadSetWitnessPlugin<CryptoWalletNftWitness>(\n { required: { [NftSchema]: 1 }, schema: PayloadSetSchema },\n {\n witness: async (params) => {\n const result = await CryptoWalletNftWitness.create(params)\n return result\n },\n },\n )\n","import { assertEx } from '@xylabs/assert'\nimport { EthAddress } from '@xylabs/eth-address'\nimport { AbstractWitness } from '@xyo-network/abstract-witness'\nimport {\n CryptoWalletNftWitnessConfig,\n isNftWitnessQuery,\n NftInfo,\n NftSchema,\n NftWitnessConfigSchema,\n NftWitnessQuery,\n} from '@xyo-network/crypto-nft-payload-plugin'\nimport { AnyConfigSchema } from '@xyo-network/module-model'\nimport { WitnessParams } from '@xyo-network/witness-model'\n\nimport { getNftsOwnedByAddress } from './lib'\n\nexport type CryptoWalletNftWitnessParams = WitnessParams<AnyConfigSchema<CryptoWalletNftWitnessConfig>>\n\nconst schema = NftSchema\n\nconst defaultMaxNfts = 100\n\nexport class CryptoWalletNftWitness<TParams extends CryptoWalletNftWitnessParams = CryptoWalletNftWitnessParams> extends AbstractWitness<\n TParams,\n NftWitnessQuery,\n NftInfo\n> {\n static override configSchemas = [NftWitnessConfigSchema]\n\n get timeout() {\n return this.config.timeout ?? 2000\n }\n\n protected override async observeHandler(payloads?: NftWitnessQuery[]): Promise<NftInfo[]> {\n await this.started('throw')\n const queries = payloads?.filter(isNftWitnessQuery) ?? []\n const observations = await Promise.all(\n queries.map(async (query) => {\n const address = assertEx(\n EthAddress.parse(assertEx(query?.address || this.config.address, 'params.address is required')),\n 'Failed to parse params.address',\n ).toString()\n const chainId = assertEx(query?.chainId || this.config.chainId, 'params.chainId is required')\n const maxNfts = query?.maxNfts || defaultMaxNfts\n try {\n const nfts = await getNftsOwnedByAddress(address, chainId, this.account.private.hex, maxNfts, this.timeout)\n const observation = nfts.map<NftInfo>((nft) => {\n return { ...nft, schema }\n })\n return observation\n } catch (error) {\n throw new Error(`Failed to get nfts for address ${address} on chainId ${chainId}`)\n }\n }),\n )\n return observations.flat()\n }\n}\n","import { Auth, SDK } from '@infura/sdk'\nimport { AxiosJson } from '@xyo-network/axios'\nimport { NftInfoFields, toTokenType } from '@xyo-network/crypto-nft-payload-plugin'\nimport { ERC721__factory, ERC1155__factory } from '@xyo-network/open-zeppelin-typechain'\n\nimport { getInfuraProvider } from './getInfuraProvider'\n\ntype PublicAddressOptions = {\n cursor?: string\n includeMetadata?: boolean\n publicAddress: string\n tokenAddresses?: string[]\n}\n\nconst ipfsGateway = '5d7b6582.beta.decentralnetworkservices.com'\n\n/**\n * Returns the equivalent IPFS gateway URL for the supplied URL.\n * @param urlToCheck The URL to check\n * @returns If the supplied URL is an IPFS URL, it converts the URL to the\n * equivalent IPFS gateway URL. Otherwise, returns the original URL.\n */\nexport const checkIpfsUrl = (urlToCheck: string, ipfsGateway: string) => {\n const url = new URL(urlToCheck)\n let protocol = url.protocol\n let host = url.host\n let path = url.pathname\n const query = url.search\n if (protocol === 'ipfs:') {\n protocol = 'https:'\n host = ipfsGateway\n path = url.host === 'ipfs' ? `ipfs${path}` : `ipfs/${url.host}${path}`\n const root = `${protocol}//${host}/${path}`\n return query?.length > 0 ? `${root}?${query}` : root\n } else {\n return urlToCheck\n }\n}\n\nexport const getErc721MetadataUri = async (address: string, tokenId: string): Promise<[string | undefined, Error | undefined]> => {\n try {\n const contract = ERC721__factory.connect(address, getInfuraProvider())\n return [await contract.tokenURI(tokenId), undefined]\n } catch (ex) {\n return [undefined, ex as Error]\n }\n}\n\nexport const getErc1155MetadataUri = async (address: string, tokenId: string): Promise<[string | undefined, Error | undefined]> => {\n try {\n const contract = ERC1155__factory.connect(address, getInfuraProvider())\n return [await contract.uri(tokenId), undefined]\n } catch (ex) {\n return [undefined, ex as Error]\n }\n}\n\nexport const getNftMetadataUri = async (address: string, tokenId: string) => {\n const results = await Promise.all([getErc721MetadataUri(address, tokenId), getErc1155MetadataUri(address, tokenId)])\n return results[0][0] ?? results[1][0]\n}\n\nexport const getNftsOwnedByAddress = async (\n /** @param publicAddress The address of the wallet to search for NFTs */\n publicAddress: string,\n /** @param chainId The chain ID (1 = Ethereum Mainnet, 4 = Rinkeby, etc.) of the chain to search for NFTs on */\n chainId: number,\n /** @param privateKey The private key of the wallet to use to search for NFTs */\n privateKey: string,\n /** @param maxNfts The maximum number of NFTs to return. Configurable to prevent large wallets from exhausting Infura API credits. */\n maxNfts = 1000,\n /** @param httpTimeout The connection timeout for http call to get metadata */\n timeout = 2000,\n): Promise<NftInfoFields[]> => {\n const sdk = new SDK(new Auth({ chainId, privateKey, projectId: process.env.INFURA_PROJECT_ID, secretId: process.env.INFURA_PROJECT_SECRET }))\n const nfts: NftInfoFields[] = []\n const axios = new AxiosJson()\n let cursor: string | undefined = undefined\n do {\n const opts: PublicAddressOptions = { cursor, includeMetadata: true, publicAddress }\n const { cursor: nextCursor, pageSize, total, assets } = await sdk.api.getNFTs(opts)\n const batch: NftInfoFields[] = assets.slice(0, Math.min(pageSize, total - nfts.length)).map((asset) => {\n const { contract: address, type: tokenType, ...rest } = asset\n const type = toTokenType(tokenType)\n return { address, chainId, type, ...rest }\n })\n nfts.push(...batch)\n cursor = nextCursor\n if (nfts.length >= total || !cursor) break\n } while (nfts.length < maxNfts)\n\n return await Promise.all(\n nfts.map(async (nft) => {\n const metaDataUri = await getNftMetadataUri(nft.address, nft.tokenId)\n if (metaDataUri) {\n nft.metaDataUri = metaDataUri\n const cookedUri = checkIpfsUrl(metaDataUri, ipfsGateway)\n try {\n nft.metadata = (await axios.get(cookedUri, { timeout }))?.data\n } catch (ex) {\n console.log(`failed to get NTF metadata [${cookedUri}] [${ex}]`)\n }\n } else {\n console.log('failed to get NTF metadata URI')\n }\n return nft\n }),\n )\n}\n","import { InfuraProvider, Provider } from '@ethersproject/providers'\nimport { assertEx } from '@xylabs/assert'\n\nexport interface InfuraProviderConfig {\n projectId: string\n projectSecret: string\n}\n\nlet instance: InfuraProvider | undefined = undefined\n\nexport const getInfuraProvider = (): Provider => {\n if (instance) return instance\n const config = getInfuraProviderConfig()\n instance = new InfuraProvider('homestead', config)\n return instance\n}\n\nexport const canUseInfuraProvider = (): boolean => {\n return !!process.env.INFURA_PROJECT_ID && !!process.env.INFURA_PROJECT_SECRET ? true : false\n}\n\nexport const getInfuraProviderConfig = (): InfuraProviderConfig => {\n const projectId = assertEx(process.env.INFURA_PROJECT_ID, 'Missing INFURA_PROJECT_ID ENV VAR')\n const projectSecret = assertEx(process.env.INFURA_PROJECT_SECRET, 'Missing INFURA_PROJECT_SECRET ENV VAR')\n return { projectId, projectSecret }\n}\n"],"mappings":"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","names":["import_crypto_nft_payload_plugin","import_assert","import_crypto_nft_payload_plugin","ipfsGateway"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts","../../src/Plugin.ts","../../src/Witness.ts","../../src/lib/getNftsOwnedByAddress.ts","../../src/lib/getInfuraProvider.ts","../../src/lib/getNftFields.ts","../../src/lib/getNftCollectionMetadata.ts","../../src/lib/getProvider.ts"],"sourcesContent":["import { CryptoWalletNftWitnessPlugin } from './Plugin'\n\nexport * from './lib'\nexport * from './Witness'\n\nexport { CryptoWalletNftWitnessPlugin }\n\n// eslint-disable-next-line import/no-default-export\nexport default CryptoWalletNftWitnessPlugin\n","import { NftSchema } from '@xyo-network/crypto-nft-payload-plugin'\nimport { PayloadSetSchema } from '@xyo-network/payload-model'\nimport { createPayloadSetWitnessPlugin } from '@xyo-network/payloadset-plugin'\n\nimport { CryptoWalletNftWitness } from './Witness'\n\nexport const CryptoWalletNftWitnessPlugin = () =>\n createPayloadSetWitnessPlugin<CryptoWalletNftWitness>(\n { required: { [NftSchema]: 1 }, schema: PayloadSetSchema },\n {\n witness: async (params) => {\n const result = await CryptoWalletNftWitness.create(params)\n return result\n },\n },\n )\n","import { assertEx } from '@xylabs/assert'\nimport { EthAddress } from '@xylabs/eth-address'\nimport { AbstractWitness } from '@xyo-network/abstract-witness'\nimport {\n CryptoWalletNftWitnessConfig,\n isNftWitnessQuery,\n NftInfo,\n NftSchema,\n NftWitnessConfigSchema,\n NftWitnessQuery,\n} from '@xyo-network/crypto-nft-payload-plugin'\nimport { AnyConfigSchema } from '@xyo-network/module-model'\nimport { WitnessParams } from '@xyo-network/witness-model'\n\nimport { getNftsOwnedByAddress } from './lib'\n\nexport type CryptoWalletNftWitnessParams = WitnessParams<AnyConfigSchema<CryptoWalletNftWitnessConfig>>\n\nconst schema = NftSchema\n\nconst defaultMaxNfts = 100\n\nexport class CryptoWalletNftWitness<TParams extends CryptoWalletNftWitnessParams = CryptoWalletNftWitnessParams> extends AbstractWitness<\n TParams,\n NftWitnessQuery,\n NftInfo\n> {\n static override configSchemas = [NftWitnessConfigSchema]\n\n get timeout() {\n return this.config.timeout ?? 2000\n }\n\n protected override async observeHandler(payloads?: NftWitnessQuery[]): Promise<NftInfo[]> {\n await this.started('throw')\n const queries = payloads?.filter(isNftWitnessQuery) ?? []\n const observations = await Promise.all(\n queries.map(async (query) => {\n const address = assertEx(\n EthAddress.parse(assertEx(query?.address || this.config.address, 'params.address is required')),\n 'Failed to parse params.address',\n ).toString()\n const chainId = assertEx(query?.chainId || this.config.chainId, 'params.chainId is required')\n const maxNfts = query?.maxNfts || defaultMaxNfts\n try {\n const nfts = await getNftsOwnedByAddress(address, chainId, this.account.private.hex, maxNfts, this.timeout)\n const observation = nfts.map<NftInfo>((nft) => {\n return { ...nft, schema }\n })\n return observation\n } catch (error) {\n throw new Error(`Failed to get nfts for address ${address} on chainId ${chainId}`)\n }\n }),\n )\n return observations.flat()\n }\n}\n","import { AxiosJson } from '@xyo-network/axios'\nimport { NftInfoFields } from '@xyo-network/crypto-nft-payload-plugin'\nimport { ERC721__factory, ERC1155__factory } from '@xyo-network/open-zeppelin-typechain'\n\nimport { getInfuraProvider } from './getInfuraProvider'\nimport { getNftFields } from './getNftFields'\nimport { getProviderFromEnv } from './getProvider'\n\n/**\n * Returns the equivalent IPFS gateway URL for the supplied URL.\n * @param urlToCheck The URL to check\n * @returns If the supplied URL is an IPFS URL, it converts the URL to the\n * equivalent IPFS gateway URL. Otherwise, returns the original URL.\n */\nexport const checkIpfsUrl = (urlToCheck: string, ipfsGateway: string) => {\n const url = new URL(urlToCheck)\n let protocol = url.protocol\n let host = url.host\n let path = url.pathname\n const query = url.search\n if (protocol === 'ipfs:') {\n protocol = 'https:'\n host = ipfsGateway\n path = url.host === 'ipfs' ? `ipfs${path}` : `ipfs/${url.host}${path}`\n const root = `${protocol}//${host}/${path}`\n return query?.length > 0 ? `${root}?${query}` : root\n } else {\n return urlToCheck\n }\n}\n\nexport const getErc721MetadataUri = async (address: string, tokenId: string): Promise<[string | undefined, Error | undefined]> => {\n try {\n const contract = ERC721__factory.connect(address, getInfuraProvider())\n return [await contract.tokenURI(tokenId), undefined]\n } catch (ex) {\n return [undefined, ex as Error]\n }\n}\n\nexport const getErc1155MetadataUri = async (address: string, tokenId: string): Promise<[string | undefined, Error | undefined]> => {\n try {\n const contract = ERC1155__factory.connect(address, getInfuraProvider())\n return [await contract.uri(tokenId), undefined]\n } catch (ex) {\n return [undefined, ex as Error]\n }\n}\n\nexport const getNftMetadataUri = async (address: string, tokenId: string) => {\n const results = await Promise.all([getErc721MetadataUri(address, tokenId), getErc1155MetadataUri(address, tokenId)])\n return results[0][0] ?? results[1][0]\n}\n\ninterface QuickNodeNft {\n contractAddress: string\n tokenId: string\n}\n\nexport const getNftsOwnedByAddress = async (\n /** @param publicAddress The address of the wallet to search for NFTs */\n publicAddress: string,\n /** @param chainId The chain ID (1 = Ethereum Mainnet, 4 = Rinkeby, etc.) of the chain to search for NFTs on */\n chainId: number,\n /** @param privateKey The private key of the wallet to use to search for NFTs */\n privateKey: string,\n /** @param maxNfts The maximum number of NFTs to return. Configurable to prevent large wallets from exhausting Infura API credits. */\n maxNfts = 1000,\n /** @param httpTimeout The connection timeout for http call to get metadata */\n timeout = 2000,\n): Promise<NftInfoFields[]> => {\n const axios = new AxiosJson()\n const nfts: NftInfoFields[] = []\n const provider = getProviderFromEnv()\n\n const qnUri = 'https://api.quicknode.com/graphql'\n\n const result = await axios.post(qnUri, {\n query: `query Query {\n ethereum {\n walletByAddress(address: \"${publicAddress}\") {\n walletNFTs {\n edges {\n node {\n nft {\n contractAddress\n tokenId\n }\n }\n }\n }\n }\n }\n }`,\n variables: {},\n })\n\n const nftResult = await Promise.all(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Object.values(result.data.data.ethereum.walletByAddress.walletNFTs.edges).map(async (nft: any) => {\n try {\n const { contractAddress, tokenId } = nft.node.nft as QuickNodeNft\n const { supply, type } = await getNftFields(contractAddress, provider, tokenId)\n const fields: NftInfoFields = {\n address: contractAddress,\n chainId,\n supply,\n tokenId,\n type,\n }\n return fields\n } catch (ex) {\n const error = ex as Error\n console.error(`Error: ${error.message}`)\n console.error(`${error.stack}`)\n throw ex\n }\n }),\n )\n\n return nftResult\n}\n","import { InfuraProvider, Provider } from '@ethersproject/providers'\nimport { assertEx } from '@xylabs/assert'\n\nexport interface InfuraProviderConfig {\n projectId: string\n projectSecret: string\n}\n\nlet instance: InfuraProvider | undefined = undefined\n\nexport const getInfuraProvider = (): Provider => {\n if (instance) return instance\n const config = getInfuraProviderConfig()\n instance = new InfuraProvider('homestead', config)\n return instance\n}\n\nexport const canUseInfuraProvider = (): boolean => {\n return !!process.env.INFURA_PROJECT_ID && !!process.env.INFURA_PROJECT_SECRET ? true : false\n}\n\nexport const getInfuraProviderConfig = (): InfuraProviderConfig => {\n const projectId = assertEx(process.env.INFURA_PROJECT_ID, 'Missing INFURA_PROJECT_ID ENV VAR')\n const projectSecret = assertEx(process.env.INFURA_PROJECT_SECRET, 'Missing INFURA_PROJECT_SECRET ENV VAR')\n return { projectId, projectSecret }\n}\n","import { JsonRpcProvider } from '@ethersproject/providers'\nimport { AxiosJson } from '@xyo-network/axios'\nimport { NftInfo, NftMetadata, NftSchema, toTokenType } from '@xyo-network/crypto-nft-payload-plugin'\nimport { ERC721URIStorage__factory, ERC1155Supply__factory } from '@xyo-network/open-zeppelin-typechain'\n\nimport { getNftCollectionMetadata } from './getNftCollectionMetadata'\n\nconst ipfsGateway = '5d7b6582.beta.decentralnetworkservices.com'\n\n/**\n * Returns the equivalent IPFS gateway URL for the supplied URL.\n * @param urlToCheck The URL to check\n * @returns If the supplied URL is an IPFS URL, it converts the URL to the\n * equivalent IPFS gateway URL. Otherwise, returns the original URL.\n */\nexport const checkIpfsUrl = (urlToCheck: string, ipfsGateway: string) => {\n const url = new URL(urlToCheck)\n let protocol = url.protocol\n let host = url.host\n let path = url.pathname\n const query = url.search\n if (protocol === 'ipfs:') {\n protocol = 'https:'\n host = ipfsGateway\n path = url.host === 'ipfs' ? `ipfs${path}` : `ipfs/${url.host}${path}`\n const root = `${protocol}//${host}/${path}`\n return query?.length > 0 ? `${root}?${query}` : root\n } else {\n return urlToCheck\n }\n}\n\nexport const getNftFields = async (\n /**\n * The address of the NFT contract to search for\n */\n contractAddress: string,\n /**\n * The chain ID (1 = Ethereum Mainnet, 4 = Rinkeby, etc.) of the chain to search for NFTs on\n */\n provider: JsonRpcProvider,\n /**\n * The maximum number of NFTs to return. Configurable to prevent\n * large wallets from exhausting Infura API credits. Ideally a\n * multiple of 100 as that appears to be the default page size.\n */\n tokenId: string,\n): Promise<NftInfo> => {\n const axios = new AxiosJson({ timeout: 500 })\n const storage = ERC721URIStorage__factory.connect(contractAddress, provider)\n const supply1155 = ERC1155Supply__factory.connect(contractAddress, provider)\n const { type: nftType } = await getNftCollectionMetadata(contractAddress, provider)\n\n let supply: string | undefined\n try {\n supply = nftType === toTokenType('ERC1155') ? (await supply1155.totalSupply(tokenId)).toHexString() : '0x01'\n } catch (ex) {\n const error = ex as Error\n console.error(`supply: ${error.message}`)\n }\n\n let metaDataUri: string | undefined\n try {\n metaDataUri = await storage.tokenURI(tokenId)\n } catch (ex) {\n const error = ex as Error\n console.error(`metaDataUri: ${error.message}`)\n }\n\n const checkedMetaDataUri = metaDataUri ? checkIpfsUrl(metaDataUri, ipfsGateway) : metaDataUri\n let metadata: NftMetadata | undefined = undefined\n try {\n metadata = checkedMetaDataUri ? (await axios.get(checkedMetaDataUri)).data : undefined\n } catch (ex) {\n const error = ex as Error\n console.error(`metadata: ${error.message}`)\n }\n\n const info: NftInfo = {\n address: contractAddress,\n chainId: provider.network.chainId,\n metaDataUri,\n metadata,\n schema: NftSchema,\n supply: supply ?? '1',\n tokenId,\n type: nftType,\n }\n return info\n}\n","import { Interface } from '@ethersproject/abi'\nimport { JsonRpcProvider } from '@ethersproject/providers'\nimport { NftCollectionMetadata } from '@xyo-network/crypto-nft-collection-payload-plugin'\nimport { ERC721Enumerable__factory, ERC1155__factory } from '@xyo-network/open-zeppelin-typechain'\nimport { constants } from 'ethers'\n\nimport { getProviderFromEnv } from './getProvider'\n\nexport function getInterfaceID(contractInterface: Interface) {\n let interfaceID = constants.Zero\n const functions: string[] = Object.keys(contractInterface.functions)\n for (let i = 0; i < functions.length; i++) {\n interfaceID = interfaceID.xor(contractInterface.getSighash(functions[i]))\n }\n\n return interfaceID.toHexString()\n}\n\nexport const getNftCollectionMetadata = async (\n /**\n * The address of the NFT contract to search for\n */\n contractAddress: string,\n /**\n * The chain ID (1 = Ethereum Mainnet, 4 = Rinkeby, etc.) of the chain to search for NFTs on\n */\n provider: JsonRpcProvider,\n): Promise<Omit<NftCollectionMetadata, 'total'>> => {\n try {\n const contract721 = ERC721Enumerable__factory.connect(contractAddress, provider)\n const contract1155 = ERC1155__factory.connect(contractAddress, provider)\n let name: string = ''\n try {\n name = await contract721.name()\n } catch (ex) {\n const error = ex as Error\n console.log(`name: ${error.message}`)\n }\n let symbol: string = ''\n try {\n symbol = await contract721.symbol()\n } catch (ex) {\n const error = ex as Error\n console.log(`symbol: ${error.message}`)\n }\n let is1155: boolean = false\n try {\n is1155 = await contract1155.supportsInterface(getInterfaceID(ERC1155__factory.getInterface(ERC1155__factory.abi)))\n } catch (ex) {\n const error = ex as Error\n console.log(`is1155: ${error.message}`)\n is1155 = false\n }\n return { address: contractAddress, chainId: provider.network.chainId, name, symbol, type: is1155 ? 'ERC1155' : 'ERC721' }\n } catch (ex) {\n const error = ex as Error\n console.error(`getNftCollectionMetadata: ${error.message}`)\n throw ex\n }\n}\n","import { InfuraProvider, WebSocketProvider } from '@ethersproject/providers'\n\nexport const getProviderFromEnv = (chainId: string | number = 'homestead') => {\n const infuraWssUri = process.env.INFURA_WSS_URI\n const infuraProvider = new InfuraProvider('homestead', {\n projectId: process.env.INFURA_PROJECT_ID,\n projectSecret: process.env.INFURA_PROJECT_SECRET,\n })\n\n const infuraWebsocketProvider = infuraWssUri ? new WebSocketProvider(infuraWssUri, chainId) : undefined\n\n const quickNodeUri = process.env.QUICKNODE_WSS_URI\n const quickNodeProvider = quickNodeUri ? new WebSocketProvider(quickNodeUri, chainId) : undefined\n\n const provider = infuraWebsocketProvider ?? infuraProvider ?? infuraWebsocketProvider ?? quickNodeProvider ?? infuraProvider\n return provider\n}\n"],"mappings":"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","names":["checkIpfsUrl","import_crypto_nft_payload_plugin","import_assert","import_crypto_nft_payload_plugin","import_axios","import_open_zeppelin_typechain","import_open_zeppelin_typechain","ipfsGateway","import_providers","checkIpfsUrl","ipfsGateway"]}
|
package/dist/browser/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/Plugin.ts
|
|
2
|
-
import { NftSchema as
|
|
2
|
+
import { NftSchema as NftSchema3 } from "@xyo-network/crypto-nft-payload-plugin";
|
|
3
3
|
import { PayloadSetSchema } from "@xyo-network/payload-model";
|
|
4
4
|
import { createPayloadSetWitnessPlugin } from "@xyo-network/payloadset-plugin";
|
|
5
5
|
|
|
@@ -9,15 +9,13 @@ import { EthAddress } from "@xylabs/eth-address";
|
|
|
9
9
|
import { AbstractWitness } from "@xyo-network/abstract-witness";
|
|
10
10
|
import {
|
|
11
11
|
isNftWitnessQuery,
|
|
12
|
-
NftSchema,
|
|
12
|
+
NftSchema as NftSchema2,
|
|
13
13
|
NftWitnessConfigSchema
|
|
14
14
|
} from "@xyo-network/crypto-nft-payload-plugin";
|
|
15
15
|
|
|
16
16
|
// src/lib/getNftsOwnedByAddress.ts
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import { toTokenType } from "@xyo-network/crypto-nft-payload-plugin";
|
|
20
|
-
import { ERC721__factory, ERC1155__factory } from "@xyo-network/open-zeppelin-typechain";
|
|
17
|
+
import { AxiosJson as AxiosJson2 } from "@xyo-network/axios";
|
|
18
|
+
import { ERC721__factory, ERC1155__factory as ERC1155__factory2 } from "@xyo-network/open-zeppelin-typechain";
|
|
21
19
|
|
|
22
20
|
// src/lib/getInfuraProvider.ts
|
|
23
21
|
import { InfuraProvider } from "@ethersproject/providers";
|
|
@@ -36,7 +34,57 @@ var getInfuraProviderConfig = () => {
|
|
|
36
34
|
return { projectId, projectSecret };
|
|
37
35
|
};
|
|
38
36
|
|
|
39
|
-
// src/lib/
|
|
37
|
+
// src/lib/getNftFields.ts
|
|
38
|
+
import { AxiosJson } from "@xyo-network/axios";
|
|
39
|
+
import { NftSchema, toTokenType } from "@xyo-network/crypto-nft-payload-plugin";
|
|
40
|
+
import { ERC721URIStorage__factory, ERC1155Supply__factory } from "@xyo-network/open-zeppelin-typechain";
|
|
41
|
+
|
|
42
|
+
// src/lib/getNftCollectionMetadata.ts
|
|
43
|
+
import { ERC721Enumerable__factory, ERC1155__factory } from "@xyo-network/open-zeppelin-typechain";
|
|
44
|
+
import { constants } from "ethers";
|
|
45
|
+
function getInterfaceID(contractInterface) {
|
|
46
|
+
let interfaceID = constants.Zero;
|
|
47
|
+
const functions = Object.keys(contractInterface.functions);
|
|
48
|
+
for (let i = 0; i < functions.length; i++) {
|
|
49
|
+
interfaceID = interfaceID.xor(contractInterface.getSighash(functions[i]));
|
|
50
|
+
}
|
|
51
|
+
return interfaceID.toHexString();
|
|
52
|
+
}
|
|
53
|
+
var getNftCollectionMetadata = async (contractAddress, provider) => {
|
|
54
|
+
try {
|
|
55
|
+
const contract721 = ERC721Enumerable__factory.connect(contractAddress, provider);
|
|
56
|
+
const contract1155 = ERC1155__factory.connect(contractAddress, provider);
|
|
57
|
+
let name = "";
|
|
58
|
+
try {
|
|
59
|
+
name = await contract721.name();
|
|
60
|
+
} catch (ex) {
|
|
61
|
+
const error = ex;
|
|
62
|
+
console.log(`name: ${error.message}`);
|
|
63
|
+
}
|
|
64
|
+
let symbol = "";
|
|
65
|
+
try {
|
|
66
|
+
symbol = await contract721.symbol();
|
|
67
|
+
} catch (ex) {
|
|
68
|
+
const error = ex;
|
|
69
|
+
console.log(`symbol: ${error.message}`);
|
|
70
|
+
}
|
|
71
|
+
let is1155 = false;
|
|
72
|
+
try {
|
|
73
|
+
is1155 = await contract1155.supportsInterface(getInterfaceID(ERC1155__factory.getInterface(ERC1155__factory.abi)));
|
|
74
|
+
} catch (ex) {
|
|
75
|
+
const error = ex;
|
|
76
|
+
console.log(`is1155: ${error.message}`);
|
|
77
|
+
is1155 = false;
|
|
78
|
+
}
|
|
79
|
+
return { address: contractAddress, chainId: provider.network.chainId, name, symbol, type: is1155 ? "ERC1155" : "ERC721" };
|
|
80
|
+
} catch (ex) {
|
|
81
|
+
const error = ex;
|
|
82
|
+
console.error(`getNftCollectionMetadata: ${error.message}`);
|
|
83
|
+
throw ex;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
// src/lib/getNftFields.ts
|
|
40
88
|
var ipfsGateway = "5d7b6582.beta.decentralnetworkservices.com";
|
|
41
89
|
var checkIpfsUrl = (urlToCheck, ipfsGateway2) => {
|
|
42
90
|
const url = new URL(urlToCheck);
|
|
@@ -54,6 +102,78 @@ var checkIpfsUrl = (urlToCheck, ipfsGateway2) => {
|
|
|
54
102
|
return urlToCheck;
|
|
55
103
|
}
|
|
56
104
|
};
|
|
105
|
+
var getNftFields = async (contractAddress, provider, tokenId) => {
|
|
106
|
+
const axios = new AxiosJson({ timeout: 500 });
|
|
107
|
+
const storage = ERC721URIStorage__factory.connect(contractAddress, provider);
|
|
108
|
+
const supply1155 = ERC1155Supply__factory.connect(contractAddress, provider);
|
|
109
|
+
const { type: nftType } = await getNftCollectionMetadata(contractAddress, provider);
|
|
110
|
+
let supply;
|
|
111
|
+
try {
|
|
112
|
+
supply = nftType === toTokenType("ERC1155") ? (await supply1155.totalSupply(tokenId)).toHexString() : "0x01";
|
|
113
|
+
} catch (ex) {
|
|
114
|
+
const error = ex;
|
|
115
|
+
console.error(`supply: ${error.message}`);
|
|
116
|
+
}
|
|
117
|
+
let metaDataUri;
|
|
118
|
+
try {
|
|
119
|
+
metaDataUri = await storage.tokenURI(tokenId);
|
|
120
|
+
} catch (ex) {
|
|
121
|
+
const error = ex;
|
|
122
|
+
console.error(`metaDataUri: ${error.message}`);
|
|
123
|
+
}
|
|
124
|
+
const checkedMetaDataUri = metaDataUri ? checkIpfsUrl(metaDataUri, ipfsGateway) : metaDataUri;
|
|
125
|
+
let metadata = void 0;
|
|
126
|
+
try {
|
|
127
|
+
metadata = checkedMetaDataUri ? (await axios.get(checkedMetaDataUri)).data : void 0;
|
|
128
|
+
} catch (ex) {
|
|
129
|
+
const error = ex;
|
|
130
|
+
console.error(`metadata: ${error.message}`);
|
|
131
|
+
}
|
|
132
|
+
const info = {
|
|
133
|
+
address: contractAddress,
|
|
134
|
+
chainId: provider.network.chainId,
|
|
135
|
+
metaDataUri,
|
|
136
|
+
metadata,
|
|
137
|
+
schema: NftSchema,
|
|
138
|
+
supply: supply ?? "1",
|
|
139
|
+
tokenId,
|
|
140
|
+
type: nftType
|
|
141
|
+
};
|
|
142
|
+
return info;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
// src/lib/getProvider.ts
|
|
146
|
+
import { InfuraProvider as InfuraProvider2, WebSocketProvider } from "@ethersproject/providers";
|
|
147
|
+
var getProviderFromEnv = (chainId = "homestead") => {
|
|
148
|
+
const infuraWssUri = process.env.INFURA_WSS_URI;
|
|
149
|
+
const infuraProvider = new InfuraProvider2("homestead", {
|
|
150
|
+
projectId: process.env.INFURA_PROJECT_ID,
|
|
151
|
+
projectSecret: process.env.INFURA_PROJECT_SECRET
|
|
152
|
+
});
|
|
153
|
+
const infuraWebsocketProvider = infuraWssUri ? new WebSocketProvider(infuraWssUri, chainId) : void 0;
|
|
154
|
+
const quickNodeUri = process.env.QUICKNODE_WSS_URI;
|
|
155
|
+
const quickNodeProvider = quickNodeUri ? new WebSocketProvider(quickNodeUri, chainId) : void 0;
|
|
156
|
+
const provider = infuraWebsocketProvider ?? infuraProvider ?? infuraWebsocketProvider ?? quickNodeProvider ?? infuraProvider;
|
|
157
|
+
return provider;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
// src/lib/getNftsOwnedByAddress.ts
|
|
161
|
+
var checkIpfsUrl2 = (urlToCheck, ipfsGateway2) => {
|
|
162
|
+
const url = new URL(urlToCheck);
|
|
163
|
+
let protocol = url.protocol;
|
|
164
|
+
let host = url.host;
|
|
165
|
+
let path = url.pathname;
|
|
166
|
+
const query = url.search;
|
|
167
|
+
if (protocol === "ipfs:") {
|
|
168
|
+
protocol = "https:";
|
|
169
|
+
host = ipfsGateway2;
|
|
170
|
+
path = url.host === "ipfs" ? `ipfs${path}` : `ipfs/${url.host}${path}`;
|
|
171
|
+
const root = `${protocol}//${host}/${path}`;
|
|
172
|
+
return query?.length > 0 ? `${root}?${query}` : root;
|
|
173
|
+
} else {
|
|
174
|
+
return urlToCheck;
|
|
175
|
+
}
|
|
176
|
+
};
|
|
57
177
|
var getErc721MetadataUri = async (address, tokenId) => {
|
|
58
178
|
try {
|
|
59
179
|
const contract = ERC721__factory.connect(address, getInfuraProvider());
|
|
@@ -64,7 +184,7 @@ var getErc721MetadataUri = async (address, tokenId) => {
|
|
|
64
184
|
};
|
|
65
185
|
var getErc1155MetadataUri = async (address, tokenId) => {
|
|
66
186
|
try {
|
|
67
|
-
const contract =
|
|
187
|
+
const contract = ERC1155__factory2.connect(address, getInfuraProvider());
|
|
68
188
|
return [await contract.uri(tokenId), void 0];
|
|
69
189
|
} catch (ex) {
|
|
70
190
|
return [void 0, ex];
|
|
@@ -75,44 +195,56 @@ var getNftMetadataUri = async (address, tokenId) => {
|
|
|
75
195
|
return results[0][0] ?? results[1][0];
|
|
76
196
|
};
|
|
77
197
|
var getNftsOwnedByAddress = async (publicAddress, chainId, privateKey, maxNfts = 1e3, timeout = 2e3) => {
|
|
78
|
-
const
|
|
198
|
+
const axios = new AxiosJson2();
|
|
79
199
|
const nfts = [];
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
return await Promise.all(
|
|
96
|
-
nfts.map(async (nft) => {
|
|
97
|
-
const metaDataUri = await getNftMetadataUri(nft.address, nft.tokenId);
|
|
98
|
-
if (metaDataUri) {
|
|
99
|
-
nft.metaDataUri = metaDataUri;
|
|
100
|
-
const cookedUri = checkIpfsUrl(metaDataUri, ipfsGateway);
|
|
101
|
-
try {
|
|
102
|
-
nft.metadata = (await axios.get(cookedUri, { timeout }))?.data;
|
|
103
|
-
} catch (ex) {
|
|
104
|
-
console.log(`failed to get NTF metadata [${cookedUri}] [${ex}]`);
|
|
200
|
+
const provider = getProviderFromEnv();
|
|
201
|
+
const qnUri = "https://api.quicknode.com/graphql";
|
|
202
|
+
const result = await axios.post(qnUri, {
|
|
203
|
+
query: `query Query {
|
|
204
|
+
ethereum {
|
|
205
|
+
walletByAddress(address: "${publicAddress}") {
|
|
206
|
+
walletNFTs {
|
|
207
|
+
edges {
|
|
208
|
+
node {
|
|
209
|
+
nft {
|
|
210
|
+
contractAddress
|
|
211
|
+
tokenId
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
105
215
|
}
|
|
106
|
-
} else {
|
|
107
|
-
console.log("failed to get NTF metadata URI");
|
|
108
216
|
}
|
|
109
|
-
|
|
217
|
+
}
|
|
218
|
+
}`,
|
|
219
|
+
variables: {}
|
|
220
|
+
});
|
|
221
|
+
const nftResult = await Promise.all(
|
|
222
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
223
|
+
Object.values(result.data.data.ethereum.walletByAddress.walletNFTs.edges).map(async (nft) => {
|
|
224
|
+
try {
|
|
225
|
+
const { contractAddress, tokenId } = nft.node.nft;
|
|
226
|
+
const { supply, type } = await getNftFields(contractAddress, provider, tokenId);
|
|
227
|
+
const fields = {
|
|
228
|
+
address: contractAddress,
|
|
229
|
+
chainId,
|
|
230
|
+
supply,
|
|
231
|
+
tokenId,
|
|
232
|
+
type
|
|
233
|
+
};
|
|
234
|
+
return fields;
|
|
235
|
+
} catch (ex) {
|
|
236
|
+
const error = ex;
|
|
237
|
+
console.error(`Error: ${error.message}`);
|
|
238
|
+
console.error(`${error.stack}`);
|
|
239
|
+
throw ex;
|
|
240
|
+
}
|
|
110
241
|
})
|
|
111
242
|
);
|
|
243
|
+
return nftResult;
|
|
112
244
|
};
|
|
113
245
|
|
|
114
246
|
// src/Witness.ts
|
|
115
|
-
var schema =
|
|
247
|
+
var schema = NftSchema2;
|
|
116
248
|
var defaultMaxNfts = 100;
|
|
117
249
|
var CryptoWalletNftWitness = class extends AbstractWitness {
|
|
118
250
|
static configSchemas = [NftWitnessConfigSchema];
|
|
@@ -147,7 +279,7 @@ var CryptoWalletNftWitness = class extends AbstractWitness {
|
|
|
147
279
|
|
|
148
280
|
// src/Plugin.ts
|
|
149
281
|
var CryptoWalletNftWitnessPlugin = () => createPayloadSetWitnessPlugin(
|
|
150
|
-
{ required: { [
|
|
282
|
+
{ required: { [NftSchema3]: 1 }, schema: PayloadSetSchema },
|
|
151
283
|
{
|
|
152
284
|
witness: async (params) => {
|
|
153
285
|
const result = await CryptoWalletNftWitness.create(params);
|
|
@@ -161,7 +293,7 @@ var src_default = CryptoWalletNftWitnessPlugin;
|
|
|
161
293
|
export {
|
|
162
294
|
CryptoWalletNftWitness,
|
|
163
295
|
CryptoWalletNftWitnessPlugin,
|
|
164
|
-
checkIpfsUrl,
|
|
296
|
+
checkIpfsUrl2 as checkIpfsUrl,
|
|
165
297
|
src_default as default,
|
|
166
298
|
getErc1155MetadataUri,
|
|
167
299
|
getErc721MetadataUri,
|