@quicknode/sdk 0.5.2 → 1.0.0-beta.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/README.md CHANGED
@@ -1,255 +1,832 @@
1
1
  # QuickNode SDK
2
2
 
3
- An SDK from [QuickNode](https://www.quicknode.com/) making it easy for developers to interact with the blockchain.
3
+ > :warning: **This is an beta release** This release is not production-ready yet and only meant as a technical preview. The API could break in subsequent beta releases until the 1.0.0 release is finalized.
4
4
 
5
- Currently supports getting started with [Icy Tools GraphQL API](https://developers.icy.tools/) in a blink!
5
+ A SDK from [QuickNode](https://www.quicknode.com/) making it easy for developers to interact with QuickNode's services.
6
6
 
7
+ QuickNode's SDK is a JavaScript and TypeScript framework-agnostic library that supports both CommonJS and ES module systems.
8
+
9
+ Currently the SDK makes it even easier to use the [QuickNode Graph API](https://www.quicknode.com/graph-api) to query market insights, trading data, transactions by wallets and contracts, cached NFT images, and more!
10
+
11
+ > :grey_question: We want to hear from you! Please take a few minutes to fill out our [QuickNode SDK feedback form](https://forms.gle/vWFXDDjEUySjWUof6) and let us know what you currently think about the SDK. This helps us further improve the SDK.
12
+
13
+ [![Coverage Status](https://coveralls.io/repos/github/quiknode-labs/qn-oss/badge.svg?branch=main)](https://coveralls.io/github/quiknode-labs/qn-oss?branch=main)
7
14
  [![npm](https://img.shields.io/npm/dm/@quicknode/sdk)](https://www.npmjs.com/package/@quicknode/sdk)
8
15
  [![npm](https://img.shields.io/npm/v/@quicknode/sdk?color=g)](https://www.npmjs.com/package/@quicknode/sdk)
9
- ![Maintenance](https://img.shields.io/maintenance/yes/2022?color=g)
16
+ ![Maintenance](https://img.shields.io/maintenance/yes/2023?color=g)
10
17
  [![License](https://img.shields.io/npm/l/@quicknode/sdk?color=g)](https://github.com/quiknode-labs/qn-oss/blob/main/LICENSE.txt)
11
18
  [![GitHub issues](https://img.shields.io/github/issues-raw/quiknode-labs/qn-oss?color=g)](https://github.com/quiknode-labs/qn-oss/issues)
12
19
  [![Discord](https://img.shields.io/discord/880505845090250794?color=g)](https://discord.gg/DkdgEqE)
13
20
 
14
- ## Quick Start
21
+ <br>
22
+
23
+ - [QuickNode SDK](#quicknode-sdk)
24
+ - [Getting Started](#getting-started)
25
+ - [Installation](#installation)
26
+ - [Quickstart](#quickstart)
27
+ - [API functions](#api-functions)
28
+ - [Configuration](#configuration)
29
+ - [Configuration Arguments](#configuration-arguments)
30
+ - [nfts.getByWallet](#nftsgetbywallet)
31
+ - [nfts.getTrendingCollections](#nftsgettrendingcollections)
32
+ - [nfts.getByContractAddress](#nftsgetbycontractaddress)
33
+ - [nfts.getNFTDetails](#nftsgetnftdetails)
34
+ - [nfts.getCollectionDetails](#nftsgetcollectiondetails)
35
+ - [tokens.getBalancesByWallet](#tokensgetbalancesbywallet)
36
+ - [contracts.getDetails](#contractsgetdetails)
37
+ - [transactions.getByWallet](#transactionsgetbywallet)
38
+ - [transactions.getAll](#transactionsgetall)
39
+ - [transactions.getByHash](#transactionsgetbyhash)
40
+ - [events.getByContract](#eventsgetbycontract)
41
+ - [events.getByNFTCollection](#eventsgetbynftcollection)
42
+ - [events.getByNFT](#eventsgetbynft)
43
+ - [events.getAll](#eventsgetall)
44
+ - [utils.getGasPrices](#utilsgetgasprices)
45
+ - [graphApiClient.query](#graphapiclientquery)
46
+ - [Error Handling](#error-handling)
47
+ - [Filters](#filters)
48
+ - [Token Event Filters](#token-event-filters)
49
+ - [Pagination](#pagination)
50
+ - [Contributing corner](#contributing-corner)
51
+ - [Issues](#issues)
52
+ - [Development](#development)
53
+ - [Running tests](#running-tests)
54
+ - [Running linting](#running-linting)
55
+ - [Generate graphql codegen typings](#generate-graphql-codegen-typings)
56
+
57
+ <br>
58
+
59
+ ## Getting Started
60
+
61
+ ### Installation
62
+
63
+ - Requires Node.js v16 or higher
64
+ - `npm install @quicknode/sdk` or `yarn add @quicknode/sdk`
65
+
66
+ <br>
67
+
68
+ ### Quickstart
15
69
 
16
70
  ```ts
17
- import { QuickNodeSDK } from '@quicknode/sdk';
71
+ import QuickNode from '@quicknode/sdk';
18
72
 
19
- const client = new QuickNodeSDK();
73
+ const qn = new QuickNode.API({ graphApiKey: 'my-api-key' });
20
74
 
21
- client.nft
22
- .getNFTsByWalletENS({
23
- ensName: 'vitalik.eth',
75
+ qn.nfts
76
+ .getByWallet({
77
+ address: 'quicknode.eth',
24
78
  first: 5,
25
79
  })
26
80
  .then((response) => console.log(response));
27
81
  ```
28
82
 
29
- Full example implementation [here](https://github.com/quiknode-labs/qn-oss/tree/main/packages/apps/examples/nft-sdk)
83
+ Full example app implementation [here](https://github.com/quiknode-labs/qn-oss/tree/main/packages/apps/examples/sdk-api)
30
84
 
31
- ## Providing a config object to the client
85
+ <br>
86
+
87
+ ## API functions
32
88
 
33
- > :warning: This client (and the underlying API) can be used without an icyApiKey, but its usage will be heavily rate limited, intended for trial and development purposes only.
89
+ These functions return data from the powerful [QuickNode Graph API](https://www.quicknode.com/graph-api), making it even easier to use.
90
+
91
+ <br>
92
+
93
+ ### Configuration
94
+
95
+ Sign up for a [QuickNode](https://www.quicknode.com/) account to use the multi-chain [QuickNode Graph API](https://www.quicknode.com/graph-api) API key in the SDK. The API functions in the SDK (and the underlying Graph API) can be used without an API key, but its usage will be heavily rate limited, intended for trial and development purposes only. For more information, please see [QuickNode's Graph API documentation](https://docs.quicknode.com/docs/graphql/getting-started/)
34
96
 
35
97
  ```ts
36
- import { QuickNodeSDK } from '@quicknode/sdk';
98
+ import QuickNode from '@quicknode/sdk';
37
99
 
38
- const client = new QuickNodeSDK({
39
- icyApiKey: 'my-api-key', // which is obtained by signing up on https://developers.icy.tools/
100
+ const qn = new QuickNode.API({
101
+ graphApiKey: 'my-api-key', // which is obtained by signing up on https://www.quicknode.com/signup
102
+ defaultChain: 'ethereum',
40
103
  });
41
104
  ```
42
105
 
43
- ### Client config API
106
+ A `defaultChain` can be set to set the chain for all calls. Currently we support:
107
+
108
+ - `ethereum` Ethereum Mainnet
109
+ - `ethereumSepolia` Ethereum Sepolia
110
+ - `polygon` Polygon Mainnet
111
+
112
+ The `defaultChain` in the initializer can be overridden with the `chain` argument in functions.
113
+
114
+ If no `defaultChain` is passed into the initializer or a `chain` argument to a function,`ethereum` is used by default.
115
+
116
+ <br>
117
+
118
+ ### Configuration Arguments
44
119
 
45
- | Property | Values | Example |
46
- | --------- | ------ | ---------------------------------- |
47
- | icyApiKey | string | 1c1t00ls-4p10-k3y0-lu21-43405e3310 |
120
+ | Property | Values | Required | Description | Example |
121
+ | ------------ | ------ | -------- | ------------------------------------------------------------------- | -------- |
122
+ | graphApiKey | string | ❌ | The QuickNode GraphQL API Key | abcd1234 |
123
+ | defaultChain | string | ❌ | The default chain to use for all functions (defaults to `ethereum`) | polygon |
48
124
 
49
125
  <br>
50
126
 
51
- ## Methods
127
+ ### nfts.getByWallet
52
128
 
53
- ### nft.getNFTsByWalletENS
129
+ Returns NFTs owned by a wallet
54
130
 
55
- | Argument | Values | Optional | Description | Example |
56
- | -------- | ------ | -------- | ------------------------------- | --------------------------- |
57
- | ensName | string | | Wallet ENS address | vitalik.eth |
58
- | first | number | | Number of results to return | 10 |
59
- | after | string | | Return results after end cursor | YXJyYXljb25uZWN0aW9uOjUwNQ= |
131
+ | Argument | Values | Required | Description | Example |
132
+ | -------- | ------ | -------- | --------------------------------------------------- | --------------------------------------------------- |
133
+ | address | string | | Wallet address or ENS domain | quicknode.eth |
134
+ | first | number | | Number of results to return | 10 |
135
+ | before | string | | Return results before cursor | T2Zmc2V0Q29ubmVjdGlvbjow |
136
+ | after | string | ❌ | Return results after cursor | T2Zmc2V0Q29ubmVjdGlvbjo2 |
137
+ | chain | string | ❌ | Blockchain name | polygon |
138
+ | filter | object | ❌ | An object with the optional filters for the request | { contractTokens: [{ contractAddress: "0x00..." }]} |
139
+
140
+ `filter` Parameters
141
+
142
+ | Argument | Values | Description | Example |
143
+ | -------------- | ------ | --------------------------------------------------------------------- | ------------------------------------------------------------------- |
144
+ | contractTokens | Array | An array of objects with NFT contract addresses and optional tokenIds | [{ contractAddress: "0x2106C00Ac7dA0A3430aE667879139E832307AeAa" }] |
60
145
 
61
146
  ```ts
62
- import { QuickNodeSDK } from '@quicknode/sdk';
147
+ import QuickNode from '@quicknode/sdk';
148
+
149
+ const qn = new QuickNode.API({
150
+ graphApiKey: 'my-api-key', // which is obtained by signing up on https://www.quicknode.com/signup
151
+ });
63
152
 
64
- const client = new QuickNodeSDK();
153
+ qn.nfts
154
+ .getByWallet({
155
+ address: '0x51ABa267A6e8e1E76B44183a73E881D73A102F26',
156
+ first: 5,
157
+ })
158
+ .then((response) => console.log(response));
65
159
 
66
- client.nft
67
- .getNFTsByWalletENS({
68
- ensName: 'vitalik.eth',
160
+ // can pass in ENS domain
161
+ qn.nfts
162
+ .getByWallet({
163
+ address: 'quicknode.eth',
69
164
  first: 5,
70
165
  })
71
166
  .then((response) => console.log(response));
72
167
  ```
73
168
 
74
- ### nft.getNFTsByWalletAddress
169
+ <br>
170
+
171
+ ### nfts.getTrendingCollections
172
+
173
+ Returns trending NFT Collections
75
174
 
76
- | Argument | Values | Optional | Description | Example |
77
- | -------- | ------ | -------- | ------------------------------- | ------------------------------------------ |
78
- | address | string | ❌ | Wallet address | 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 |
79
- | first | number | | Number of results to return | 10 |
80
- | after | string | | Return results after end cursor | YXJyYXljb25uZWN0aW9uOjUwNQ= |
175
+ | Argument | Values | Required | Description | Example |
176
+ | -------- | ------ | -------- | ---------------------------- | ------------------------ |
177
+ | first | number | ❌ | Number of results to return | 10 |
178
+ | before | string | | Return results before cursor | T2Zmc2V0Q29ubmVjdGlvbjow |
179
+ | after | string | | Return results after cursor | T2Zmc2V0Q29ubmVjdGlvbjo2 |
180
+ | chain | string | ❌ | Blockchain name | polygon |
81
181
 
82
182
  ```ts
83
- import { QuickNodeSDK } from '@quicknode/sdk';
183
+ import QuickNode from '@quicknode/sdk';
84
184
 
85
- const client = new QuickNodeSDK();
185
+ const qn = new QuickNode({
186
+ graphApiKey: 'my-api-key', // which is obtained by signing up on https://www.quicknode.com/signup
187
+ });
86
188
 
87
- client.nft
88
- .getNFTsByWalletAddress({
89
- address: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
189
+ qn.nfts
190
+ .getTrendingCollections({
90
191
  first: 5,
91
192
  })
92
193
  .then((response) => console.log(response));
93
194
  ```
94
195
 
95
- ### nft.getNFTsByContractAddress
196
+ <br>
197
+
198
+ ### nfts.getByContractAddress
96
199
 
97
- | Argument | Values | Optional | Description | Example |
98
- | -------- | ------ | -------- | ------------------------------- | ------------------------------------------ |
99
- | address | string | | Contract address of NFT | 0x2106C00Ac7dA0A3430aE667879139E832307AeAa |
100
- | first | number | | Number of results to return | 10 |
101
- | after | string | ✅ | Return results after end cursor | YXJyYXljb25uZWN0aW9uOjUwNQ= |
200
+ Returns NFTs by contract address. The response differs based on if they are an ERC721 or ERC1155 standard.
201
+
202
+ | Argument | Values | Required | Description | Example |
203
+ | --------------- | ------ | -------- | ---------------------------- | ------------------------------------------ |
204
+ | contractAddress | string | ✅ | NFT contract address | 0x2106C00Ac7dA0A3430aE667879139E832307AeAa |
205
+ | first | number | ❌ | Number of results to return | 10 |
206
+ | before | string | ❌ | Return results before cursor | T2Zmc2V0Q29ubmVjdGlvbjow |
207
+ | after | string | ❌ | Return results after cursor | T2Zmc2V0Q29ubmVjdGlvbjo2 |
208
+ | chain | string | ❌ | Blockchain name | polygon |
102
209
 
103
210
  ```ts
104
- import { QuickNodeSDK } from '@quicknode/sdk';
211
+ import QuickNode from '@quicknode/sdk';
105
212
 
106
- const client = new QuickNodeSDK();
213
+ const qn = new QuickNode.API({
214
+ graphApiKey: 'my-api-key', // which is obtained by signing up on https://www.quicknode.com/signup
215
+ });
107
216
 
108
- client.nft
109
- .getNFTsByContractAddress({
110
- address: '0x2106C00Ac7dA0A3430aE667879139E832307AeAa',
217
+ qn.nfts
218
+ .getByContractAddress({
219
+ contractAddress: '0x2106C00Ac7dA0A3430aE667879139E832307AeAa',
111
220
  first: 5,
112
221
  })
113
222
  .then((response) => console.log(response));
114
223
  ```
115
224
 
116
- ### nft.getCollectionDetails
225
+ <br>
226
+
227
+ ### nfts.getNFTDetails
117
228
 
118
- | Argument | Values | Optional | Description | Example |
119
- | -------- | ------ | -------- | ----------------------- | ------------------------------------------ |
120
- | address | string | | Contract address of NFT | 0x2106C00Ac7dA0A3430aE667879139E832307AeAa |
229
+ Returns the details for a specified NFT
230
+
231
+ | Argument | Values | Required | Description | Example |
232
+ | --------------- | ------ | -------- | -------------------- | ------------------------------------------ |
233
+ | contractAddress | string | ✅ | NFT contract address | 0x2106C00Ac7dA0A3430aE667879139E832307AeAa |
234
+ | tokenId | string | ✅ | NFT Token ID | 1 |
235
+ | chain | string | ❌ | Blockchain name | polygon |
121
236
 
122
237
  ```ts
123
- import { QuickNodeSDK } from '@quicknode/sdk';
238
+ import QuickNode from '@quicknode/sdk';
239
+
240
+ const qn = new QuickNode.API({
241
+ graphApiKey: 'my-api-key', // which is obtained by signing up on https://www.quicknode.com/signup
242
+ });
124
243
 
125
- const client = new QuickNodeSDK();
244
+ qn.nfts
245
+ .getNFTDetails({
246
+ contractAddress: '0x2106C00Ac7dA0A3430aE667879139E832307AeAa',
247
+ tokenId: '1',
248
+ })
249
+ .then((response) => console.log(response));
250
+ ```
126
251
 
127
- client.nft
252
+ <br>
253
+
254
+ ### nfts.getCollectionDetails
255
+
256
+ Returns the details for an NFT Collection
257
+
258
+ | Argument | Values | Required | Description | Example |
259
+ | --------------- | ------ | -------- | -------------------- | ------------------------------------------ |
260
+ | contractAddress | string | ✅ | NFT contract address | 0x2106C00Ac7dA0A3430aE667879139E832307AeAa |
261
+ | chain | string | ❌ | Blockchain name | polygon |
262
+
263
+ ```ts
264
+ import QuickNode from '@quicknode/sdk';
265
+
266
+ const qn = new QuickNode.API({
267
+ gqlApiKey: 'my-api-key', // which is obtained by signing up on https://www.quicknode.com/signup
268
+ });
269
+
270
+ qn.nfts
128
271
  .getCollectionDetails({
129
- address: '0x2106C00Ac7dA0A3430aE667879139E832307AeAa',
272
+ contractAddress: '0x2106C00Ac7dA0A3430aE667879139E832307AeAa',
130
273
  })
131
274
  .then((response) => console.log(response));
132
275
  ```
133
276
 
134
- ### nft.getNFTEventLogs
277
+ <br>
278
+
279
+ ### nfts.verifyOwnership
280
+
281
+ Check if the wallet address is an owner of any of the provided NFT contract addresses. Returns a boolean if they own and NFT from _any_ of the provided contract addresses.
282
+
283
+ | Argument | Values | Required | Description | Example |
284
+ | -------- | ------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
285
+ | address | string | ✅ | Address or ENS name of wallet to check as owner | 0x3C6aEFF92b4B35C2e1b196B57d0f8FFB56884A17 |
286
+ | nfts | array | ✅ | an array of objects with `contractAddress` and optional `tokenId` to check ownership of. Ownership is verified if any of the parameters are owned by the wallet | [{ contractAddress: "0x2106C00Ac7dA0A3430aE667879139E832307AeAa" }] |
287
+ | chain | string | ❌ | Blockchain name | polygon |
135
288
 
136
- | Argument | Values | Optional | Description | Example |
137
- | -------- | ------ | -------- | --------------------------------------------------------------------------------- | ------------------------------------------ |
138
- | address | string | ❌ | Contract address of NFT | 0x2106C00Ac7dA0A3430aE667879139E832307AeAa |
139
- | tokenId | string | ❌ | NFT ID | 100 |
140
- | types | array | ✅ | An array of event types 'TRANSFER', 'ORDER', and/or 'MINT'. Defaults to all types | ['TRANSFER', 'ORDER', 'MINT] |
141
- | first | number | ✅ | Number of results to return | 10 |
142
- | after | string | ✅ | Return results after end cursor | YXJyYXljb25uZWN0aW9uOjUwNQ= |
289
+ ```typescript
290
+ import QuickNode from '@quicknode/sdk';
291
+
292
+ const qn = new QuickNode.API({
293
+ graphApiKey: 'my-api-key', // which is obtained by signing up on https://www.quicknode.com/signup
294
+ });
295
+
296
+ // returns true if wallet owns at least one NFT of 0x2106C00Ac7dA0A3430aE667879139E832307AeAa
297
+ qn.nfts
298
+ .verifyOwnership({
299
+ address: '0xD10E24685c7CDD3cd3BaAA86b09C92Be28c834B6',
300
+ nfts: [
301
+ {
302
+ contractAddress: '0x2106C00Ac7dA0A3430aE667879139E832307AeAa',
303
+ },
304
+ ],
305
+ })
306
+ .then((response) => console.log(response));
307
+
308
+ // returns true if quicknode.eth owns the exact NFT id 123 from contract address 0x2106C00Ac7dA0A3430aE667879139E832307AeAa
309
+ qn.nfts
310
+ .verifyOwnership({
311
+ address: 'quicknode.eth', // or wallet address
312
+ nfts: [
313
+ {
314
+ contractAddress: '0x2106C00Ac7dA0A3430aE667879139E832307AeAa',
315
+ tokenId: '123',
316
+ },
317
+ ],
318
+ })
319
+ .then((response) => console.log(response));
320
+
321
+ // returns true if quicknode.eth owns an NFT from either 0x2106C00Ac7dA0A3430aE667879139E832307AeAa or 0x9D90669665607F08005CAe4A7098143f554c59EF
322
+ qn.nfts
323
+ .verifyOwnership({
324
+ address: 'quicknode.eth', // or wallet address
325
+ nfts: [
326
+ {
327
+ contractAddress: '0x2106C00Ac7dA0A3430aE667879139E832307AeAa',
328
+ },
329
+ {
330
+ contractAddress: '0x9D90669665607F08005CAe4A7098143f554c59EF',
331
+ },
332
+ ],
333
+ })
334
+ .then((response) => console.log(response));
335
+ ```
336
+
337
+ <br>
338
+
339
+ ### tokens.getBalancesByWallet
340
+
341
+ Returns ERC20 token balances for a wallet
342
+
343
+ | Argument | Values | Required | Description | Example |
344
+ | -------- | ------ | -------- | ---------------------------- | ------------------------------------------ |
345
+ | address | string | ✅ | Wallet address or ENS domain | 0x3C6aEFF92b4B35C2e1b196B57d0f8FFB56884A17 |
346
+ | first | number | ❌ | Number of results to return | 10 |
347
+ | before | string | ❌ | Return results before cursor | T2Zmc2V0Q29ubmVjdGlvbjow |
348
+ | after | string | ❌ | Return results after cursor | T2Zmc2V0Q29ubmVjdGlvbjo2 |
349
+ | chain | string | ❌ | Blockchain name | polygon |
143
350
 
144
351
  ```ts
145
- import { QuickNodeSDK } from '@quicknode/sdk';
352
+ import QuickNode from '@quicknode/sdk';
146
353
 
147
- const client = new QuickNodeSDK();
354
+ const qn = new QuickNode.API({
355
+ graphApiKey: 'my-api-key', // which is obtained by signing up on https://www.quicknode.com/signup
356
+ });
357
+
358
+ qn.tokens
359
+ .getBalancesByWallet({
360
+ address: '0xd10e24685c7cdd3cd3baaa86b09c92be28c834b6',
361
+ first: 5,
362
+ })
363
+ .then((response) => console.log(response));
148
364
 
149
- client.nft
150
- .getNFTEventLogs({
151
- address: '0x60E4d786628Fea6478F785A6d7e704777c86a7c6',
152
- tokenId: '100',
153
- types: ['TRANSFER', 'ORDER'],
365
+ // Can pass in ENS domain
366
+ qn.tokens
367
+ .getBalancesByWallet({
368
+ address: 'quicknode.eth',
369
+ first: 5,
154
370
  })
155
371
  .then((response) => console.log(response));
156
372
  ```
157
373
 
158
- ### nft.getNFTDetails
374
+ <br>
375
+
376
+ ### contracts.getDetails
159
377
 
160
- Returns the details for a single NFT
161
- | Argument | Values | Optional | Description | Example |
162
- | --------------- | ------ | -------- | --------------------------------- | ------------------------------------------ |
163
- | contractAddress | string | | Contract address of NFT Collection | 0x2106C00Ac7dA0A3430aE667879139E832307AeAa |
164
- | tokenId | string | | NFT ID | 5020 |
378
+ Get the details and ABI for a contract address
379
+
380
+ | Argument | Values | Required | Description | Example |
381
+ | --------------- | ------ | -------- | ---------------- | ------------------------------------------ |
382
+ | contractAddress | string | | contract address | 0x2106C00Ac7dA0A3430aE667879139E832307AeAa |
383
+ | chain | string | ❌ | Blockchain name | polygon |
165
384
 
166
385
  ```ts
167
- import { QuickNodeSDK } from '@quicknode/sdk';
386
+ import QuickNode, { gql } from '@quicknode/sdk';
168
387
 
169
- const client = new QuickNodeSDK();
388
+ const qn = new QuickNode.API({
389
+ graphApiKey: 'my-api-key', // which is obtained by signing up on https://www.quicknode.com/signup
390
+ });
170
391
 
171
- client.nft
172
- .getNFTDetails({
173
- contractAddress: '0x23581767a106ae21c074b2276D25e5C3e136a68b',
174
- tokenId: '400',
392
+ qn.contracts
393
+ .getDetails({
394
+ contractAddress: '0x2106C00Ac7dA0A3430aE667879139E832307AeAa',
175
395
  })
176
396
  .then((response) => console.log(response));
177
397
  ```
178
398
 
179
- ### nft.getContractEventLogs
399
+ <br>
400
+
401
+ ### transactions.getByWallet
180
402
 
181
- Returns the log events for a NFT contract
403
+ Returns transactions for a wallet
182
404
 
183
- | Argument | Values | Optional | Description | Example |
184
- | -------- | ------ | -------- | --------------------------------------------------------------------------------- | ------------------------------------------ |
185
- | address | string | | Contract address of NFT | 0x2106C00Ac7dA0A3430aE667879139E832307AeAa |
186
- | types | array | | An array of event types 'TRANSFER', 'ORDER', and/or 'MINT'. Defaults to all types | ['TRANSFER', 'ORDER', 'MINT] |
187
- | first | number | | Number of results to return | 10 |
188
- | after | string | | Return results after end cursor | YXJyYXljb25uZWN0aW9uOjUwNQ= |
405
+ | Argument | Values | Required | Description | Example |
406
+ | -------- | ------ | -------- | ---------------------------- | ------------------------------------------ |
407
+ | address | string | | Wallet address or ENS domain | 0x3C6aEFF92b4B35C2e1b196B57d0f8FFB56884A17 |
408
+ | first | number | | Number of results to return | 10 |
409
+ | before | string | | Return results before cursor | T2Zmc2V0Q29ubmVjdGlvbjow |
410
+ | after | string | | Return results after cursor | T2Zmc2V0Q29ubmVjdGlvbjo2 |
411
+ | chain | string | ❌ | Blockchain name | polygon |
189
412
 
190
413
  ```ts
191
- import { QuickNodeSDK } from '@quicknode/sdk';
414
+ import QuickNode from '@quicknode/sdk';
192
415
 
193
- const client = new QuickNodeSDK();
416
+ const qn = new QuickNode.API({
417
+ graphApiKey: 'my-api-key', // which is obtained by signing up on https://www.quicknode.com/signup
418
+ });
194
419
 
195
- client.nft
196
- .getContractEventLogs({
197
- address: '0x60E4d786628Fea6478F785A6d7e704777c86a7c6',
198
- types: ['TRANSFER', 'ORDER'],
420
+ qn.transactions
421
+ .getByWallet({
422
+ address: '0xd10e24685c7cdd3cd3baaa86b09c92be28c834b6',
423
+ first: 5,
424
+ })
425
+ .then((response) => console.log(response));
426
+
427
+ // Can pass in ENS domain
428
+ qn.transactions
429
+ .getByWallet({
430
+ address: 'quicknode.eth',
431
+ first: 5,
199
432
  })
200
433
  .then((response) => console.log(response));
201
434
  ```
202
435
 
203
- ### nft.getNFTsByWalletAndContracts
436
+ <br>
437
+
438
+ ### transactions.getAll
439
+
440
+ Returns transactions filtered by search parameters
441
+
442
+ | Argument | Values | Required | Description | Example |
443
+ | -------- | ------ | -------- | --------------------------------------------------- | ------------------------------- |
444
+ | first | number | ❌ | Number of results to return | 10 |
445
+ | before | string | ❌ | Return results before cursor | T2Zmc2V0Q29ubmVjdGlvbjow |
446
+ | after | string | ❌ | Return results after cursor | T2Zmc2V0Q29ubmVjdGlvbjo2 |
447
+ | chain | string | ❌ | Blockchain name | polygon |
448
+ | filter | object | ✅ | An object with the optional filters for the request | { blockNumber: { eq: 123456 } } |
449
+
450
+ `filter` Parameters
204
451
 
205
- Gets NFTs from specified collections held by a wallet
452
+ | Argument | Values | Description | Example |
453
+ | ----------- | ------ | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------- |
454
+ | fromAddress | string | Filter transactions sent from address | fromAddress: "0xD10E24685c7CDD3cd3BaAA86b09C92Be28c834B6" |
455
+ | toAddress | string | Filter transactions sent to address | toAddress: "0xD10E24685c7CDD3cd3BaAA86b09C92Be28c834B6" |
456
+ | blockNumber | object | An object with any combination of `eq`, `gt`, `gte`, `in`, `lt`, or `lte` | { lt: 17343891, gt: 17343881 } |
457
+ | timestamp | object | An object with any combination of `eq`, `gt`, `gte`, `in`, `lt`, or `lte` with a valid timestamp | { lt: "2022-12-03T10:15:30Z" } |
206
458
 
207
- | Argument | Values | Optional | Description | Example |
208
- | --------- | ---------------- | -------- | ------------------------------- | ---------------------------------------------- |
209
- | address | string | ❌ | Wallet address | 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 |
210
- | contracts | array of strings | ❌ | NFT contract addresses | ['0xba30e5f9bb24caa003e9f2f0497ad287fdf95623'] |
211
- | first | number | ✅ | Number of results to return | 10 |
212
- | after | string | ✅ | Return results after end cursor | YXJyYXljb25uZWN0aW9uOjUwNQ= |
459
+ _timestamp can be a date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the date-time format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar._
213
460
 
214
461
  ```ts
215
- import { QuickNodeSDK } from '@quicknode/sdk';
462
+ import QuickNode from '@quicknode/sdk';
216
463
 
217
- const client = new QuickNodeSDK();
464
+ const qn = new QuickNode.API({
465
+ graphApiKey: 'my-api-key', // which is obtained by signing up on https://www.quicknode.com/signup
466
+ });
218
467
 
219
- client.nft
220
- .getNFTsByWalletAndContracts({
221
- address: '0x13928eb9a86c8278a45b6ff2935c7730b58ac675',
222
- contracts: [
223
- '0xba30e5f9bb24caa003e9f2f0497ad287fdf95623',
224
- '0xbce3781ae7ca1a5e050bd9c4c77369867ebc307e',
225
- ],
468
+ // Use the filters
469
+ qn.transactions
470
+ .getAll({
471
+ filter: {
472
+ blockNumber: {
473
+ eq: 17372310,
474
+ },
475
+ fromAddress: '0x41407a3c41da7970d30a0343cda8b9db70c145fb',
476
+ },
477
+ })
478
+ .then((response) => console.log(response));
479
+
480
+ // Filters can be left blank to get the latest data
481
+ qn.transactions.getAll({ filter: {}, first: 5 }).then((response) => console.log(response));
482
+ ```
483
+
484
+ <br>
485
+
486
+ ### transactions.getByHash
487
+
488
+ Returns transaction information by transaction hash
489
+
490
+ | Argument | Values | Required | Description | Example |
491
+ | -------- | ------ | -------- | ----------------------- | ------------------------------------------------------------------ |
492
+ | hash | string | ✅ | Hash of the transaction | 0x1aa26d1d542b414dd2e2d1aa6f8d8e128e2a45bc4a04c24232207221914389bf |
493
+
494
+ ```ts
495
+ import QuickNode from '@quicknode/sdk';
496
+
497
+ const qn = new QuickNode.API({
498
+ graphApiKey: 'my-api-key', // which is obtained by signing up on https://www.quicknode.com/signup
499
+ });
500
+
501
+ qn.transactions
502
+ .getByHash({
503
+ hash: '0x1aa26d1d542b414dd2e2d1aa6f8d8e128e2a45bc4a04c24232207221914389bf',
504
+ })
505
+ .then((response) => console.log(response));
506
+ ```
507
+
508
+ <br>
509
+
510
+ ### events.getByContract
511
+
512
+ Returns events by contract address
513
+
514
+ | Argument | Values | Required | Description | Example |
515
+ | -------- | ------ | -------- | --------------------------------------------------- | ------------------------------- |
516
+ | first | number | ❌ | Number of results to return | 10 |
517
+ | before | string | ❌ | Return results before cursor | T2Zmc2V0Q29ubmVjdGlvbjow |
518
+ | after | string | ❌ | Return results after cursor | T2Zmc2V0Q29ubmVjdGlvbjo2 |
519
+ | chain | string | ❌ | Blockchain name | polygon |
520
+ | filter | object | ❌ | An object with the optional filters for the request | { blockNumber: { eq: 123456 } } |
521
+
522
+ `filter` Parameters
523
+
524
+ Please see the [Token Event Filters section](#token-event-filters) for all options
525
+
526
+ ```typescript
527
+ import QuickNode from '@quicknode/sdk';
528
+
529
+ const qn = new QuickNode.API({
530
+ graphApiKey: 'my-api-key', // which is obtained by signing up on https://www.quicknode.com/signup
531
+ });
532
+
533
+ qn.events
534
+ .getByContract({
535
+ contractAddress: '0x2106C00Ac7dA0A3430aE667879139E832307AeAa',
536
+ })
537
+ .then((response) => console.log(response));
538
+
539
+ // Using filters
540
+ qn.events
541
+ .getByContract({
542
+ contractAddress: '0x2106C00Ac7dA0A3430aE667879139E832307AeAa',
543
+ filter: {
544
+ fromAddress: {
545
+ eq: '0x10fa1c188eca954419a85112f975155f717ad8ea',
546
+ },
547
+ type: {
548
+ in: ['TRANSFER'],
549
+ },
550
+ }
551
+ })
552
+ .then((response) => console.log(response));
553
+ `
554
+ ```
555
+
556
+ <br>
557
+
558
+ ### events.getByNFTCollection
559
+
560
+ Returns the events for an NFT Collection
561
+
562
+ | Argument | Values | Required | Description | Example |
563
+ | --------------- | ------ | -------- | --------------------------------------------------- | ------------------------------------------ |
564
+ | contractAddress | string | ✅ | NFT contract address | 0x2106C00Ac7dA0A3430aE667879139E832307AeAa |
565
+ | chain | string | ❌ | Blockchain name | polygon |
566
+ | first | number | ❌ | Number of results to return | 10 |
567
+ | before | string | ❌ | Return results before cursor | T2Zmc2V0Q29ubmVjdGlvbjow |
568
+ | after | string | ❌ | Return results after cursor | T2Zmc2V0Q29ubmVjdGlvbjo2 |
569
+ | filter | object | ❌ | An object with the optional filters for the request | { blockNumber: { eq: 123456 } } |
570
+
571
+ `filter` Parameters
572
+
573
+ Please see the [Token Event Filters section](#token-event-filters) for all options
574
+
575
+ ```ts
576
+ import QuickNode from '@quicknode/sdk';
577
+
578
+ const qn = new QuickNode.API({
579
+ graphApiKey: 'my-api-key', // which is obtained by signing up on https://www.quicknode.com/signup
580
+ });
581
+
582
+ qn.events
583
+ .getByNFTCollection({
584
+ contractAddress: '0x2106C00Ac7dA0A3430aE667879139E832307AeAa',
585
+ first: 5,
586
+ })
587
+ .then((response) => console.log(response));
588
+
589
+ // Can pass in filters
590
+ qn.events
591
+ .getByNftCollection({
592
+ contractAddress: '0x2106C00Ac7dA0A3430aE667879139E832307AeAa',
593
+ first: 5,
594
+ filter: {
595
+ type: {
596
+ eq: 'TRANSFER',
597
+ },
598
+ },
599
+ })
600
+ .then((response) => console.log(response));
601
+ ```
602
+
603
+ <br>
604
+
605
+ ### events.getByNFT
606
+
607
+ Returns the events for a specific NFT
608
+
609
+ | Argument | Values | Required | Description | Example |
610
+ | --------------- | ------ | -------- | --------------------------------------------------- | ------------------------------------------ |
611
+ | contractAddress | string | ✅ | NFT contract address | 0x2106C00Ac7dA0A3430aE667879139E832307AeAa |
612
+ | tokenId | string | ✅ | NFT Token ID | 1 |
613
+ | chain | string | ❌ | Blockchain name | polygon |
614
+ | first | number | ❌ | Number of results to return | 10 |
615
+ | before | string | ❌ | Return results before cursor | T2Zmc2V0Q29ubmVjdGlvbjow |
616
+ | after | string | ❌ | Return results after cursor | T2Zmc2V0Q29ubmVjdGlvbjo2 |
617
+ | filter | object | ❌ | An object with the optional filters for the request | { blockNumber: { eq: 123456 } } |
618
+
619
+ `filter` Parameters
620
+
621
+ Please see the [Token Event Filters section](#token-event-filters) for all options
622
+
623
+ ```ts
624
+ import QuickNode from '@quicknode/sdk';
625
+
626
+ const qn = new QuickNode.API({
627
+ graphApiKey: 'my-api-key', // which is obtained by signing up on https://www.quicknode.com/signup
628
+ });
629
+
630
+ qn.events
631
+ .getByNFT({
632
+ contractAddress: '0x2106C00Ac7dA0A3430aE667879139E832307AeAa',
633
+ tokenId: '1',
634
+ })
635
+ .then((response) => console.log(response));
636
+
637
+ qn.events
638
+ .getByNFT({
639
+ contractAddress: '0x2106C00Ac7dA0A3430aE667879139E832307AeAa',
640
+ tokenId: '1',
641
+ filter: {
642
+ type: {
643
+ eq: 'TRANSFER',
644
+ },
645
+ },
226
646
  })
227
647
  .then((response) => console.log(response));
228
648
  ```
229
649
 
230
- ### nft.getTrendingNFTCollections
650
+ <br>
651
+
652
+ ### events.getAll
231
653
 
232
- | Argument | Values | Optional | Description | Example |
233
- | -------------- | --------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- |
234
- | first | number | | Number of results to return | 10 |
235
- | after | string | | Return results after end cursor | YXJyYXljb25uZWN0aW9uOjUwNQ= |
236
- | orderBy | TrendingCollectionsOrderByEnum | | Sort contracts by average sale price ('AVERAGE'), number of sales ('SALES') or volume ('VOLUME') | 'AVERAGE' |
237
- | orderDirection | OrderDirectionEnum | | Sort results ascending ('ASC') or descending ('DESC') | 'ASC' |
238
- | timePeriod | TrendingCollectionsTimePeriodEnum | | Get results from last hour ('ONE_HOUR'), last 12 hours ('TWELVE_HOURS') results, last day ('ONE_DAY') or last 7 days ('SEVEN_DAYS') | 'ONE_HOUR' |
239
- | timeRange | DateInputType | | Define the modifier in which `timePeriod` will take action to. It can be equal to ('eq'), greater than ('gt'), greater than or equal to ('gte'), less than ('lt') or less than or equal to ('lte') | 'gt' |
654
+ Returns events filtered by search parameters
655
+
656
+ | Argument | Values | Required | Description | Example |
657
+ | -------- | ------ | -------- | --------------------------------------------------- | ------------------------------- |
658
+ | chain | string | | Blockchain name | polygon |
659
+ | first | number | | Number of results to return | 10 |
660
+ | before | string | | Return results before cursor | T2Zmc2V0Q29ubmVjdGlvbjow |
661
+ | after | string | | Return results after cursor | T2Zmc2V0Q29ubmVjdGlvbjo2 |
662
+ | filter | object | ❌ | An object with the optional filters for the request | { blockNumber: { eq: 123456 } } |
663
+
664
+ `filter` Parameters
665
+
666
+ Please see the [Token Event Filters section](#token-event-filters) for all options
240
667
 
241
668
  ```ts
242
- import { QuickNodeSDK } from '@quicknode/sdk';
669
+ import QuickNode from '@quicknode/sdk';
243
670
 
244
- const client = new QuickNodeSDK();
671
+ const qn = new QuickNode.API({
672
+ graphApiKey: 'my-api-key', // which is obtained by signing up on https://www.quicknode.com/signup
673
+ });
245
674
 
246
- client.nft
247
- .getTrendingNFTCollections({
248
- first: 10,
675
+ // Use filters to get specific events
676
+ qn.events
677
+ .getAll({
678
+ first: 2,
679
+ filter: {
680
+ blockNumber: {
681
+ eq: 17414768,
682
+ },
683
+ toAddress: {
684
+ eq: '0xef1c6e67703c7bd7107eed8303fbe6ec2554bf6b',
685
+ },
686
+ },
249
687
  })
250
688
  .then((response) => console.log(response));
689
+
690
+ // Filters can be left blank to get the latest data
691
+ qn.events.getAll({}).then((response) => console.log(response));
251
692
  ```
252
693
 
694
+ <br>
695
+
696
+ ### utils.getGasPrices
697
+
698
+ Returns historical gas prices by block number. Defaults to returning values in wei.
699
+
700
+ | Argument | Values | Required | Description | Example |
701
+ | ------------ | ------- | -------- | --------------------------------------------------- | --------------------------------- |
702
+ | chain | string | ❌ | Blockchain name | polygon |
703
+ | returnInGwei | boolean | ❌ | Return gas values in Gwei | true |
704
+ | filter | object | ❌ | An object with the optional filters for the request | { blockNumber: { eq: 17343891 } } |
705
+
706
+ `filter` Parameters
707
+
708
+ | Argument | Values | Description | Example |
709
+ | ----------- | ------ | ------------------------------------------------------------------------- | ------------------------------ |
710
+ | blockNumber | object | An object with any combination of `eq`, `gt`, `gte`, `in`, `lt`, or `lte` | { lt: 17343891, gt: 17343881 } |
711
+
712
+ ```ts
713
+ import QuickNode from '@quicknode/sdk';
714
+
715
+ const qn = new QuickNode.API({
716
+ graphApiKey: 'my-api-key', // which is obtained by signing up on https://www.quicknode.com/signup
717
+ });
718
+
719
+ // Get the latest data
720
+ qn.utils.getGasPrices({}).then((response) => console.log(response));
721
+
722
+ // Get filtered data
723
+ qn.utils
724
+ .getGasPrices({
725
+ filter: {
726
+ blockNumber: {
727
+ eq: 17343891,
728
+ },
729
+ },
730
+ })
731
+ .then((response) => console.log(response));
732
+ ```
733
+
734
+ <br>
735
+
736
+ ### graphApiClient.query
737
+
738
+ A way to send GraphQL queries directly to the [QuickNode GraphQL API](https://www.quicknode.com/graph-api). `graphApiClient` is an [Urql client](https://formidable.com/open-source/urql/docs/api/core/#client) instance configured to use QuickNode's Graph API. For more information about the query structure, see the [Graph API documentation](https://docs.quicknode.com/docs/graphql/getting-started/)
739
+
740
+ ```ts
741
+ import QuickNode, { gql } from '@quicknode/sdk';
742
+
743
+ const qn = new QuickNode.API({
744
+ graphApiKey: 'my-api-key', // which is obtained by signing up on https://www.quicknode.com/signup
745
+ });
746
+
747
+ const query = gql`
748
+ query ($contractAddress: String!) {
749
+ ethereum {
750
+ collection(contractAddress: $contractAddress) {
751
+ address
752
+ name
753
+ symbol
754
+ totalSupply
755
+ }
756
+ }
757
+ }
758
+ `;
759
+ const variables = {
760
+ contractAddress: '0x2106c00ac7da0a3430ae667879139e832307aeaa',
761
+ };
762
+
763
+ qn.graphApiClient.query({ query, variables }).then(({ data }) => console.log(data));
764
+ ```
765
+
766
+ <br>
767
+
768
+ ### Error handling
769
+
770
+ The input to API functions is validated at runtime in order to handle both untyped JavaScript input and user input in end user applications. In short, this will help prevent you sending invalid Graph API queries because of bad input. The validation is done by [zod](https://www.npmjs.com/package/zod) under the hood and we expose the errors to you in a `QNInputValidationError` instance.
771
+
772
+ For example, you can handle these errors:
773
+
774
+ ```typescript
775
+ import QuickNode from '@quicknode/sdk';
776
+
777
+ const qn = new QuickNode.API({ graphApiKey: 'my-api-key' });
778
+
779
+ // Inside async function
780
+ try {
781
+ const eventsByContract = await events.getByContract({
782
+ contractAddress: userInput, // Input comes from the user, we don't know what will be here
783
+ });
784
+ return eventsByContract;
785
+ } catch (error) {
786
+ if (error instanceof QNInputValidationError) {
787
+ console.error(error.stack);
788
+ return { errors: error.issues }; // Return formatted issues to handle as needed by UI or user
789
+ } else {
790
+ // handle unexpected errors here
791
+ }
792
+ }
793
+ ```
794
+
795
+ The `QNInputValidationError` instance has the following properties:
796
+
797
+ | Property | Type | Description |
798
+ | -------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
799
+ | messages | string[] | An array of concise error messages |
800
+ | zodError | ZodError | The full `ZodError` instance, see [the Zod error handling docs](https://github.com/colinhacks/zod/blob/master/ERROR_HANDLING.md) for more information |
801
+ | issues | ZodIssue[] | An array of [Zod Issue](https://github.com/colinhacks/zod/blob/master/ERROR_HANDLING.md#zodissue) instances, which is a formatted error data structure |
802
+
803
+ <br>
804
+
805
+ ## Filters
806
+
807
+ Some filters are shared between queries
808
+
809
+ <br>
810
+
811
+ ### Token Event Filters
812
+
813
+ | Argument | Values | Description | Example |
814
+ | ---------------- | ------ | --------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
815
+ | blockNumber | object | An object with any combination of `eq`, `gt`, `gte`, `in`, `lt`, or `lte` | { lt: 17343891, gt: 17343881 } |
816
+ | contractAddress | object | A contract address with `eq`, `in`, or `notIn` | { eq: "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984" } |
817
+ | contractStandard | object | A valid contract standard `ERC20`, `ERC721`, `ERC1155` with `eq`, `in`, or `notIn` | { eq: "ERC20" } |
818
+ | fromAddress | object | Filter events sent from address with `eq`, `in`, or `notIn` | { eq: "0xD10E24685c7CDD3cd3BaAA86b09C92Be28c834B6" } |
819
+ | marketplace | object | `BLUR`, `CRYPTOPUNKS`, `LOOKSRARE`, `NIFTY_GATEWAY`, `OPENSEA`, `SEAPORT`, `X2Y2`, `ZEROX` with with `eq`, `in`, or `notIn` | { eq: "OPENSEA" } |
820
+ | timestamp | object | An object with any combination of `eq`, `gt`, `gte`, `in`, `lt`, or `lte` with a valid timestamp | { lt: "2022-12-03T10:15:30Z" } |
821
+ | toAddress | object | Filter events sent to address with `eq`, `in`, or `notIn` | { eq: "0xD10E24685c7CDD3cd3BaAA86b09C92Be28c834B6" } |
822
+ | transactionHash | object | A transaction hash with with `eq`, `in`, or `notIn` | { eq: "0xdd652cfd936f7a22ab217a69c1f4356a6d15a4c8d61e30d87a4cd8abca30046f" } |
823
+ | type | object | `TRANSFER`, `MINT`, `SALE`, `SWAP`, or `BURN` with `eq`, `in`, or `notIn` | { in: ["TRANSFER", "MINT"] } |
824
+ | walletAddress | object | A valid wallet address with `eq`, `in`, or `notIn` | { eq: "0xD10E24685c7CDD3cd3BaAA86b09C92Be28c834B6" } |
825
+
826
+ _timestamp can be a date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the date-time format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar._
827
+
828
+ <br>
829
+
253
830
  ## Pagination
254
831
 
255
832
  For functions that support pagination, use the `first` property to specify the amount of results to return.
@@ -261,10 +838,13 @@ The returned `data.tokensPageInfo.endCursor` property in the response can be use
261
838
  For example, if a response contains:
262
839
 
263
840
  ```json
264
- "data": {
265
- "tokensPageInfo": {
841
+ {
842
+ "results": [...],
843
+ "pageInfo": {
844
+ "endCursor": "T2Zmc2V0Q29ubmVjdGlvbjox",
266
845
  "hasNextPage": true,
267
- "endCursor": 'YXJyYXljb25uZWN0aW9uOlk='
846
+ "hasPreviousPage": false,
847
+ "startCursor": "T2Zmc2V0Q29ubmVjdGlvbjow"
268
848
  }
269
849
  }
270
850
  ```
@@ -272,31 +852,77 @@ For example, if a response contains:
272
852
  calling the following will get the next page of results
273
853
 
274
854
  ```typescript
275
- client.nft.getNFTsByWalletENS({
276
- ensName: 'vitalik.eth',
277
- first: 5,
278
- after: 'YXJyYXljb25uZWN0aW9uOlk=', // from data.tokensPageInfo.endCursor in response
855
+ qn.nfts.getByWallet({
856
+ address: 'quicknode.eth',
857
+ after: 'T2Zmc2V0Q29ubmVjdGlvbjox', // Using the endCursor
858
+ });
859
+ ```
860
+
861
+ You can do the same with `before` and return the results before the specified cursor if `hasPreviousPage` is true
862
+
863
+ For example, if the response contains the following:
864
+
865
+ ```json
866
+ {
867
+ "results": [...],
868
+ "pageInfo": {
869
+ "endCursor": "T2Zmc2V0Q29ubmVjdGlvbjo2",
870
+ "hasNextPage": true,
871
+ "hasPreviousPage": true,
872
+ "startCursor": "T2Zmc2V0Q29ubmVjdGlvbjoy"
873
+ }
874
+ }
875
+ ```
876
+
877
+ calling the following will get the previous page of results
878
+
879
+ ```typescript
880
+ qn.nfts.getByWallet({
881
+ address: 'quicknode.eth',
882
+ before: 'T2Zmc2V0Q29ubmVjdGlvbjoy', // Using the startCursor
279
883
  });
280
884
  ```
281
885
 
282
- # Contributing corner
886
+ <br>
887
+
888
+ ## Contributing corner
889
+
890
+ ### Issues
891
+
892
+ Please submit any issues or feature requests as an [issue in Github](https://github.com/quiknode-labs/qn-oss/issues).
893
+
894
+ <br>
895
+
896
+ ### Development
897
+
898
+ We recommend using the example application to develop
899
+
900
+ 1. In `qn-oss` monorepo root directory, run `yarn install`
901
+ 1. cd `packages/apps/examples/sdk-api` from `qn-oss` monorepo root
902
+ 1. `cp .env.example .env` and add api key
903
+ 1. `nx serve apps-examples-sdk-api`
904
+ 1. Then you can send requests to the API, for example: `curl http://localhost:3333/api/nftsByAddress/0xbc08dadccc79c00587d7e6a75bb68ff5fd30f9e0`
283
905
 
284
- ## Issues
906
+ <br>
907
+
908
+ ### Running tests
285
909
 
286
- Please submit any questions, issues, or feedback as an [issue in Github](https://github.com/quiknode-labs/qn-oss/issues).
910
+ Run `nx test libs-sdk` to execute the tests via [Jest](https://jestjs.io).
287
911
 
288
- ## Building
912
+ API responses are recorded using [polly.js](https://github.com/Netflix/pollyjs). You can re-record live requests by passing in an API key, copy `.env.test.example` to `.env.test` and fill out with your API key.
289
913
 
290
- Run `nx build libs-api-sdk` to build the library.
914
+ <br>
291
915
 
292
- ## Running unit tests
916
+ ### Running linting
293
917
 
294
- Run `nx test libs-api-sdk` to execute the unit tests via [Jest](https://jestjs.io).
918
+ Run `nx lint libs-sdk` to execute the lint via [ESLint](https://eslint.org/).
295
919
 
296
- ## Running lint
920
+ <br>
297
921
 
298
- Run `nx lint libs-api-sdk` to execute the lint via [ESLint](https://eslint.org/).
922
+ ### Generate graphql codegen typings
299
923
 
300
- ## Generate graphql
924
+ Generate graphql typings via [Codegen](https://www.the-guild.dev/graphql/codegen).
301
925
 
302
- Run `yarn codegen` to generate graphql typings via [Codegen](https://www.the-guild.dev/graphql/codegen).
926
+ 1. navigate to `packages/libs/sdk` from `qn-oss` monorepo root
927
+ 1. `cp .env.example .env` and add api key
928
+ 1. run `yarn run codegen`