@xyo-network/crypto-nft-witness-wallet-plugin 2.78.0 → 2.78.2
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 +174 -35
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.js +173 -34
- 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/getNftMetadata.d.cts +11 -0
- package/dist/browser/lib/getNftMetadata.d.cts.map +1 -0
- package/dist/browser/lib/getNftMetadata.d.mts +11 -0
- package/dist/browser/lib/getNftMetadata.d.mts.map +1 -0
- package/dist/browser/lib/getNftMetadata.d.ts +11 -0
- package/dist/browser/lib/getNftMetadata.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 +174 -36
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +173 -35
- 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/getNftMetadata.d.cts +11 -0
- package/dist/node/lib/getNftMetadata.d.cts.map +1 -0
- package/dist/node/lib/getNftMetadata.d.mts +11 -0
- package/dist/node/lib/getNftMetadata.d.mts.map +1 -0
- package/dist/node/lib/getNftMetadata.d.ts +11 -0
- package/dist/node/lib/getNftMetadata.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/getNftMetadata.ts +79 -0
- package/src/lib/getNftsOwnedByAddress.ts +75 -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,9 @@ 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 import_axios = require("@xyo-network/axios");
|
|
46
|
+
var import_axios2 = require("@xyo-network/axios");
|
|
48
47
|
var import_crypto_nft_payload_plugin = require("@xyo-network/crypto-nft-payload-plugin");
|
|
49
|
-
var
|
|
48
|
+
var import_open_zeppelin_typechain3 = require("@xyo-network/open-zeppelin-typechain");
|
|
50
49
|
|
|
51
50
|
// src/lib/getInfuraProvider.ts
|
|
52
51
|
var import_providers = require("@ethersproject/providers");
|
|
@@ -65,7 +64,54 @@ var getInfuraProviderConfig = () => {
|
|
|
65
64
|
return { projectId, projectSecret };
|
|
66
65
|
};
|
|
67
66
|
|
|
68
|
-
// src/lib/
|
|
67
|
+
// src/lib/getNftCollectionMetadata.ts
|
|
68
|
+
var import_open_zeppelin_typechain = require("@xyo-network/open-zeppelin-typechain");
|
|
69
|
+
var import_ethers = require("ethers");
|
|
70
|
+
function getInterfaceID(contractInterface) {
|
|
71
|
+
let interfaceID = import_ethers.constants.Zero;
|
|
72
|
+
const functions = Object.keys(contractInterface.functions);
|
|
73
|
+
for (let i = 0; i < functions.length; i++) {
|
|
74
|
+
interfaceID = interfaceID.xor(contractInterface.getSighash(functions[i]));
|
|
75
|
+
}
|
|
76
|
+
return interfaceID.toHexString();
|
|
77
|
+
}
|
|
78
|
+
var getNftCollectionMetadata = async (contractAddress, provider) => {
|
|
79
|
+
try {
|
|
80
|
+
const contract721 = import_open_zeppelin_typechain.ERC721Enumerable__factory.connect(contractAddress, provider);
|
|
81
|
+
const contract1155 = import_open_zeppelin_typechain.ERC1155__factory.connect(contractAddress, provider);
|
|
82
|
+
let name = "";
|
|
83
|
+
try {
|
|
84
|
+
name = await contract721.name();
|
|
85
|
+
} catch (ex) {
|
|
86
|
+
const error = ex;
|
|
87
|
+
console.log(`name: ${error.message}`);
|
|
88
|
+
}
|
|
89
|
+
let symbol = "";
|
|
90
|
+
try {
|
|
91
|
+
symbol = await contract721.symbol();
|
|
92
|
+
} catch (ex) {
|
|
93
|
+
const error = ex;
|
|
94
|
+
console.log(`symbol: ${error.message}`);
|
|
95
|
+
}
|
|
96
|
+
let is1155 = false;
|
|
97
|
+
try {
|
|
98
|
+
is1155 = await contract1155.supportsInterface(getInterfaceID(import_open_zeppelin_typechain.ERC1155__factory.getInterface(import_open_zeppelin_typechain.ERC1155__factory.abi)));
|
|
99
|
+
} catch (ex) {
|
|
100
|
+
const error = ex;
|
|
101
|
+
console.log(`is1155: ${error.message}`);
|
|
102
|
+
is1155 = false;
|
|
103
|
+
}
|
|
104
|
+
return { address: contractAddress, chainId: provider.network.chainId, name, symbol, type: is1155 ? "ERC1155" : "ERC721" };
|
|
105
|
+
} catch (ex) {
|
|
106
|
+
const error = ex;
|
|
107
|
+
console.error(`getNftCollectionMetadata: ${error.message}`);
|
|
108
|
+
throw ex;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// src/lib/getNftMetadata.ts
|
|
113
|
+
var import_axios = require("@xyo-network/axios");
|
|
114
|
+
var import_open_zeppelin_typechain2 = require("@xyo-network/open-zeppelin-typechain");
|
|
69
115
|
var ipfsGateway = "5d7b6582.beta.decentralnetworkservices.com";
|
|
70
116
|
var checkIpfsUrl = (urlToCheck, ipfsGateway2) => {
|
|
71
117
|
const url = new URL(urlToCheck);
|
|
@@ -83,9 +129,71 @@ var checkIpfsUrl = (urlToCheck, ipfsGateway2) => {
|
|
|
83
129
|
return urlToCheck;
|
|
84
130
|
}
|
|
85
131
|
};
|
|
132
|
+
var getNftMetadata = async (contractAddress, provider, tokenId) => {
|
|
133
|
+
const axios = new import_axios.AxiosJson({ timeout: 2e3 });
|
|
134
|
+
const storage = import_open_zeppelin_typechain2.ERC721URIStorage__factory.connect(contractAddress, provider);
|
|
135
|
+
const storage1155 = import_open_zeppelin_typechain2.ERC1155URIStorage__factory.connect(contractAddress, provider);
|
|
136
|
+
let uri1155;
|
|
137
|
+
try {
|
|
138
|
+
uri1155 = await storage1155.uri(tokenId);
|
|
139
|
+
} catch (ex) {
|
|
140
|
+
const error = ex;
|
|
141
|
+
console.error(`metaDataUri: ${error.message}`);
|
|
142
|
+
}
|
|
143
|
+
let metadataUri;
|
|
144
|
+
try {
|
|
145
|
+
metadataUri = await storage.tokenURI(tokenId);
|
|
146
|
+
} catch (ex) {
|
|
147
|
+
const error = ex;
|
|
148
|
+
console.error(`metadataUri: ${error.message}`);
|
|
149
|
+
}
|
|
150
|
+
const tokenMetadataUri = metadataUri ?? uri1155;
|
|
151
|
+
const checkedMetaDataUri = tokenMetadataUri ? checkIpfsUrl(tokenMetadataUri, ipfsGateway) : tokenMetadataUri;
|
|
152
|
+
let metadata = void 0;
|
|
153
|
+
try {
|
|
154
|
+
metadata = checkedMetaDataUri ? (await axios.get(checkedMetaDataUri)).data : void 0;
|
|
155
|
+
} catch (ex) {
|
|
156
|
+
const error = ex;
|
|
157
|
+
console.error(`metadata: ${error.message}`);
|
|
158
|
+
}
|
|
159
|
+
return [tokenMetadataUri, metadata];
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
// src/lib/getProvider.ts
|
|
163
|
+
var import_providers2 = require("@ethersproject/providers");
|
|
164
|
+
var getProviderFromEnv = (chainId = "homestead") => {
|
|
165
|
+
const infuraWssUri = process.env.INFURA_WSS_URI;
|
|
166
|
+
const infuraProvider = new import_providers2.InfuraProvider("homestead", {
|
|
167
|
+
projectId: process.env.INFURA_PROJECT_ID,
|
|
168
|
+
projectSecret: process.env.INFURA_PROJECT_SECRET
|
|
169
|
+
});
|
|
170
|
+
const infuraWebsocketProvider = infuraWssUri ? new import_providers2.WebSocketProvider(infuraWssUri, chainId) : void 0;
|
|
171
|
+
const quickNodeUri = process.env.QUICKNODE_WSS_URI;
|
|
172
|
+
const quickNodeProvider = quickNodeUri ? new import_providers2.WebSocketProvider(quickNodeUri, chainId) : void 0;
|
|
173
|
+
const provider = infuraWebsocketProvider ?? infuraProvider ?? infuraWebsocketProvider ?? quickNodeProvider ?? infuraProvider;
|
|
174
|
+
return provider;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
// src/lib/getNftsOwnedByAddress.ts
|
|
178
|
+
var checkIpfsUrl2 = (urlToCheck, ipfsGateway2) => {
|
|
179
|
+
const url = new URL(urlToCheck);
|
|
180
|
+
let protocol = url.protocol;
|
|
181
|
+
let host = url.host;
|
|
182
|
+
let path = url.pathname;
|
|
183
|
+
const query = url.search;
|
|
184
|
+
if (protocol === "ipfs:") {
|
|
185
|
+
protocol = "https:";
|
|
186
|
+
host = ipfsGateway2;
|
|
187
|
+
path = url.host === "ipfs" ? `ipfs${path}` : `ipfs/${url.host}${path}`;
|
|
188
|
+
const root = `${protocol}//${host}/${path}`;
|
|
189
|
+
return query?.length > 0 ? `${root}?${query}` : root;
|
|
190
|
+
} else {
|
|
191
|
+
return urlToCheck;
|
|
192
|
+
}
|
|
193
|
+
};
|
|
86
194
|
var getErc721MetadataUri = async (address, tokenId) => {
|
|
87
195
|
try {
|
|
88
|
-
const contract =
|
|
196
|
+
const contract = import_open_zeppelin_typechain3.ERC721__factory.connect(address, getInfuraProvider());
|
|
89
197
|
return [await contract.tokenURI(tokenId), void 0];
|
|
90
198
|
} catch (ex) {
|
|
91
199
|
return [void 0, ex];
|
|
@@ -93,7 +201,7 @@ var getErc721MetadataUri = async (address, tokenId) => {
|
|
|
93
201
|
};
|
|
94
202
|
var getErc1155MetadataUri = async (address, tokenId) => {
|
|
95
203
|
try {
|
|
96
|
-
const contract =
|
|
204
|
+
const contract = import_open_zeppelin_typechain3.ERC1155__factory.connect(address, getInfuraProvider());
|
|
97
205
|
return [await contract.uri(tokenId), void 0];
|
|
98
206
|
} catch (ex) {
|
|
99
207
|
return [void 0, ex];
|
|
@@ -104,40 +212,71 @@ var getNftMetadataUri = async (address, tokenId) => {
|
|
|
104
212
|
return results[0][0] ?? results[1][0];
|
|
105
213
|
};
|
|
106
214
|
var getNftsOwnedByAddress = async (publicAddress, chainId, privateKey, maxNfts = 1e3, timeout = 2e3) => {
|
|
107
|
-
const
|
|
108
|
-
const
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
215
|
+
const axios = new import_axios2.AxiosJson({ timeout });
|
|
216
|
+
const provider = getProviderFromEnv();
|
|
217
|
+
const qnUri = "https://api.quicknode.com/graphql";
|
|
218
|
+
const result = await axios.post(qnUri, {
|
|
219
|
+
query: `query Query {
|
|
220
|
+
ethereum {
|
|
221
|
+
walletByAddress(address: "${publicAddress}") {
|
|
222
|
+
walletNFTs (first: ${maxNfts}) {
|
|
223
|
+
edges {
|
|
224
|
+
node {
|
|
225
|
+
nft {
|
|
226
|
+
contractAddress
|
|
227
|
+
metadata
|
|
228
|
+
tokenId
|
|
229
|
+
externalUrl
|
|
230
|
+
name
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}`,
|
|
238
|
+
variables: {}
|
|
239
|
+
});
|
|
240
|
+
const nftResult = await Promise.all(
|
|
241
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
242
|
+
Object.values(result.data.data.ethereum.walletByAddress.walletNFTs.edges).map(async (nft) => {
|
|
243
|
+
try {
|
|
244
|
+
const { contractAddress, tokenId, metadata, externalUrl } = nft.node.nft;
|
|
245
|
+
let supply = "0x01";
|
|
246
|
+
let type = (0, import_crypto_nft_payload_plugin.toTokenType)("ERC721");
|
|
130
247
|
try {
|
|
131
|
-
|
|
248
|
+
const supply1155 = import_open_zeppelin_typechain3.ERC1155Supply__factory.connect(contractAddress, provider);
|
|
249
|
+
const { type: nftType } = await getNftCollectionMetadata(contractAddress, provider);
|
|
250
|
+
type = nftType;
|
|
251
|
+
supply = nftType === (0, import_crypto_nft_payload_plugin.toTokenType)("ERC1155") ? (await supply1155.totalSupply(tokenId)).toHexString() : "0x01";
|
|
132
252
|
} catch (ex) {
|
|
133
|
-
|
|
253
|
+
const error = ex;
|
|
254
|
+
console.error(`supply: ${error.message}`);
|
|
255
|
+
}
|
|
256
|
+
const fields = {
|
|
257
|
+
address: contractAddress,
|
|
258
|
+
chainId,
|
|
259
|
+
metadata,
|
|
260
|
+
metadataUri: externalUrl,
|
|
261
|
+
supply,
|
|
262
|
+
tokenId,
|
|
263
|
+
type
|
|
264
|
+
};
|
|
265
|
+
if (!fields.metadataUri || !fields.metadata) {
|
|
266
|
+
const [metadataUri, metadata2] = await getNftMetadata(contractAddress, provider, fields.tokenId);
|
|
267
|
+
fields.metadata = metadata2;
|
|
268
|
+
fields.metadataUri = metadataUri;
|
|
134
269
|
}
|
|
135
|
-
|
|
136
|
-
|
|
270
|
+
return fields;
|
|
271
|
+
} catch (ex) {
|
|
272
|
+
const error = ex;
|
|
273
|
+
console.error(`Error: ${error.message}`);
|
|
274
|
+
console.error(`${error.stack}`);
|
|
275
|
+
throw ex;
|
|
137
276
|
}
|
|
138
|
-
return nft;
|
|
139
277
|
})
|
|
140
278
|
);
|
|
279
|
+
return nftResult;
|
|
141
280
|
};
|
|
142
281
|
|
|
143
282
|
// 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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,oCAA0B;AAC1B,2BAAiC;AACjC,+BAA8C;;;ACF9C,IAAAC,iBAAyB;AACzB,yBAA2B;AAC3B,8BAAgC;AAChC,IAAAC,oCAOO;;;ACVP,iBAA0B;AAC1B,mBAA0B;AAC1B,uCAA2C;AAC3C,qCAAkD;;;ACHlD,uBAAyC;AACzC,oBAAyB;AAOzB,IAAI,WAAuC;AAEpC,IAAM,oBAAoB,MAAgB;AAC/C,MAAI;AAAU,WAAO;AACrB,QAAM,SAAS,wBAAwB;AACvC,aAAW,IAAI,gCAAe,aAAa,MAAM;AACjD,SAAO;AACT;AAMO,IAAM,0BAA0B,MAA4B;AACjE,QAAM,gBAAY,wBAAS,QAAQ,IAAI,mBAAmB,mCAAmC;AAC7F,QAAM,oBAAgB,wBAAS,QAAQ,IAAI,uBAAuB,uCAAuC;AACzG,SAAO,EAAE,WAAW,cAAc;AACpC;;;ADXA,IAAM,cAAc;AAQb,IAAM,eAAe,CAAC,YAAoBC,iBAAwB;AACvE,QAAM,MAAM,IAAI,IAAI,UAAU;AAC9B,MAAI,WAAW,IAAI;AACnB,MAAI,OAAO,IAAI;AACf,MAAI,OAAO,IAAI;AACf,QAAM,QAAQ,IAAI;AAClB,MAAI,aAAa,SAAS;AACxB,eAAW;AACX,WAAOA;AACP,WAAO,IAAI,SAAS,SAAS,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,GAAG,IAAI;AACpE,UAAM,OAAO,GAAG,QAAQ,KAAK,IAAI,IAAI,IAAI;AACzC,WAAO,OAAO,SAAS,IAAI,GAAG,IAAI,IAAI,KAAK,KAAK;AAAA,EAClD,OAAO;AACL,WAAO;AAAA,EACT;AACF;AAEO,IAAM,uBAAuB,OAAO,SAAiB,YAAsE;AAChI,MAAI;AACF,UAAM,WAAW,+CAAgB,QAAQ,SAAS,kBAAkB,CAAC;AACrE,WAAO,CAAC,MAAM,SAAS,SAAS,OAAO,GAAG,MAAS;AAAA,EACrD,SAAS,IAAI;AACX,WAAO,CAAC,QAAW,EAAW;AAAA,EAChC;AACF;AAEO,IAAM,wBAAwB,OAAO,SAAiB,YAAsE;AACjI,MAAI;AACF,UAAM,WAAW,gDAAiB,QAAQ,SAAS,kBAAkB,CAAC;AACtE,WAAO,CAAC,MAAM,SAAS,IAAI,OAAO,GAAG,MAAS;AAAA,EAChD,SAAS,IAAI;AACX,WAAO,CAAC,QAAW,EAAW;AAAA,EAChC;AACF;AAEO,IAAM,oBAAoB,OAAO,SAAiB,YAAoB;AAC3E,QAAM,UAAU,MAAM,QAAQ,IAAI,CAAC,qBAAqB,SAAS,OAAO,GAAG,sBAAsB,SAAS,OAAO,CAAC,CAAC;AACnH,SAAO,QAAQ,CAAC,EAAE,CAAC,KAAK,QAAQ,CAAC,EAAE,CAAC;AACtC;AAEO,IAAM,wBAAwB,OAEnC,eAEA,SAEA,YAEA,UAAU,KAEV,UAAU,QACmB;AAC7B,QAAM,MAAM,IAAI,eAAI,IAAI,gBAAK,EAAE,SAAS,YAAY,WAAW,QAAQ,IAAI,mBAAmB,UAAU,QAAQ,IAAI,sBAAsB,CAAC,CAAC;AAC5I,QAAM,OAAwB,CAAC;AAC/B,QAAM,QAAQ,IAAI,uBAAU;AAC5B,MAAI,SAA6B;AACjC,KAAG;AACD,UAAM,OAA6B,EAAE,QAAQ,iBAAiB,MAAM,cAAc;AAClF,UAAM,EAAE,QAAQ,YAAY,UAAU,OAAO,OAAO,IAAI,MAAM,IAAI,IAAI,QAAQ,IAAI;AAClF,UAAM,QAAyB,OAAO,MAAM,GAAG,KAAK,IAAI,UAAU,QAAQ,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,UAAU;AACrG,YAAM,EAAE,UAAU,SAAS,MAAM,WAAW,GAAG,KAAK,IAAI;AACxD,YAAM,WAAO,8CAAY,SAAS;AAClC,aAAO,EAAE,SAAS,SAAS,MAAM,GAAG,KAAK;AAAA,IAC3C,CAAC;AACD,SAAK,KAAK,GAAG,KAAK;AAClB,aAAS;AACT,QAAI,KAAK,UAAU,SAAS,CAAC;AAAQ;AAAA,EACvC,SAAS,KAAK,SAAS;AAEvB,SAAO,MAAM,QAAQ;AAAA,IACnB,KAAK,IAAI,OAAO,QAAQ;AACtB,YAAM,cAAc,MAAM,kBAAkB,IAAI,SAAS,IAAI,OAAO;AACpE,UAAI,aAAa;AACf,YAAI,cAAc;AAClB,cAAM,YAAY,aAAa,aAAa,WAAW;AACvD,YAAI;AACF,cAAI,YAAY,MAAM,MAAM,IAAI,WAAW,EAAE,QAAQ,CAAC,IAAI;AAAA,QAC5D,SAAS,IAAI;AACX,kBAAQ,IAAI,+BAA+B,SAAS,MAAM,EAAE,GAAG;AAAA,QACjE;AAAA,MACF,OAAO;AACL,gBAAQ,IAAI,gCAAgC;AAAA,MAC9C;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AACF;;;AD1FA,IAAM,SAAS;AAEf,IAAM,iBAAiB;AAEhB,IAAM,yBAAN,cAAkH,wCAIvH;AAAA,EACA,OAAgB,gBAAgB,CAAC,wDAAsB;AAAA,EAEvD,IAAI,UAAU;AACZ,WAAO,KAAK,OAAO,WAAW;AAAA,EAChC;AAAA,EAEA,MAAyB,eAAe,UAAkD;AACxF,UAAM,KAAK,QAAQ,OAAO;AAC1B,UAAM,UAAU,UAAU,OAAO,mDAAiB,KAAK,CAAC;AACxD,UAAM,eAAe,MAAM,QAAQ;AAAA,MACjC,QAAQ,IAAI,OAAO,UAAU;AAC3B,cAAM,cAAU;AAAA,UACd,8BAAW,UAAM,yBAAS,OAAO,WAAW,KAAK,OAAO,SAAS,4BAA4B,CAAC;AAAA,UAC9F;AAAA,QACF,EAAE,SAAS;AACX,cAAM,cAAU,yBAAS,OAAO,WAAW,KAAK,OAAO,SAAS,4BAA4B;AAC5F,cAAM,UAAU,OAAO,WAAW;AAClC,YAAI;AACF,gBAAM,OAAO,MAAM,sBAAsB,SAAS,SAAS,KAAK,QAAQ,QAAQ,KAAK,SAAS,KAAK,OAAO;AAC1G,gBAAM,cAAc,KAAK,IAAa,CAAC,QAAQ;AAC7C,mBAAO,EAAE,GAAG,KAAK,OAAO;AAAA,UAC1B,CAAC;AACD,iBAAO;AAAA,QACT,SAAS,OAAO;AACd,gBAAM,IAAI,MAAM,kCAAkC,OAAO,eAAe,OAAO,EAAE;AAAA,QACnF;AAAA,MACF,CAAC;AAAA,IACH;AACA,WAAO,aAAa,KAAK;AAAA,EAC3B;AACF;;;ADnDO,IAAM,+BAA+B,UAC1C;AAAA,EACE,EAAE,UAAU,EAAE,CAAC,2CAAS,GAAG,EAAE,GAAG,QAAQ,sCAAiB;AAAA,EACzD;AAAA,IACE,SAAS,OAAO,WAAW;AACzB,YAAM,SAAS,MAAM,uBAAuB,OAAO,MAAM;AACzD,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;ADPF,IAAO,cAAQ;","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/getNftCollectionMetadata.ts","../../src/lib/getNftMetadata.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, NftMetadata, toTokenType } from '@xyo-network/crypto-nft-payload-plugin'\nimport { ERC721__factory, ERC1155__factory, ERC1155Supply__factory } from '@xyo-network/open-zeppelin-typechain'\n\nimport { getInfuraProvider } from './getInfuraProvider'\nimport { getNftCollectionMetadata } from './getNftCollectionMetadata'\nimport { getNftMetadata } from './getNftMetadata'\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 externalUrl: string\n metadata: NftMetadata\n name: 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({ timeout })\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 (first: ${maxNfts}) {\n edges {\n node {\n nft {\n contractAddress\n metadata\n tokenId\n externalUrl\n name\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, metadata, externalUrl } = nft.node.nft as QuickNodeNft\n let supply = '0x01'\n let type = toTokenType('ERC721')\n try {\n const supply1155 = ERC1155Supply__factory.connect(contractAddress, provider)\n const { type: nftType } = await getNftCollectionMetadata(contractAddress, provider)\n type = nftType\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 const fields: NftInfoFields = {\n address: contractAddress,\n chainId,\n metadata,\n metadataUri: externalUrl,\n supply,\n tokenId,\n type,\n }\n if (!fields.metadataUri || !fields.metadata) {\n const [metadataUri, metadata] = await getNftMetadata(contractAddress, provider, fields.tokenId)\n fields.metadata = metadata\n fields.metadataUri = metadataUri\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 { 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 { JsonRpcProvider } from '@ethersproject/providers'\nimport { AxiosJson } from '@xyo-network/axios'\nimport { NftMetadata } from '@xyo-network/crypto-nft-payload-plugin'\nimport { ERC721URIStorage__factory, ERC1155URIStorage__factory } from '@xyo-network/open-zeppelin-typechain'\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 getNftMetadata = 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<[string | undefined, NftMetadata | undefined]> => {\n const axios = new AxiosJson({ timeout: 2000 })\n const storage = ERC721URIStorage__factory.connect(contractAddress, provider)\n const storage1155 = ERC1155URIStorage__factory.connect(contractAddress, provider)\n\n let uri1155: string | undefined\n try {\n uri1155 = await storage1155.uri(tokenId)\n } catch (ex) {\n const error = ex as Error\n console.error(`metaDataUri: ${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 tokenMetadataUri = metadataUri ?? uri1155\n\n const checkedMetaDataUri = tokenMetadataUri ? checkIpfsUrl(tokenMetadataUri, ipfsGateway) : tokenMetadataUri\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 return [tokenMetadataUri, metadata]\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","metadata"]}
|
package/dist/browser/index.js
CHANGED
|
@@ -14,10 +14,9 @@ import {
|
|
|
14
14
|
} from "@xyo-network/crypto-nft-payload-plugin";
|
|
15
15
|
|
|
16
16
|
// src/lib/getNftsOwnedByAddress.ts
|
|
17
|
-
import {
|
|
18
|
-
import { AxiosJson } from "@xyo-network/axios";
|
|
17
|
+
import { AxiosJson as AxiosJson2 } from "@xyo-network/axios";
|
|
19
18
|
import { toTokenType } from "@xyo-network/crypto-nft-payload-plugin";
|
|
20
|
-
import { ERC721__factory, ERC1155__factory } from "@xyo-network/open-zeppelin-typechain";
|
|
19
|
+
import { ERC721__factory, ERC1155__factory as ERC1155__factory2, ERC1155Supply__factory } from "@xyo-network/open-zeppelin-typechain";
|
|
21
20
|
|
|
22
21
|
// src/lib/getInfuraProvider.ts
|
|
23
22
|
import { InfuraProvider } from "@ethersproject/providers";
|
|
@@ -36,7 +35,54 @@ var getInfuraProviderConfig = () => {
|
|
|
36
35
|
return { projectId, projectSecret };
|
|
37
36
|
};
|
|
38
37
|
|
|
39
|
-
// src/lib/
|
|
38
|
+
// src/lib/getNftCollectionMetadata.ts
|
|
39
|
+
import { ERC721Enumerable__factory, ERC1155__factory } from "@xyo-network/open-zeppelin-typechain";
|
|
40
|
+
import { constants } from "ethers";
|
|
41
|
+
function getInterfaceID(contractInterface) {
|
|
42
|
+
let interfaceID = constants.Zero;
|
|
43
|
+
const functions = Object.keys(contractInterface.functions);
|
|
44
|
+
for (let i = 0; i < functions.length; i++) {
|
|
45
|
+
interfaceID = interfaceID.xor(contractInterface.getSighash(functions[i]));
|
|
46
|
+
}
|
|
47
|
+
return interfaceID.toHexString();
|
|
48
|
+
}
|
|
49
|
+
var getNftCollectionMetadata = async (contractAddress, provider) => {
|
|
50
|
+
try {
|
|
51
|
+
const contract721 = ERC721Enumerable__factory.connect(contractAddress, provider);
|
|
52
|
+
const contract1155 = ERC1155__factory.connect(contractAddress, provider);
|
|
53
|
+
let name = "";
|
|
54
|
+
try {
|
|
55
|
+
name = await contract721.name();
|
|
56
|
+
} catch (ex) {
|
|
57
|
+
const error = ex;
|
|
58
|
+
console.log(`name: ${error.message}`);
|
|
59
|
+
}
|
|
60
|
+
let symbol = "";
|
|
61
|
+
try {
|
|
62
|
+
symbol = await contract721.symbol();
|
|
63
|
+
} catch (ex) {
|
|
64
|
+
const error = ex;
|
|
65
|
+
console.log(`symbol: ${error.message}`);
|
|
66
|
+
}
|
|
67
|
+
let is1155 = false;
|
|
68
|
+
try {
|
|
69
|
+
is1155 = await contract1155.supportsInterface(getInterfaceID(ERC1155__factory.getInterface(ERC1155__factory.abi)));
|
|
70
|
+
} catch (ex) {
|
|
71
|
+
const error = ex;
|
|
72
|
+
console.log(`is1155: ${error.message}`);
|
|
73
|
+
is1155 = false;
|
|
74
|
+
}
|
|
75
|
+
return { address: contractAddress, chainId: provider.network.chainId, name, symbol, type: is1155 ? "ERC1155" : "ERC721" };
|
|
76
|
+
} catch (ex) {
|
|
77
|
+
const error = ex;
|
|
78
|
+
console.error(`getNftCollectionMetadata: ${error.message}`);
|
|
79
|
+
throw ex;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// src/lib/getNftMetadata.ts
|
|
84
|
+
import { AxiosJson } from "@xyo-network/axios";
|
|
85
|
+
import { ERC721URIStorage__factory, ERC1155URIStorage__factory } from "@xyo-network/open-zeppelin-typechain";
|
|
40
86
|
var ipfsGateway = "5d7b6582.beta.decentralnetworkservices.com";
|
|
41
87
|
var checkIpfsUrl = (urlToCheck, ipfsGateway2) => {
|
|
42
88
|
const url = new URL(urlToCheck);
|
|
@@ -54,6 +100,68 @@ var checkIpfsUrl = (urlToCheck, ipfsGateway2) => {
|
|
|
54
100
|
return urlToCheck;
|
|
55
101
|
}
|
|
56
102
|
};
|
|
103
|
+
var getNftMetadata = async (contractAddress, provider, tokenId) => {
|
|
104
|
+
const axios = new AxiosJson({ timeout: 2e3 });
|
|
105
|
+
const storage = ERC721URIStorage__factory.connect(contractAddress, provider);
|
|
106
|
+
const storage1155 = ERC1155URIStorage__factory.connect(contractAddress, provider);
|
|
107
|
+
let uri1155;
|
|
108
|
+
try {
|
|
109
|
+
uri1155 = await storage1155.uri(tokenId);
|
|
110
|
+
} catch (ex) {
|
|
111
|
+
const error = ex;
|
|
112
|
+
console.error(`metaDataUri: ${error.message}`);
|
|
113
|
+
}
|
|
114
|
+
let metadataUri;
|
|
115
|
+
try {
|
|
116
|
+
metadataUri = await storage.tokenURI(tokenId);
|
|
117
|
+
} catch (ex) {
|
|
118
|
+
const error = ex;
|
|
119
|
+
console.error(`metadataUri: ${error.message}`);
|
|
120
|
+
}
|
|
121
|
+
const tokenMetadataUri = metadataUri ?? uri1155;
|
|
122
|
+
const checkedMetaDataUri = tokenMetadataUri ? checkIpfsUrl(tokenMetadataUri, ipfsGateway) : tokenMetadataUri;
|
|
123
|
+
let metadata = void 0;
|
|
124
|
+
try {
|
|
125
|
+
metadata = checkedMetaDataUri ? (await axios.get(checkedMetaDataUri)).data : void 0;
|
|
126
|
+
} catch (ex) {
|
|
127
|
+
const error = ex;
|
|
128
|
+
console.error(`metadata: ${error.message}`);
|
|
129
|
+
}
|
|
130
|
+
return [tokenMetadataUri, metadata];
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// src/lib/getProvider.ts
|
|
134
|
+
import { InfuraProvider as InfuraProvider2, WebSocketProvider } from "@ethersproject/providers";
|
|
135
|
+
var getProviderFromEnv = (chainId = "homestead") => {
|
|
136
|
+
const infuraWssUri = process.env.INFURA_WSS_URI;
|
|
137
|
+
const infuraProvider = new InfuraProvider2("homestead", {
|
|
138
|
+
projectId: process.env.INFURA_PROJECT_ID,
|
|
139
|
+
projectSecret: process.env.INFURA_PROJECT_SECRET
|
|
140
|
+
});
|
|
141
|
+
const infuraWebsocketProvider = infuraWssUri ? new WebSocketProvider(infuraWssUri, chainId) : void 0;
|
|
142
|
+
const quickNodeUri = process.env.QUICKNODE_WSS_URI;
|
|
143
|
+
const quickNodeProvider = quickNodeUri ? new WebSocketProvider(quickNodeUri, chainId) : void 0;
|
|
144
|
+
const provider = infuraWebsocketProvider ?? infuraProvider ?? infuraWebsocketProvider ?? quickNodeProvider ?? infuraProvider;
|
|
145
|
+
return provider;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
// src/lib/getNftsOwnedByAddress.ts
|
|
149
|
+
var checkIpfsUrl2 = (urlToCheck, ipfsGateway2) => {
|
|
150
|
+
const url = new URL(urlToCheck);
|
|
151
|
+
let protocol = url.protocol;
|
|
152
|
+
let host = url.host;
|
|
153
|
+
let path = url.pathname;
|
|
154
|
+
const query = url.search;
|
|
155
|
+
if (protocol === "ipfs:") {
|
|
156
|
+
protocol = "https:";
|
|
157
|
+
host = ipfsGateway2;
|
|
158
|
+
path = url.host === "ipfs" ? `ipfs${path}` : `ipfs/${url.host}${path}`;
|
|
159
|
+
const root = `${protocol}//${host}/${path}`;
|
|
160
|
+
return query?.length > 0 ? `${root}?${query}` : root;
|
|
161
|
+
} else {
|
|
162
|
+
return urlToCheck;
|
|
163
|
+
}
|
|
164
|
+
};
|
|
57
165
|
var getErc721MetadataUri = async (address, tokenId) => {
|
|
58
166
|
try {
|
|
59
167
|
const contract = ERC721__factory.connect(address, getInfuraProvider());
|
|
@@ -64,7 +172,7 @@ var getErc721MetadataUri = async (address, tokenId) => {
|
|
|
64
172
|
};
|
|
65
173
|
var getErc1155MetadataUri = async (address, tokenId) => {
|
|
66
174
|
try {
|
|
67
|
-
const contract =
|
|
175
|
+
const contract = ERC1155__factory2.connect(address, getInfuraProvider());
|
|
68
176
|
return [await contract.uri(tokenId), void 0];
|
|
69
177
|
} catch (ex) {
|
|
70
178
|
return [void 0, ex];
|
|
@@ -75,40 +183,71 @@ var getNftMetadataUri = async (address, tokenId) => {
|
|
|
75
183
|
return results[0][0] ?? results[1][0];
|
|
76
184
|
};
|
|
77
185
|
var getNftsOwnedByAddress = async (publicAddress, chainId, privateKey, maxNfts = 1e3, timeout = 2e3) => {
|
|
78
|
-
const
|
|
79
|
-
const
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
186
|
+
const axios = new AxiosJson2({ timeout });
|
|
187
|
+
const provider = getProviderFromEnv();
|
|
188
|
+
const qnUri = "https://api.quicknode.com/graphql";
|
|
189
|
+
const result = await axios.post(qnUri, {
|
|
190
|
+
query: `query Query {
|
|
191
|
+
ethereum {
|
|
192
|
+
walletByAddress(address: "${publicAddress}") {
|
|
193
|
+
walletNFTs (first: ${maxNfts}) {
|
|
194
|
+
edges {
|
|
195
|
+
node {
|
|
196
|
+
nft {
|
|
197
|
+
contractAddress
|
|
198
|
+
metadata
|
|
199
|
+
tokenId
|
|
200
|
+
externalUrl
|
|
201
|
+
name
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}`,
|
|
209
|
+
variables: {}
|
|
210
|
+
});
|
|
211
|
+
const nftResult = await Promise.all(
|
|
212
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
213
|
+
Object.values(result.data.data.ethereum.walletByAddress.walletNFTs.edges).map(async (nft) => {
|
|
214
|
+
try {
|
|
215
|
+
const { contractAddress, tokenId, metadata, externalUrl } = nft.node.nft;
|
|
216
|
+
let supply = "0x01";
|
|
217
|
+
let type = toTokenType("ERC721");
|
|
101
218
|
try {
|
|
102
|
-
|
|
219
|
+
const supply1155 = ERC1155Supply__factory.connect(contractAddress, provider);
|
|
220
|
+
const { type: nftType } = await getNftCollectionMetadata(contractAddress, provider);
|
|
221
|
+
type = nftType;
|
|
222
|
+
supply = nftType === toTokenType("ERC1155") ? (await supply1155.totalSupply(tokenId)).toHexString() : "0x01";
|
|
103
223
|
} catch (ex) {
|
|
104
|
-
|
|
224
|
+
const error = ex;
|
|
225
|
+
console.error(`supply: ${error.message}`);
|
|
226
|
+
}
|
|
227
|
+
const fields = {
|
|
228
|
+
address: contractAddress,
|
|
229
|
+
chainId,
|
|
230
|
+
metadata,
|
|
231
|
+
metadataUri: externalUrl,
|
|
232
|
+
supply,
|
|
233
|
+
tokenId,
|
|
234
|
+
type
|
|
235
|
+
};
|
|
236
|
+
if (!fields.metadataUri || !fields.metadata) {
|
|
237
|
+
const [metadataUri, metadata2] = await getNftMetadata(contractAddress, provider, fields.tokenId);
|
|
238
|
+
fields.metadata = metadata2;
|
|
239
|
+
fields.metadataUri = metadataUri;
|
|
105
240
|
}
|
|
106
|
-
|
|
107
|
-
|
|
241
|
+
return fields;
|
|
242
|
+
} catch (ex) {
|
|
243
|
+
const error = ex;
|
|
244
|
+
console.error(`Error: ${error.message}`);
|
|
245
|
+
console.error(`${error.stack}`);
|
|
246
|
+
throw ex;
|
|
108
247
|
}
|
|
109
|
-
return nft;
|
|
110
248
|
})
|
|
111
249
|
);
|
|
250
|
+
return nftResult;
|
|
112
251
|
};
|
|
113
252
|
|
|
114
253
|
// src/Witness.ts
|
|
@@ -161,7 +300,7 @@ var src_default = CryptoWalletNftWitnessPlugin;
|
|
|
161
300
|
export {
|
|
162
301
|
CryptoWalletNftWitness,
|
|
163
302
|
CryptoWalletNftWitnessPlugin,
|
|
164
|
-
checkIpfsUrl,
|
|
303
|
+
checkIpfsUrl2 as checkIpfsUrl,
|
|
165
304
|
src_default as default,
|
|
166
305
|
getErc1155MetadataUri,
|
|
167
306
|
getErc721MetadataUri,
|