@quicknode/sdk 1.0.0 → 1.1.0

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.
Files changed (65) hide show
  1. package/README.md +2 -0
  2. package/cjs/index.js +314 -1
  3. package/esm/package.json +2 -1
  4. package/esm/package.json.js +3 -0
  5. package/esm/src/api/api.js +85 -0
  6. package/esm/src/api/controllers/contracts.js +36 -0
  7. package/esm/src/api/controllers/events.js +121 -0
  8. package/esm/src/api/controllers/nfts.js +244 -0
  9. package/esm/src/api/controllers/tokens.js +98 -0
  10. package/esm/src/api/controllers/transactions.js +125 -0
  11. package/esm/src/api/controllers/utils.js +55 -0
  12. package/esm/src/api/graphql/customUrqlClient.js +23 -0
  13. package/esm/{index.js → src/api/graphql/generatedTypes.js} +1 -1099
  14. package/esm/src/api/graphql/schema.json.js +3 -0
  15. package/esm/src/api/index.d.ts +2687 -0
  16. package/esm/src/api/index.js +2 -0
  17. package/esm/src/api/types/chains.js +7 -0
  18. package/esm/src/api/types/contracts/getContractDetails.js +12 -0
  19. package/esm/src/api/types/events/getAll.js +7 -0
  20. package/esm/src/api/types/events/getByContract.js +12 -0
  21. package/esm/src/api/types/nfts/getByContractAddress.js +10 -0
  22. package/esm/src/api/types/nfts/getByWalletAddress.js +18 -0
  23. package/esm/src/api/types/nfts/getCollectionDetails.js +11 -0
  24. package/esm/src/api/types/nfts/getCollectionEvents.js +12 -0
  25. package/esm/src/api/types/nfts/getNFTDetails.js +9 -0
  26. package/esm/src/api/types/nfts/getNFTEvents.js +13 -0
  27. package/esm/src/api/types/nfts/getTrendingCollections.js +7 -0
  28. package/esm/src/api/types/nfts/verifyOwnershipByAddress.js +12 -0
  29. package/esm/src/api/types/tokens/getBalancesByWalletAddress.js +12 -0
  30. package/esm/src/api/types/transactions/getByHash.js +11 -0
  31. package/esm/src/api/types/transactions/getBySearch.js +7 -0
  32. package/esm/src/api/types/utils/gasPrices.js +12 -0
  33. package/esm/src/api/utils/constants.js +3 -0
  34. package/esm/src/api/utils/helpers.js +11 -0
  35. package/esm/src/api/utils/isValidENSAddress.js +21 -0
  36. package/esm/src/api/utils/postQueryFormatter.js +24 -0
  37. package/esm/src/api/utils/removeNodesAndEdges.js +51 -0
  38. package/esm/src/client/client.js +9 -0
  39. package/esm/src/client/index.js +2 -0
  40. package/esm/src/core/addOns/nftTokenV2/actions.js +107 -0
  41. package/esm/src/core/addOns/nftTokenV2/types/qn_fetchNFTCollectionDetails.js +10 -0
  42. package/esm/src/core/addOns/nftTokenV2/types/qn_fetchNFTs.js +13 -0
  43. package/esm/src/core/addOns/nftTokenV2/types/qn_fetchNFTsByCollection.js +13 -0
  44. package/esm/src/core/addOns/nftTokenV2/types/qn_getTokenMetadataByContractAddress.js +10 -0
  45. package/esm/src/core/addOns/nftTokenV2/types/qn_getTokenMetadataBySymbol.js +11 -0
  46. package/esm/src/core/addOns/nftTokenV2/types/qn_getTransactionsByAddress.js +18 -0
  47. package/esm/src/core/addOns/nftTokenV2/types/qn_getTransfersByNFT.js +12 -0
  48. package/esm/src/core/addOns/nftTokenV2/types/qn_getWalletTokenBalance.js +12 -0
  49. package/esm/src/core/addOns/nftTokenV2/types/qn_getWalletTokenTransactions.js +14 -0
  50. package/esm/src/core/addOns/nftTokenV2/types/qn_verifyNFTsOwner.js +11 -0
  51. package/esm/src/core/addOns/shared/helpers.js +10 -0
  52. package/esm/src/core/chains.js +60 -0
  53. package/esm/src/core/core.js +24 -0
  54. package/esm/src/core/index.d.ts +555 -0
  55. package/esm/src/core/index.js +2 -0
  56. package/esm/src/index.js +10 -0
  57. package/esm/src/lib/errors/QNChainNotSupported.js +7 -0
  58. package/esm/src/lib/errors/QNInputValidationError.js +10 -0
  59. package/esm/src/lib/errors/QNInvalidEnpointUrl.js +7 -0
  60. package/esm/src/lib/helpers/globalFetch.js +13 -0
  61. package/esm/src/lib/validation/ValidateInput.js +35 -0
  62. package/esm/src/lib/validation/codegenDerivedValidators.js +28 -0
  63. package/esm/src/lib/validation/validators.js +105 -0
  64. package/index.d.ts +560 -1
  65. package/package.json +25 -3
package/README.md CHANGED
@@ -50,6 +50,8 @@ Full example app implementation [here](https://github.com/quiknode-labs/qn-oss/t
50
50
 
51
51
  Please see [the official QuickNode SDK documentation](https://www.quicknode.com/docs/quicknode-sdk/getting-started) for the full documentation of SDK functions.
52
52
 
53
+ <br>
54
+
53
55
  ## Contributing corner
54
56
 
55
57
  ### Issues
package/cjs/index.js CHANGED
@@ -7,10 +7,31 @@ var core = require('@urql/core');
7
7
  var exchangeGraphcache = require('@urql/exchange-graphcache');
8
8
  var tslib = require('tslib');
9
9
  var zod = require('zod');
10
+ var viem = require('viem');
11
+ var chains = require('viem/chains');
10
12
 
11
13
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
12
14
 
15
+ function _interopNamespace(e) {
16
+ if (e && e.__esModule) return e;
17
+ var n = Object.create(null);
18
+ if (e) {
19
+ Object.keys(e).forEach(function (k) {
20
+ if (k !== 'default') {
21
+ var d = Object.getOwnPropertyDescriptor(e, k);
22
+ Object.defineProperty(n, k, d.get ? d : {
23
+ enumerable: true,
24
+ get: function () { return e[k]; }
25
+ });
26
+ }
27
+ });
28
+ }
29
+ n["default"] = e;
30
+ return Object.freeze(n);
31
+ }
32
+
13
33
  var fetch__default = /*#__PURE__*/_interopDefaultLegacy(fetch);
34
+ var viem__namespace = /*#__PURE__*/_interopNamespace(viem);
14
35
 
15
36
  function isConnection(object) {
16
37
  return (typeof object === 'object' &&
@@ -225,6 +246,12 @@ const contractTokensFilter = zod.z
225
246
  })
226
247
  .strict())
227
248
  .nonempty();
249
+ const rpcPaginationParams = zod.z
250
+ .object({
251
+ perPage: zod.z.number().positive().nullish(),
252
+ page: zod.z.number().positive().nullish(),
253
+ })
254
+ .strict();
228
255
 
229
256
  const walletByAddressValidator = zod.z
230
257
  .object({
@@ -375,6 +402,18 @@ class QNInputValidationError extends Error {
375
402
  }
376
403
  }
377
404
 
405
+ class QNInvalidEndpointUrl extends Error {
406
+ constructor() {
407
+ super('Endpoint URL is not in a valid QuickNode URL format. Please check the URL and try again');
408
+ }
409
+ }
410
+
411
+ class QNChainNotSupported extends Error {
412
+ constructor(endpointUrl) {
413
+ super(`The chain for endpoint URL ${endpointUrl} is not currently supported by the QuickNode SDK.`);
414
+ }
415
+ }
416
+
378
417
  function formatErrors(baseError) {
379
418
  const errorMessages = [];
380
419
  baseError.errors.forEach((error) => {
@@ -1088,7 +1127,7 @@ tslib.__decorate([
1088
1127
  tslib.__metadata("design:returntype", Promise)
1089
1128
  ], TransactionsController.prototype, "getByHash", null);
1090
1129
 
1091
- var name="@quicknode/sdk";var repository={type:"git",url:"https://github.com/quiknode-labs/qn-oss.git",directory:"packages/libs/sdk"};var license="MIT";var version="1.0.0";var main="./cjs/index.js";var module$1="./esm/index.js";var types="./index.d.ts";var dependencies={"@urql/core":"^4.0.7","@urql/exchange-graphcache":"^6.0.4","cross-fetch":"^3.1.6",tslib:"^2.5.3",zod:"^3.21.4"};var devDependencies={"@graphql-codegen/cli":"4.0.1","@graphql-codegen/fragment-matcher":"^3.3.1","@graphql-codegen/introspection":"^3.0.1","@graphql-codegen/typed-document-node":"^4.0.1","@graphql-codegen/typescript":"2.8.0","@graphql-codegen/typescript-operations":"^2.5.5","@pollyjs/adapter-node-http":"^6.0.5","@pollyjs/core":"^6.0.5","@pollyjs/persister-fs":"^6.0.5","@types/jest":"^29.5.1","@types/mocha":"^10.0.1","@types/node":"^18.13.0","@types/supertest":"^2.0.12",dotenv:"^16.0.3","eslint-plugin-no-only-tests":"^3.1.0",graphql:"^16.6.0",supertest:"^6.3.3"};var scripts={codegen:"npx graphql-codegen --require dotenv/config"};var exports$1={".":{"import":"./esm/index.js",require:"./cjs/index.js"}};var packageJson = {name:name,repository:repository,license:license,version:version,main:main,module:module$1,types:types,dependencies:dependencies,devDependencies:devDependencies,scripts:scripts,exports:exports$1};
1130
+ var name="@quicknode/sdk";var repository={type:"git",url:"https://github.com/quiknode-labs/qn-oss.git",directory:"packages/libs/sdk"};var license="MIT";var version="1.1.0";var main="./cjs/index.js";var module$1="./esm/src/index.js";var types="./index.d.ts";var sideEffects=false;var dependencies={"@urql/core":"^4.0.7","@urql/exchange-graphcache":"^6.0.4","cross-fetch":"^3.1.6",viem:"^1.2.0",tslib:"^2.5.3",zod:"^3.21.4"};var devDependencies={"@graphql-codegen/cli":"4.0.1","@graphql-codegen/fragment-matcher":"^3.3.1","@graphql-codegen/introspection":"^3.0.1","@graphql-codegen/typed-document-node":"^4.0.1","@graphql-codegen/typescript":"2.8.0","@graphql-codegen/typescript-operations":"^2.5.5","@pollyjs/adapter-node-http":"^6.0.5","@pollyjs/core":"^6.0.5","@pollyjs/persister-fs":"^6.0.5","@types/jest":"^29.5.1","@types/mocha":"^10.0.1","@types/node":"^18.13.0","@types/supertest":"^2.0.12",dotenv:"^16.0.3","eslint-plugin-no-only-tests":"^3.1.0",graphql:"^16.6.0",supertest:"^6.3.3"};var scripts={codegen:"npx graphql-codegen --require dotenv/config"};var exports$1={".":{"import":"./esm/src/index.js",require:"./cjs/index.js"},"./api":{"import":"./esm/src/api/index.js","default":"./cjs/src/api/index.js",types:"./esm/src/api/index.d.ts"},"./core":{"import":"./esm/src/core/index.js","default":"./cjs/src/core/index.js",types:"./esm/src/core/index.d.ts"}};var typesVersions={"*":{api:["./esm/src/api/index.d.ts"],core:["./esm/src/core/index.d.ts"]}};var packageJson = {name:name,repository:repository,license:license,version:version,main:main,module:module$1,types:types,sideEffects:sideEffects,dependencies:dependencies,devDependencies:devDependencies,scripts:scripts,exports:exports$1,typesVersions:typesVersions};
1092
1131
 
1093
1132
  class API {
1094
1133
  constructor({ graphApiKey, additionalHeaders, defaultChain, } = {}) {
@@ -1160,14 +1199,288 @@ class API {
1160
1199
  }
1161
1200
  }
1162
1201
 
1202
+ // We can't dynamically extend the viem client based on which add-ons are specified, which would
1203
+ // make the types fully align with the add-ons for the client, so instead we do run-time checks to
1204
+ // prevent calling add-ons not explicitly added in the config
1205
+ function checkAddOnEnabled(enabled, humanName, configName) {
1206
+ if (!enabled) {
1207
+ throw new Error(`${humanName} is not set as enabled. Please ensure the addon is enabled on your QuickNode endpoint and enable ${configName} in the Core configuration argument`);
1208
+ }
1209
+ }
1210
+
1211
+ const qnFetchNFTInputSchema = zod.z
1212
+ .object({
1213
+ wallet: isEvmAddress,
1214
+ contracts: zod.z.array(isEvmAddress).nullish(),
1215
+ omitFields: zod.z.array(zod.z.string()).nullish(),
1216
+ })
1217
+ .merge(rpcPaginationParams)
1218
+ .strict();
1219
+
1220
+ const qnFetchNFTCollectionDetailsInputSchema = zod.z
1221
+ .object({
1222
+ contracts: zod.z.array(isEvmAddress),
1223
+ })
1224
+ .strict();
1225
+
1226
+ const qnFetchNFTsByCollectionInputSchema = zod.z
1227
+ .object({
1228
+ collection: isEvmAddress,
1229
+ tokens: zod.z.array(zod.z.string()).nullish(),
1230
+ omitFields: zod.z.array(zod.z.string()).nullish(),
1231
+ })
1232
+ .merge(rpcPaginationParams)
1233
+ .strict();
1234
+
1235
+ const qnGetTransfersByNFTInputSchema = zod.z
1236
+ .object({
1237
+ collection: isEvmAddress,
1238
+ collectionTokenId: zod.z.string(),
1239
+ })
1240
+ .merge(rpcPaginationParams)
1241
+ .strict();
1242
+
1243
+ const qnVerifyNFTsOwnerInputSchema = zod.z
1244
+ .object({
1245
+ wallet: isEvmAddress,
1246
+ contracts: zod.z.array(zod.z.string()), // TODO: make this enforce the address:id format
1247
+ })
1248
+ .strict();
1249
+
1250
+ const qnGetTokenMetadataByCAInputSchema = zod.z
1251
+ .object({
1252
+ contract: isEvmAddress,
1253
+ })
1254
+ .strict();
1255
+
1256
+ const qnGetTokenMetadataBySymbolInputSchema = zod.z
1257
+ .object({
1258
+ symbol: zod.z.string(),
1259
+ })
1260
+ .merge(rpcPaginationParams)
1261
+ .strict();
1262
+
1263
+ const qnGetTransactionsByAddressInputSchema = zod.z
1264
+ .object({
1265
+ address: isEvmAddress,
1266
+ fromBlock: zod.z.number().positive().nullish(),
1267
+ toBlock: zod.z.number().positive().nullish(),
1268
+ })
1269
+ .merge(rpcPaginationParams)
1270
+ .strict()
1271
+ .refine(({ fromBlock, toBlock }) => {
1272
+ if (fromBlock && toBlock)
1273
+ return fromBlock < toBlock;
1274
+ return true;
1275
+ }, { message: 'fromBlock must be less than toBlock' });
1276
+
1277
+ const qnGetWalletTokenBalanceInputSchema = zod.z
1278
+ .object({
1279
+ wallet: isEvmAddress,
1280
+ contracts: zod.z.array(isEvmAddress).nullish(),
1281
+ })
1282
+ .merge(rpcPaginationParams)
1283
+ .strict();
1284
+
1285
+ const qnGetWalletTokenTransactionsInputSchema = zod.z
1286
+ .object({
1287
+ address: isEvmAddress,
1288
+ contract: isEvmAddress,
1289
+ fromBlock: zod.z.number().positive().nullish(),
1290
+ toBlock: zod.z.number().positive().nullish(),
1291
+ })
1292
+ .merge(rpcPaginationParams)
1293
+ .strict();
1294
+
1295
+ function nftAndTokenValidator(config, schema, args) {
1296
+ checkAddOnEnabled(config.addOns?.nftTokenV2 ?? false, 'NFT And Token RPC API V2', 'nftTokenV2');
1297
+ // Uses zod to validate schema at runtime
1298
+ const validation = schema.safeParse(args);
1299
+ if (!validation.success) {
1300
+ const formattedErrors = formatErrors(validation.error);
1301
+ if (formattedErrors)
1302
+ throw formattedErrors;
1303
+ }
1304
+ }
1305
+ const nftAndTokenActions = (client, config) => ({
1306
+ async qn_fetchNFTCollectionDetails(args) {
1307
+ nftAndTokenValidator(config, qnFetchNFTCollectionDetailsInputSchema, args);
1308
+ const response = await client.request({
1309
+ method: 'qn_fetchNFTCollectionDetails',
1310
+ params: [args],
1311
+ });
1312
+ return response;
1313
+ },
1314
+ async qn_fetchNFTs(args) {
1315
+ nftAndTokenValidator(config, qnFetchNFTInputSchema, args);
1316
+ const response = await client.request({
1317
+ method: 'qn_fetchNFTs',
1318
+ params: [args],
1319
+ });
1320
+ return response;
1321
+ },
1322
+ async qn_fetchNFTsByCollection(args) {
1323
+ nftAndTokenValidator(config, qnFetchNFTsByCollectionInputSchema, args);
1324
+ const response = await client.request({
1325
+ method: 'qn_fetchNFTsByCollection',
1326
+ params: [args],
1327
+ });
1328
+ return response;
1329
+ },
1330
+ async qn_getTransfersByNFT(args) {
1331
+ nftAndTokenValidator(config, qnGetTransfersByNFTInputSchema, args);
1332
+ const response = await client.request({
1333
+ method: 'qn_getTransfersByNFT',
1334
+ params: [args],
1335
+ });
1336
+ return response;
1337
+ },
1338
+ async qn_verifyNFTsOwner(args) {
1339
+ nftAndTokenValidator(config, qnVerifyNFTsOwnerInputSchema, args);
1340
+ const response = await client.request({
1341
+ method: 'qn_verifyNFTsOwner',
1342
+ params: [args],
1343
+ });
1344
+ return response;
1345
+ },
1346
+ async qn_getTokenMetadataByContractAddress(args) {
1347
+ nftAndTokenValidator(config, qnGetTokenMetadataByCAInputSchema, args);
1348
+ const response = await client.request({
1349
+ method: 'qn_getTokenMetadataByContractAddress',
1350
+ params: [args],
1351
+ });
1352
+ return response;
1353
+ },
1354
+ async qn_getTokenMetadataBySymbol(args) {
1355
+ nftAndTokenValidator(config, qnGetTokenMetadataBySymbolInputSchema, args);
1356
+ const response = await client.request({
1357
+ method: 'qn_getTokenMetadataBySymbol',
1358
+ params: [args],
1359
+ });
1360
+ return response;
1361
+ },
1362
+ async qn_getTransactionsByAddress(args) {
1363
+ nftAndTokenValidator(config, qnGetTransactionsByAddressInputSchema, args);
1364
+ const response = await client.request({
1365
+ method: 'qn_getTransactionsByAddress',
1366
+ params: [args],
1367
+ });
1368
+ return response;
1369
+ },
1370
+ async qn_getWalletTokenBalance(args) {
1371
+ nftAndTokenValidator(config, qnGetWalletTokenBalanceInputSchema, args);
1372
+ const response = await client.request({
1373
+ method: 'qn_getWalletTokenBalance',
1374
+ params: [args],
1375
+ });
1376
+ return response;
1377
+ },
1378
+ async qn_getWalletTokenTransactions(args) {
1379
+ nftAndTokenValidator(config, qnGetWalletTokenTransactionsInputSchema, args);
1380
+ const response = await client.request({
1381
+ method: 'qn_getWalletTokenTransactions',
1382
+ params: [args],
1383
+ });
1384
+ return response;
1385
+ },
1386
+ });
1387
+
1388
+ const ETH_MAINNET_NETWORK = 'ethereum-mainnet';
1389
+ const qnChainToViemChain = {
1390
+ 'arbitrum-mainnet': chains.arbitrum,
1391
+ 'arbitrum-goerli': chains.arbitrumGoerli,
1392
+ 'avalanche-mainnet': chains.avalanche,
1393
+ 'avalanche-testnet': chains.avalancheFuji,
1394
+ 'base-goerli': chains.baseGoerli,
1395
+ ['bsc']: chains.bsc,
1396
+ 'bsc-testnet': chains.bscTestnet,
1397
+ 'celo-mainnet': chains.celo,
1398
+ ['fantom']: chains.fantom,
1399
+ ['xdai']: chains.gnosis,
1400
+ ['gnosis']: chains.gnosis,
1401
+ 'ethereum-goerli': chains.goerli,
1402
+ 'harmony-mainnet': chains.harmonyOne,
1403
+ [ETH_MAINNET_NETWORK]: chains.mainnet,
1404
+ ['optimism']: chains.optimism,
1405
+ 'optimism-goerli': chains.optimismGoerli,
1406
+ ['matic']: chains.polygon,
1407
+ ['polygon']: chains.polygon,
1408
+ 'matic-testnet': chains.polygonMumbai,
1409
+ 'zkevm-mainnet': chains.polygonZkEvm,
1410
+ 'zkevm-testnet': chains.polygonZkEvmTestnet,
1411
+ 'ethereum-sepolia': chains.sepolia,
1412
+ };
1413
+ function chainNameFromEndpoint(endpointUrl) {
1414
+ let hostnameParts;
1415
+ try {
1416
+ const parsedUrl = new URL(endpointUrl);
1417
+ hostnameParts = parsedUrl.hostname.split('.');
1418
+ }
1419
+ catch (e) {
1420
+ throw new QNInvalidEndpointUrl();
1421
+ }
1422
+ const quiknode = hostnameParts.at(-2);
1423
+ const chainOrDiscover = hostnameParts.at(-3);
1424
+ if (quiknode !== 'quiknode' || !chainOrDiscover)
1425
+ throw new QNInvalidEndpointUrl();
1426
+ const indexOfName = chainOrDiscover === 'discover' ? -4 : -3;
1427
+ const lengthOfEthereum = chainOrDiscover === 'discover' ? 4 : 3;
1428
+ if (hostnameParts.length === lengthOfEthereum)
1429
+ return ETH_MAINNET_NETWORK;
1430
+ const potentialChainName = hostnameParts.at(indexOfName);
1431
+ if (potentialChainName)
1432
+ return potentialChainName;
1433
+ throw new QNInvalidEndpointUrl();
1434
+ }
1435
+ function deriveChainFromUrl(endpointUrl) {
1436
+ const chainName = chainNameFromEndpoint(endpointUrl);
1437
+ const viemChain = qnChainToViemChain[chainName];
1438
+ if (viemChain)
1439
+ return viemChain;
1440
+ throw new QNChainNotSupported(endpointUrl);
1441
+ }
1442
+
1443
+ function setupGlobalFetch() {
1444
+ // Required for viem to work in node
1445
+ if (!globalThis.fetch) {
1446
+ globalThis.fetch = fetch__default["default"];
1447
+ globalThis.Headers = fetch.Headers;
1448
+ globalThis.Request = fetch.Request;
1449
+ globalThis.Response = fetch.Response;
1450
+ }
1451
+ }
1452
+
1453
+ const buildQNActions = (config) => {
1454
+ return (client) => ({
1455
+ ...nftAndTokenActions(client, config),
1456
+ });
1457
+ };
1458
+ class Core {
1459
+ constructor({ endpointUrl, chain, config = {} }) {
1460
+ setupGlobalFetch();
1461
+ this.endpointUrl = endpointUrl;
1462
+ const baseClient = viem.createClient({
1463
+ chain: chain || deriveChainFromUrl(endpointUrl),
1464
+ transport: viem.http(this.endpointUrl),
1465
+ }).extend(viem.publicActions);
1466
+ const qnClient = baseClient.extend(buildQNActions(config));
1467
+ this.client = qnClient;
1468
+ }
1469
+ }
1470
+
1163
1471
  const QuickNode = {
1164
1472
  API: API,
1473
+ Core: Core,
1165
1474
  };
1166
1475
 
1167
1476
  Object.defineProperty(exports, 'gql', {
1168
1477
  enumerable: true,
1169
1478
  get: function () { return core.gql; }
1170
1479
  });
1480
+ exports.viem = viem__namespace;
1171
1481
  exports.API = API;
1482
+ exports.Core = Core;
1483
+ exports.QNChainNotSupported = QNChainNotSupported;
1172
1484
  exports.QNInputValidationError = QNInputValidationError;
1485
+ exports.QNInvalidEndpointUrl = QNInvalidEndpointUrl;
1173
1486
  exports["default"] = QuickNode;
package/esm/package.json CHANGED
@@ -1,3 +1,4 @@
1
1
  {
2
- "type": "module"
2
+ "type": "module",
3
+ "sideEffects": false
3
4
  }
@@ -0,0 +1,3 @@
1
+ var name="@quicknode/sdk";var repository={type:"git",url:"https://github.com/quiknode-labs/qn-oss.git",directory:"packages/libs/sdk"};var license="MIT";var version="1.1.0";var main="./cjs/index.js";var module="./esm/src/index.js";var types="./index.d.ts";var sideEffects=false;var dependencies={"@urql/core":"^4.0.7","@urql/exchange-graphcache":"^6.0.4","cross-fetch":"^3.1.6",viem:"^1.2.0",tslib:"^2.5.3",zod:"^3.21.4"};var devDependencies={"@graphql-codegen/cli":"4.0.1","@graphql-codegen/fragment-matcher":"^3.3.1","@graphql-codegen/introspection":"^3.0.1","@graphql-codegen/typed-document-node":"^4.0.1","@graphql-codegen/typescript":"2.8.0","@graphql-codegen/typescript-operations":"^2.5.5","@pollyjs/adapter-node-http":"^6.0.5","@pollyjs/core":"^6.0.5","@pollyjs/persister-fs":"^6.0.5","@types/jest":"^29.5.1","@types/mocha":"^10.0.1","@types/node":"^18.13.0","@types/supertest":"^2.0.12",dotenv:"^16.0.3","eslint-plugin-no-only-tests":"^3.1.0",graphql:"^16.6.0",supertest:"^6.3.3"};var scripts={codegen:"npx graphql-codegen --require dotenv/config"};var exports={".":{"import":"./esm/src/index.js",require:"./cjs/index.js"},"./api":{"import":"./esm/src/api/index.js","default":"./cjs/src/api/index.js",types:"./esm/src/api/index.d.ts"},"./core":{"import":"./esm/src/core/index.js","default":"./cjs/src/core/index.js",types:"./esm/src/core/index.d.ts"}};var typesVersions={"*":{api:["./esm/src/api/index.d.ts"],core:["./esm/src/core/index.d.ts"]}};var packageJson = {name:name,repository:repository,license:license,version:version,main:main,module:module,types:types,sideEffects:sideEffects,dependencies:dependencies,devDependencies:devDependencies,scripts:scripts,exports:exports,typesVersions:typesVersions};
2
+
3
+ export { packageJson as default, dependencies, devDependencies, exports, license, main, module, name, repository, scripts, sideEffects, types, typesVersions, version };
@@ -0,0 +1,85 @@
1
+ import fetch from 'cross-fetch';
2
+ import { CustomUrqlClient } from './graphql/customUrqlClient.js';
3
+ import { Client, fetchExchange } from '@urql/core';
4
+ import { cacheExchange } from '@urql/exchange-graphcache';
5
+ import { NftsController } from './controllers/nfts.js';
6
+ import { TokensController } from './controllers/tokens.js';
7
+ import { UtilsController } from './controllers/utils.js';
8
+ import { ContractsController } from './controllers/contracts.js';
9
+ import { EventsController } from './controllers/events.js';
10
+ import { DEFAULT_CHAIN } from './utils/constants.js';
11
+ import schema from './graphql/schema.json.js';
12
+ import { TransactionsController } from './controllers/transactions.js';
13
+ import packageJson from '../../package.json.js';
14
+
15
+ class API {
16
+ constructor({ graphApiKey, additionalHeaders, defaultChain, } = {}) {
17
+ if (!graphApiKey) {
18
+ console.warn('QuickNode SDK warning: no apiKey provided. Access with no apiKey is heavily rate limited and intended for development use only. For higher rate limits or production usage, create an account on https://www.quicknode.com/');
19
+ }
20
+ this.graphApiKey = graphApiKey;
21
+ this.additionalHeaders = additionalHeaders;
22
+ this.urqlClient = this.createUrqlClient();
23
+ this.customUrqlClient = new CustomUrqlClient(this.urqlClient);
24
+ this.defaultChain = defaultChain || DEFAULT_CHAIN;
25
+ this.nfts = new NftsController(this.customUrqlClient, this.defaultChain);
26
+ this.tokens = new TokensController(this.customUrqlClient, this.defaultChain);
27
+ this.utils = new UtilsController(this.customUrqlClient, this.defaultChain);
28
+ this.contracts = new ContractsController(this.customUrqlClient, this.defaultChain);
29
+ this.transactions = new TransactionsController(this.customUrqlClient, this.defaultChain);
30
+ this.events = new EventsController(this.customUrqlClient, this.defaultChain);
31
+ // Re-export the Urql client configured to use the Graph API for use with custom queries
32
+ this.graphApiClient = this.urqlClient;
33
+ }
34
+ createUrqlClient() {
35
+ const headers = { ...this.additionalHeaders };
36
+ if (this.graphApiKey)
37
+ headers['x-api-key'] = this.graphApiKey;
38
+ headers['x-quicknode-sdk'] = 'js-sdk';
39
+ headers['x-quicknode-sdk-version'] = packageJson?.version || 'n/a';
40
+ const useNftKey = (data) => `${data['contractAddress']}:${data['tokenId']}`;
41
+ const useAddressAsKey = (data) => `${data['address']}`;
42
+ const useTransactionHashAndIndex = (data) => `${data['transactionHash']}:${data['transferIndex']}`;
43
+ const urqlCache = cacheExchange({
44
+ schema,
45
+ keys: {
46
+ EVMSchemaType: () => null,
47
+ Collection: useAddressAsKey,
48
+ CollectionOHLCVChart: () => null,
49
+ Contract: useAddressAsKey,
50
+ ERC721NFT: useNftKey,
51
+ ERC721Collection: useAddressAsKey,
52
+ ERC1155NFT: useNftKey,
53
+ ERC1155Collection: useAddressAsKey,
54
+ GasPrice: () => null,
55
+ NFT: useNftKey,
56
+ NFTContract: useAddressAsKey,
57
+ TokenAttribute: () => null,
58
+ TokenContract: useAddressAsKey,
59
+ TokenEvent: useTransactionHashAndIndex,
60
+ TokenMintEvent: useTransactionHashAndIndex,
61
+ TokenBurnEvent: useTransactionHashAndIndex,
62
+ TokenSaleEvent: useTransactionHashAndIndex,
63
+ TokenSwapEvent: useTransactionHashAndIndex,
64
+ TokenTransferEvent: useTransactionHashAndIndex,
65
+ TokenUpload: () => null,
66
+ OpenSeaMetadata: () => null,
67
+ Transaction: (data) => `${data['hash']}`,
68
+ TrendingCollection: () => null,
69
+ Wallet: (data) => `${data['address']}`,
70
+ WalletNFT: () => null,
71
+ WalletTokenBalance: () => null,
72
+ },
73
+ });
74
+ const client = new Client({
75
+ fetch,
76
+ url: process.env['NX_GRAPHQL_API_URI'] ||
77
+ 'https://api.quicknode.com/graphql',
78
+ exchanges: [urqlCache, fetchExchange],
79
+ fetchOptions: () => ({ headers }),
80
+ });
81
+ return client;
82
+ }
83
+ }
84
+
85
+ export { API };
@@ -0,0 +1,36 @@
1
+ import { __decorate, __metadata } from 'tslib';
2
+ import { DEFAULT_CHAIN } from '../utils/constants.js';
3
+ import { contractDetailsValidator } from '../types/contracts/getContractDetails.js';
4
+ import { CodegenEthMainnetContractDetailsDocument, CodegenPolygonMainnetContractDetailsDocument, CodegenEthSepoliaContractDetailsDocument } from '../graphql/generatedTypes.js';
5
+ import { ValidateInput } from '../../lib/validation/ValidateInput.js';
6
+
7
+ class ContractsController {
8
+ constructor(client, defaultChain = DEFAULT_CHAIN) {
9
+ this.client = client;
10
+ this.defaultChain = defaultChain;
11
+ }
12
+ async getDetails(variables) {
13
+ const { chain, ...queryVariables } = variables;
14
+ const userChain = chain || this.defaultChain;
15
+ const query = {
16
+ ethereum: CodegenEthMainnetContractDetailsDocument,
17
+ polygon: CodegenPolygonMainnetContractDetailsDocument,
18
+ ethereumSepolia: CodegenEthSepoliaContractDetailsDocument,
19
+ };
20
+ const { data: { [userChain]: { contract }, }, } = await this.client.query({
21
+ variables: queryVariables,
22
+ query: query[userChain],
23
+ });
24
+ if (contract)
25
+ return { contract };
26
+ return { contract: null };
27
+ }
28
+ }
29
+ __decorate([
30
+ ValidateInput(contractDetailsValidator),
31
+ __metadata("design:type", Function),
32
+ __metadata("design:paramtypes", [Object]),
33
+ __metadata("design:returntype", Promise)
34
+ ], ContractsController.prototype, "getDetails", null);
35
+
36
+ export { ContractsController };
@@ -0,0 +1,121 @@
1
+ import { __decorate, __metadata } from 'tslib';
2
+ import { contractEventsValidator } from '../types/events/getByContract.js';
3
+ import { collectionEventsValidator } from '../types/nfts/getCollectionEvents.js';
4
+ import { nftEventsValidator } from '../types/nfts/getNFTEvents.js';
5
+ import { allEventsValidator } from '../types/events/getAll.js';
6
+ import { CodegenEthereumMainnetEventsByContractDocument, CodegenPolygonMainnetEventsByContractDocument, CodegenEthereumSepoliaEventsByContractDocument, CodegenEthMainnetEventsByCollectionDocument, CodegenPolygonMainnetEventsByCollectionDocument, CodegenEthSepoliaEventsByCollectionDocument, CodegenEthereumMainnetEventsByNftDocument, CodegenPolygonMainnetEventsByNftDocument, CodegenEthSepoliaEventsByNftDocument, CodegenEthereumMainnetEventsGetAllDocument, CodegenPolygonMainnetEventsGetAllDocument, CodegenEthereumSepoliaEventsGetAllDocument } from '../graphql/generatedTypes.js';
7
+ import { formatQueryResult } from '../utils/postQueryFormatter.js';
8
+ import { emptyPageInfo } from '../utils/helpers.js';
9
+ import { DEFAULT_CHAIN } from '../utils/constants.js';
10
+ import { ValidateInput } from '../../lib/validation/ValidateInput.js';
11
+
12
+ class EventsController {
13
+ constructor(client, defaultChain = DEFAULT_CHAIN) {
14
+ this.client = client;
15
+ this.defaultChain = defaultChain;
16
+ }
17
+ async getByContract(variables) {
18
+ const { chain, ...queryVariables } = variables;
19
+ const userChain = chain || this.defaultChain;
20
+ const query = {
21
+ ethereum: CodegenEthereumMainnetEventsByContractDocument,
22
+ polygon: CodegenPolygonMainnetEventsByContractDocument,
23
+ ethereumSepolia: CodegenEthereumSepoliaEventsByContractDocument,
24
+ };
25
+ const { data: { [userChain]: { contract }, }, } = await this.client.query({
26
+ query: query[userChain],
27
+ variables: queryVariables,
28
+ });
29
+ if (!contract?.tokenEvents?.length) {
30
+ return {
31
+ results: [],
32
+ pageInfo: emptyPageInfo,
33
+ };
34
+ }
35
+ const formattedResult = formatQueryResult(contract, 'tokenEvents', 'tokenEventsPageInfo');
36
+ return formattedResult;
37
+ }
38
+ async getByNFTCollection(variables) {
39
+ const { chain, ...queryVariables } = variables;
40
+ const userChain = chain || this.defaultChain;
41
+ const query = {
42
+ ethereum: CodegenEthMainnetEventsByCollectionDocument,
43
+ polygon: CodegenPolygonMainnetEventsByCollectionDocument,
44
+ ethereumSepolia: CodegenEthSepoliaEventsByCollectionDocument,
45
+ };
46
+ const { data: { [userChain]: { collection }, }, } = await this.client.query({
47
+ query: query[userChain],
48
+ variables: queryVariables,
49
+ });
50
+ if (!collection?.tokenEvents?.length)
51
+ return { results: [], pageInfo: emptyPageInfo };
52
+ function removeKeyFields(results) {
53
+ const { address, ...newResults } = results;
54
+ return newResults;
55
+ }
56
+ const formattedResult = formatQueryResult(collection, 'tokenEvents', 'tokenEventsPageInfo', null, removeKeyFields);
57
+ return formattedResult;
58
+ }
59
+ async getByNFT(variables) {
60
+ const { chain, ...queryVariables } = variables;
61
+ const userChain = chain || this.defaultChain;
62
+ const query = {
63
+ ethereum: CodegenEthereumMainnetEventsByNftDocument,
64
+ polygon: CodegenPolygonMainnetEventsByNftDocument,
65
+ ethereumSepolia: CodegenEthSepoliaEventsByNftDocument,
66
+ };
67
+ const { data: { [userChain]: { nft }, }, } = await this.client.query({
68
+ query: query[userChain],
69
+ variables: queryVariables,
70
+ });
71
+ if (!nft?.tokenEvents?.length)
72
+ return { results: [], pageInfo: emptyPageInfo };
73
+ function removeKeyFields(results) {
74
+ const { contractAddress, tokenId, ...newResults } = results;
75
+ return newResults;
76
+ }
77
+ const formattedResult = formatQueryResult(nft, 'tokenEvents', 'tokenEventsPageInfo', null, removeKeyFields);
78
+ return formattedResult;
79
+ }
80
+ async getAll(variables) {
81
+ const { chain, ...queryVariables } = variables;
82
+ const userChain = chain || this.defaultChain;
83
+ const query = {
84
+ ethereum: CodegenEthereumMainnetEventsGetAllDocument,
85
+ polygon: CodegenPolygonMainnetEventsGetAllDocument,
86
+ ethereumSepolia: CodegenEthereumSepoliaEventsGetAllDocument,
87
+ };
88
+ const { data: { [userChain]: tokenEvents }, } = await this.client.query({
89
+ query: query[userChain],
90
+ variables: queryVariables,
91
+ });
92
+ const formattedResult = formatQueryResult(tokenEvents, 'tokenEvents', 'tokenEventsPageInfo');
93
+ return formattedResult;
94
+ }
95
+ }
96
+ __decorate([
97
+ ValidateInput(contractEventsValidator),
98
+ __metadata("design:type", Function),
99
+ __metadata("design:paramtypes", [Object]),
100
+ __metadata("design:returntype", Promise)
101
+ ], EventsController.prototype, "getByContract", null);
102
+ __decorate([
103
+ ValidateInput(collectionEventsValidator),
104
+ __metadata("design:type", Function),
105
+ __metadata("design:paramtypes", [Object]),
106
+ __metadata("design:returntype", Promise)
107
+ ], EventsController.prototype, "getByNFTCollection", null);
108
+ __decorate([
109
+ ValidateInput(nftEventsValidator),
110
+ __metadata("design:type", Function),
111
+ __metadata("design:paramtypes", [Object]),
112
+ __metadata("design:returntype", Promise)
113
+ ], EventsController.prototype, "getByNFT", null);
114
+ __decorate([
115
+ ValidateInput(allEventsValidator),
116
+ __metadata("design:type", Function),
117
+ __metadata("design:paramtypes", [Object]),
118
+ __metadata("design:returntype", Promise)
119
+ ], EventsController.prototype, "getAll", null);
120
+
121
+ export { EventsController };