@quicknode/sdk 2.6.0 → 3.0.0-alpha.11
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 +212 -46
- package/browser.js +9 -0
- package/errors.js +121 -0
- package/index.d.ts +2286 -650
- package/index.darwin-arm64.node +0 -0
- package/index.js +328 -0
- package/index.linux-arm64-gnu.node +0 -0
- package/index.linux-arm64-musl.node +0 -0
- package/index.linux-x64-gnu.node +0 -0
- package/index.linux-x64-musl.node +0 -0
- package/package.json +48 -54
- package/sdk.d.ts +389 -0
- package/sdk.js +88 -0
- package/sdk.mjs +34 -0
- package/cjs/index.js +0 -542
- package/cjs/package.json +0 -3
- package/esm/client/client.js +0 -9
- package/esm/client/index.js +0 -2
- package/esm/core/addOns/nftTokenV2/actions.js +0 -107
- package/esm/core/addOns/nftTokenV2/types/qn_fetchNFTCollectionDetails.js +0 -10
- package/esm/core/addOns/nftTokenV2/types/qn_fetchNFTs.js +0 -13
- package/esm/core/addOns/nftTokenV2/types/qn_fetchNFTsByCollection.js +0 -13
- package/esm/core/addOns/nftTokenV2/types/qn_getTokenMetadataByContractAddress.js +0 -10
- package/esm/core/addOns/nftTokenV2/types/qn_getTokenMetadataBySymbol.js +0 -11
- package/esm/core/addOns/nftTokenV2/types/qn_getTransactionsByAddress.js +0 -18
- package/esm/core/addOns/nftTokenV2/types/qn_getTransfersByNFT.js +0 -12
- package/esm/core/addOns/nftTokenV2/types/qn_getWalletTokenBalance.js +0 -12
- package/esm/core/addOns/nftTokenV2/types/qn_getWalletTokenTransactions.js +0 -14
- package/esm/core/addOns/nftTokenV2/types/qn_verifyNFTsOwner.js +0 -11
- package/esm/core/addOns/shared/helpers.js +0 -10
- package/esm/core/chains.js +0 -118
- package/esm/core/core.js +0 -30
- package/esm/core/index.d.ts +0 -558
- package/esm/core/index.js +0 -2
- package/esm/index.js +0 -11
- package/esm/lib/constants.js +0 -4
- package/esm/lib/errors/QNChainNotSupported.js +0 -7
- package/esm/lib/errors/QNInputValidationError.js +0 -10
- package/esm/lib/errors/QNInvalidEnpointUrl.js +0 -7
- package/esm/lib/helpers/getClientHeaders.js +0 -11
- package/esm/lib/helpers/globalFetch.js +0 -13
- package/esm/lib/validation/ValidateInput.js +0 -16
- package/esm/lib/validation/validators.js +0 -15
- package/esm/package.json +0 -4
- package/esm/solana/index.d.ts +0 -76
- package/esm/solana/index.js +0 -2
- package/esm/solana/solana.js +0 -111
package/cjs/index.js
DELETED
|
@@ -1,542 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
|
-
var viem = require('viem');
|
|
6
|
-
var zod = require('zod');
|
|
7
|
-
var chains = require('viem/chains');
|
|
8
|
-
var fetch$1 = require('cross-fetch');
|
|
9
|
-
var web3_js = require('@solana/web3.js');
|
|
10
|
-
|
|
11
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
12
|
-
|
|
13
|
-
function _interopNamespace(e) {
|
|
14
|
-
if (e && e.__esModule) return e;
|
|
15
|
-
var n = Object.create(null);
|
|
16
|
-
if (e) {
|
|
17
|
-
Object.keys(e).forEach(function (k) {
|
|
18
|
-
if (k !== 'default') {
|
|
19
|
-
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
20
|
-
Object.defineProperty(n, k, d.get ? d : {
|
|
21
|
-
enumerable: true,
|
|
22
|
-
get: function () { return e[k]; }
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
n["default"] = e;
|
|
28
|
-
return Object.freeze(n);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
var viem__namespace = /*#__PURE__*/_interopNamespace(viem);
|
|
32
|
-
var fetch__default = /*#__PURE__*/_interopDefaultLegacy(fetch$1);
|
|
33
|
-
var web3_js__namespace = /*#__PURE__*/_interopNamespace(web3_js);
|
|
34
|
-
|
|
35
|
-
class QNInputValidationError extends Error {
|
|
36
|
-
constructor({ messages, zodError, }) {
|
|
37
|
-
super(`QuickNode SDK Input Validation Error: ${messages.join(', ')}`);
|
|
38
|
-
this.messages = messages;
|
|
39
|
-
this.issues = zodError.issues;
|
|
40
|
-
this.zodError = zodError; // see https://github.com/colinhacks/zod/blob/HEAD/ERROR_HANDLING.md
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
class QNInvalidEndpointUrl extends Error {
|
|
45
|
-
constructor() {
|
|
46
|
-
super('Endpoint URL is not in a valid QuickNode URL format. Please check the URL and try again');
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
class QNChainNotSupported extends Error {
|
|
51
|
-
constructor(endpointUrl) {
|
|
52
|
-
super(`The chain for endpoint URL ${endpointUrl} is not currently supported by the QuickNode SDK.`);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function formatErrors(baseError) {
|
|
57
|
-
const errorMessages = [];
|
|
58
|
-
baseError.errors.forEach((error) => {
|
|
59
|
-
errorMessages.push(`${error.path.length > 0 ? error.path + ': ' : ''}${error.message}`);
|
|
60
|
-
});
|
|
61
|
-
return errorMessages.length > 0
|
|
62
|
-
? new QNInputValidationError({
|
|
63
|
-
messages: errorMessages,
|
|
64
|
-
zodError: baseError,
|
|
65
|
-
})
|
|
66
|
-
: null;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// We can't dynamically extend the viem client based on which add-ons are specified, which would
|
|
70
|
-
// make the types fully align with the add-ons for the client, so instead we do run-time checks to
|
|
71
|
-
// prevent calling add-ons not explicitly added in the config
|
|
72
|
-
function checkAddOnEnabled(enabled, humanName, configName) {
|
|
73
|
-
if (!enabled) {
|
|
74
|
-
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`);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const isEvmAddress = zod.z
|
|
79
|
-
.string()
|
|
80
|
-
.length(42) // Using built-in function for better error messages
|
|
81
|
-
.startsWith('0x') // Using built-in function for better error messages
|
|
82
|
-
.regex(/^0x[a-fA-F0-9]{40}$/, 'Not a valid address');
|
|
83
|
-
const rpcPaginationParams = zod.z
|
|
84
|
-
.object({
|
|
85
|
-
perPage: zod.z.number().positive().nullish(),
|
|
86
|
-
page: zod.z.number().positive().nullish(),
|
|
87
|
-
})
|
|
88
|
-
.strict();
|
|
89
|
-
|
|
90
|
-
const qnFetchNFTInputSchema = zod.z
|
|
91
|
-
.object({
|
|
92
|
-
wallet: isEvmAddress,
|
|
93
|
-
contracts: zod.z.array(isEvmAddress).nullish(),
|
|
94
|
-
omitFields: zod.z.array(zod.z.string()).nullish(),
|
|
95
|
-
})
|
|
96
|
-
.merge(rpcPaginationParams)
|
|
97
|
-
.strict();
|
|
98
|
-
|
|
99
|
-
const qnFetchNFTCollectionDetailsInputSchema = zod.z
|
|
100
|
-
.object({
|
|
101
|
-
contracts: zod.z.array(isEvmAddress),
|
|
102
|
-
})
|
|
103
|
-
.strict();
|
|
104
|
-
|
|
105
|
-
const qnFetchNFTsByCollectionInputSchema = zod.z
|
|
106
|
-
.object({
|
|
107
|
-
collection: isEvmAddress,
|
|
108
|
-
tokens: zod.z.array(zod.z.string()).nullish(),
|
|
109
|
-
omitFields: zod.z.array(zod.z.string()).nullish(),
|
|
110
|
-
})
|
|
111
|
-
.merge(rpcPaginationParams)
|
|
112
|
-
.strict();
|
|
113
|
-
|
|
114
|
-
const qnGetTransfersByNFTInputSchema = zod.z
|
|
115
|
-
.object({
|
|
116
|
-
collection: isEvmAddress,
|
|
117
|
-
collectionTokenId: zod.z.string(),
|
|
118
|
-
})
|
|
119
|
-
.merge(rpcPaginationParams)
|
|
120
|
-
.strict();
|
|
121
|
-
|
|
122
|
-
const qnVerifyNFTsOwnerInputSchema = zod.z
|
|
123
|
-
.object({
|
|
124
|
-
wallet: isEvmAddress,
|
|
125
|
-
contracts: zod.z.array(zod.z.string()), // TODO: make this enforce the address:id format
|
|
126
|
-
})
|
|
127
|
-
.strict();
|
|
128
|
-
|
|
129
|
-
const qnGetTokenMetadataByCAInputSchema = zod.z
|
|
130
|
-
.object({
|
|
131
|
-
contract: isEvmAddress,
|
|
132
|
-
})
|
|
133
|
-
.strict();
|
|
134
|
-
|
|
135
|
-
const qnGetTokenMetadataBySymbolInputSchema = zod.z
|
|
136
|
-
.object({
|
|
137
|
-
symbol: zod.z.string(),
|
|
138
|
-
})
|
|
139
|
-
.merge(rpcPaginationParams)
|
|
140
|
-
.strict();
|
|
141
|
-
|
|
142
|
-
const qnGetTransactionsByAddressInputSchema = zod.z
|
|
143
|
-
.object({
|
|
144
|
-
address: isEvmAddress,
|
|
145
|
-
fromBlock: zod.z.number().positive().nullish(),
|
|
146
|
-
toBlock: zod.z.number().positive().nullish(),
|
|
147
|
-
})
|
|
148
|
-
.merge(rpcPaginationParams)
|
|
149
|
-
.strict()
|
|
150
|
-
.refine(({ fromBlock, toBlock }) => {
|
|
151
|
-
if (fromBlock && toBlock)
|
|
152
|
-
return fromBlock < toBlock;
|
|
153
|
-
return true;
|
|
154
|
-
}, { message: 'fromBlock must be less than toBlock' });
|
|
155
|
-
|
|
156
|
-
const qnGetWalletTokenBalanceInputSchema = zod.z
|
|
157
|
-
.object({
|
|
158
|
-
wallet: isEvmAddress,
|
|
159
|
-
contracts: zod.z.array(isEvmAddress).nullish(),
|
|
160
|
-
})
|
|
161
|
-
.merge(rpcPaginationParams)
|
|
162
|
-
.strict();
|
|
163
|
-
|
|
164
|
-
const qnGetWalletTokenTransactionsInputSchema = zod.z
|
|
165
|
-
.object({
|
|
166
|
-
address: isEvmAddress,
|
|
167
|
-
contract: isEvmAddress,
|
|
168
|
-
fromBlock: zod.z.number().positive().nullish(),
|
|
169
|
-
toBlock: zod.z.number().positive().nullish(),
|
|
170
|
-
})
|
|
171
|
-
.merge(rpcPaginationParams)
|
|
172
|
-
.strict();
|
|
173
|
-
|
|
174
|
-
function nftAndTokenValidator(config, schema, args) {
|
|
175
|
-
checkAddOnEnabled(config.addOns?.nftTokenV2 ?? false, 'NFT And Token RPC API V2', 'nftTokenV2');
|
|
176
|
-
// Uses zod to validate schema at runtime
|
|
177
|
-
const validation = schema.safeParse(args);
|
|
178
|
-
if (!validation.success) {
|
|
179
|
-
const formattedErrors = formatErrors(validation.error);
|
|
180
|
-
if (formattedErrors)
|
|
181
|
-
throw formattedErrors;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
const nftAndTokenActions = (client, config) => ({
|
|
185
|
-
async qn_fetchNFTCollectionDetails(args) {
|
|
186
|
-
nftAndTokenValidator(config, qnFetchNFTCollectionDetailsInputSchema, args);
|
|
187
|
-
const response = await client.request({
|
|
188
|
-
method: 'qn_fetchNFTCollectionDetails',
|
|
189
|
-
params: [args],
|
|
190
|
-
});
|
|
191
|
-
return response;
|
|
192
|
-
},
|
|
193
|
-
async qn_fetchNFTs(args) {
|
|
194
|
-
nftAndTokenValidator(config, qnFetchNFTInputSchema, args);
|
|
195
|
-
const response = await client.request({
|
|
196
|
-
method: 'qn_fetchNFTs',
|
|
197
|
-
params: [args],
|
|
198
|
-
});
|
|
199
|
-
return response;
|
|
200
|
-
},
|
|
201
|
-
async qn_fetchNFTsByCollection(args) {
|
|
202
|
-
nftAndTokenValidator(config, qnFetchNFTsByCollectionInputSchema, args);
|
|
203
|
-
const response = await client.request({
|
|
204
|
-
method: 'qn_fetchNFTsByCollection',
|
|
205
|
-
params: [args],
|
|
206
|
-
});
|
|
207
|
-
return response;
|
|
208
|
-
},
|
|
209
|
-
async qn_getTransfersByNFT(args) {
|
|
210
|
-
nftAndTokenValidator(config, qnGetTransfersByNFTInputSchema, args);
|
|
211
|
-
const response = await client.request({
|
|
212
|
-
method: 'qn_getTransfersByNFT',
|
|
213
|
-
params: [args],
|
|
214
|
-
});
|
|
215
|
-
return response;
|
|
216
|
-
},
|
|
217
|
-
async qn_verifyNFTsOwner(args) {
|
|
218
|
-
nftAndTokenValidator(config, qnVerifyNFTsOwnerInputSchema, args);
|
|
219
|
-
const response = await client.request({
|
|
220
|
-
method: 'qn_verifyNFTsOwner',
|
|
221
|
-
params: [args],
|
|
222
|
-
});
|
|
223
|
-
return response;
|
|
224
|
-
},
|
|
225
|
-
async qn_getTokenMetadataByContractAddress(args) {
|
|
226
|
-
nftAndTokenValidator(config, qnGetTokenMetadataByCAInputSchema, args);
|
|
227
|
-
const response = await client.request({
|
|
228
|
-
method: 'qn_getTokenMetadataByContractAddress',
|
|
229
|
-
params: [args],
|
|
230
|
-
});
|
|
231
|
-
return response;
|
|
232
|
-
},
|
|
233
|
-
async qn_getTokenMetadataBySymbol(args) {
|
|
234
|
-
nftAndTokenValidator(config, qnGetTokenMetadataBySymbolInputSchema, args);
|
|
235
|
-
const response = await client.request({
|
|
236
|
-
method: 'qn_getTokenMetadataBySymbol',
|
|
237
|
-
params: [args],
|
|
238
|
-
});
|
|
239
|
-
return response;
|
|
240
|
-
},
|
|
241
|
-
async qn_getTransactionsByAddress(args) {
|
|
242
|
-
nftAndTokenValidator(config, qnGetTransactionsByAddressInputSchema, args);
|
|
243
|
-
const response = await client.request({
|
|
244
|
-
method: 'qn_getTransactionsByAddress',
|
|
245
|
-
params: [args],
|
|
246
|
-
});
|
|
247
|
-
return response;
|
|
248
|
-
},
|
|
249
|
-
async qn_getWalletTokenBalance(args) {
|
|
250
|
-
nftAndTokenValidator(config, qnGetWalletTokenBalanceInputSchema, args);
|
|
251
|
-
const response = await client.request({
|
|
252
|
-
method: 'qn_getWalletTokenBalance',
|
|
253
|
-
params: [args],
|
|
254
|
-
});
|
|
255
|
-
return response;
|
|
256
|
-
},
|
|
257
|
-
async qn_getWalletTokenTransactions(args) {
|
|
258
|
-
nftAndTokenValidator(config, qnGetWalletTokenTransactionsInputSchema, args);
|
|
259
|
-
const response = await client.request({
|
|
260
|
-
method: 'qn_getWalletTokenTransactions',
|
|
261
|
-
params: [args],
|
|
262
|
-
});
|
|
263
|
-
return response;
|
|
264
|
-
},
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
const ETH_MAINNET_NETWORK = 'ethereum-mainnet';
|
|
268
|
-
const qnChainToViemChain = {
|
|
269
|
-
'arbitrum-mainnet': chains.arbitrum,
|
|
270
|
-
'arbitrum-goerli': chains.arbitrumGoerli,
|
|
271
|
-
'arbitrum-sepolia': chains.arbitrumSepolia,
|
|
272
|
-
'arbitrum-nova': chains.arbitrumNova,
|
|
273
|
-
'avalanche-mainnet': chains.avalanche,
|
|
274
|
-
'avalanche-testnet': chains.avalancheFuji,
|
|
275
|
-
'base-mainnet': chains.base,
|
|
276
|
-
'base-goerli': chains.baseGoerli,
|
|
277
|
-
'base-sepolia': chains.baseSepolia,
|
|
278
|
-
'bera-artio': chains.berachainTestnet,
|
|
279
|
-
'blast-mainnet': chains.blast,
|
|
280
|
-
'blast-sepolia': chains.blastSepolia,
|
|
281
|
-
['bsc']: chains.bsc,
|
|
282
|
-
'bsc-testnet': chains.bscTestnet,
|
|
283
|
-
'celo-mainnet': chains.celo,
|
|
284
|
-
'cyber-mainnet': chains.cyber,
|
|
285
|
-
'cyber-sepolia': chains.cyberTestnet,
|
|
286
|
-
['fantom']: chains.fantom,
|
|
287
|
-
['xdai']: chains.gnosis,
|
|
288
|
-
['gnosis']: chains.gnosis,
|
|
289
|
-
'ethereum-goerli': chains.goerli,
|
|
290
|
-
'harmony-mainnet': chains.harmonyOne,
|
|
291
|
-
[ETH_MAINNET_NETWORK]: chains.mainnet, // The URL doesn't actually contain this
|
|
292
|
-
'mantle-mainnet': chains.mantle,
|
|
293
|
-
'mantle-sepolia': chains.mantleSepoliaTestnet,
|
|
294
|
-
['optimism']: chains.optimism,
|
|
295
|
-
'optimism-goerli': chains.optimismGoerli,
|
|
296
|
-
'optimism-sepolia': chains.optimismSepolia,
|
|
297
|
-
['matic']: chains.polygon,
|
|
298
|
-
['polygon']: chains.polygon,
|
|
299
|
-
'scroll-mainnet': chains.scroll,
|
|
300
|
-
'scroll-testnet': chains.scrollSepolia,
|
|
301
|
-
'matic-testnet': chains.polygonMumbai,
|
|
302
|
-
'matic-amoy': chains.polygonAmoy,
|
|
303
|
-
'zkevm-mainnet': chains.polygonZkEvm,
|
|
304
|
-
'zkevm-testnet': chains.polygonZkEvmTestnet,
|
|
305
|
-
'sei-pacific': chains.sei,
|
|
306
|
-
'sei-arctic': chains.seiDevnet,
|
|
307
|
-
'ethereum-sepolia': chains.sepolia,
|
|
308
|
-
'ethereum-holesky': chains.holesky,
|
|
309
|
-
'0g-mainnet': chains.zeroGMainnet,
|
|
310
|
-
'0g-galileo': chains.zeroGTestnet,
|
|
311
|
-
'abstract-testnet': chains.abstractTestnet,
|
|
312
|
-
'abstract-mainnet': chains.abstract,
|
|
313
|
-
'b3-mainnet': chains.b3,
|
|
314
|
-
'b3-sepolia': chains.b3Sepolia,
|
|
315
|
-
'flare-mainnet': chains.flare,
|
|
316
|
-
'flare-coston2': chains.flareTestnet,
|
|
317
|
-
'gravity-alpham': chains.gravity,
|
|
318
|
-
'hemi-testnet': chains.hemiSepolia,
|
|
319
|
-
'hemi-mainnet': chains.hemi,
|
|
320
|
-
'hype-testnet': chains.hyperliquidEvmTestnet,
|
|
321
|
-
'imx-testnet': chains.immutableZkEvmTestnet,
|
|
322
|
-
'imx-mainnet': chains.immutableZkEvm,
|
|
323
|
-
'ink-mainnet': chains.ink,
|
|
324
|
-
'ink-sepolia': chains.inkSepolia,
|
|
325
|
-
'joc-mainnet': chains.jocMainnet,
|
|
326
|
-
'kaia-kairos': chains.kairos,
|
|
327
|
-
'kaia-mainnet': chains.kaia,
|
|
328
|
-
'linea-mainnet': chains.linea,
|
|
329
|
-
'monad-mainnet': chains.monad,
|
|
330
|
-
'monad-testnet': chains.monadTestnet,
|
|
331
|
-
'morph-mainnet': chains.morph,
|
|
332
|
-
'nomina-mainnet': chains.nomina,
|
|
333
|
-
'peaq-mainnet': chains.peaq,
|
|
334
|
-
'plasma-testnet': chains.plasmaTestnet,
|
|
335
|
-
'plasma-mainnet': chains.plasma,
|
|
336
|
-
'soneium-mainnet': chains.soneium,
|
|
337
|
-
'sonic-mainnet': chains.sonic,
|
|
338
|
-
'story-aeneid': chains.storyAeneid,
|
|
339
|
-
'story-mainnet': chains.story,
|
|
340
|
-
'unichain-mainnet': chains.unichain,
|
|
341
|
-
'unichain-sepolia': chains.unichainSepolia,
|
|
342
|
-
'vana-moksha': chains.vanaMoksha,
|
|
343
|
-
'vana-mainnet': chains.vana,
|
|
344
|
-
'worldchain-mainnet': chains.worldchain,
|
|
345
|
-
'worldchain-sepolia': chains.worldchainSepolia,
|
|
346
|
-
'xai-mainnet': chains.xai,
|
|
347
|
-
'xai-testnet': chains.xaiTestnet,
|
|
348
|
-
'xlayer-mainnet': chains.xLayer,
|
|
349
|
-
};
|
|
350
|
-
function chainNameFromEndpoint(endpointUrl) {
|
|
351
|
-
let hostnameParts;
|
|
352
|
-
try {
|
|
353
|
-
const parsedUrl = new URL(endpointUrl);
|
|
354
|
-
hostnameParts = parsedUrl.hostname.split('.');
|
|
355
|
-
}
|
|
356
|
-
catch (e) {
|
|
357
|
-
throw new QNInvalidEndpointUrl();
|
|
358
|
-
}
|
|
359
|
-
const quiknode = hostnameParts.at(-2);
|
|
360
|
-
const chainOrDiscover = hostnameParts.at(-3);
|
|
361
|
-
if (quiknode !== 'quiknode' || !chainOrDiscover)
|
|
362
|
-
throw new QNInvalidEndpointUrl();
|
|
363
|
-
const indexOfName = chainOrDiscover === 'discover' ? -4 : -3;
|
|
364
|
-
const lengthOfEthereum = chainOrDiscover === 'discover' ? 4 : 3;
|
|
365
|
-
if (hostnameParts.length === lengthOfEthereum)
|
|
366
|
-
return ETH_MAINNET_NETWORK;
|
|
367
|
-
const potentialChainName = hostnameParts.at(indexOfName);
|
|
368
|
-
if (potentialChainName)
|
|
369
|
-
return potentialChainName;
|
|
370
|
-
throw new QNInvalidEndpointUrl();
|
|
371
|
-
}
|
|
372
|
-
function deriveChainFromUrl(endpointUrl) {
|
|
373
|
-
const chainName = chainNameFromEndpoint(endpointUrl);
|
|
374
|
-
const viemChain = qnChainToViemChain[chainName];
|
|
375
|
-
if (viemChain)
|
|
376
|
-
return viemChain;
|
|
377
|
-
throw new QNChainNotSupported(endpointUrl);
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
function setupGlobalFetch() {
|
|
381
|
-
// Required for viem to work in node
|
|
382
|
-
if (!globalThis.fetch) {
|
|
383
|
-
globalThis.fetch = fetch__default["default"];
|
|
384
|
-
globalThis.Headers = fetch$1.Headers;
|
|
385
|
-
globalThis.Request = fetch$1.Request;
|
|
386
|
-
globalThis.Response = fetch$1.Response;
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
// Ideally we read directly from package.json, but ran into some packaging issues with that
|
|
391
|
-
const PACKAGE_VERSION = '2.6.0';
|
|
392
|
-
|
|
393
|
-
// Headers to use in RPC clients
|
|
394
|
-
function getClientHeaders() {
|
|
395
|
-
const packageVersion = PACKAGE_VERSION ;
|
|
396
|
-
return {
|
|
397
|
-
'x-qn-sdk-version': packageVersion,
|
|
398
|
-
};
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
const buildQNActions = (config) => {
|
|
402
|
-
return (client) => ({
|
|
403
|
-
...nftAndTokenActions(client, config),
|
|
404
|
-
});
|
|
405
|
-
};
|
|
406
|
-
class Core {
|
|
407
|
-
constructor({ endpointUrl, chain, config = {} }) {
|
|
408
|
-
setupGlobalFetch();
|
|
409
|
-
const clientHeaders = getClientHeaders();
|
|
410
|
-
this.endpointUrl = endpointUrl;
|
|
411
|
-
const baseClient = viem.createClient({
|
|
412
|
-
chain: chain || deriveChainFromUrl(endpointUrl),
|
|
413
|
-
transport: viem.http(this.endpointUrl, {
|
|
414
|
-
fetchOptions: {
|
|
415
|
-
headers: clientHeaders,
|
|
416
|
-
},
|
|
417
|
-
}),
|
|
418
|
-
}).extend(viem.publicActions);
|
|
419
|
-
const qnClient = baseClient.extend(buildQNActions(config));
|
|
420
|
-
this.client = qnClient;
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
// eslint-disable-next-line @nx/enforce-module-boundaries
|
|
425
|
-
class Solana {
|
|
426
|
-
constructor({ endpointUrl }) {
|
|
427
|
-
const clientHeaders = getClientHeaders();
|
|
428
|
-
this.endpointUrl = endpointUrl;
|
|
429
|
-
this.connection = new web3_js.Connection(endpointUrl, {
|
|
430
|
-
httpHeaders: clientHeaders,
|
|
431
|
-
});
|
|
432
|
-
}
|
|
433
|
-
/**
|
|
434
|
-
* Sends a transaction with a dynamically generated priority fee based on the current network conditions and compute units needed by the transaction.
|
|
435
|
-
*/
|
|
436
|
-
async sendSmartTransaction(args) {
|
|
437
|
-
const { transaction, keyPair, feeLevel = 'medium', sendTransactionOptions = {}, } = args;
|
|
438
|
-
const smartTransaction = await this.prepareSmartTransaction({
|
|
439
|
-
transaction,
|
|
440
|
-
payerPublicKey: keyPair.publicKey,
|
|
441
|
-
feeLevel,
|
|
442
|
-
});
|
|
443
|
-
smartTransaction.sign(keyPair);
|
|
444
|
-
const hash = await this.connection.sendRawTransaction(transaction.serialize(), { skipPreflight: true, ...sendTransactionOptions });
|
|
445
|
-
return hash;
|
|
446
|
-
}
|
|
447
|
-
/**
|
|
448
|
-
* Prepares a transaction to be sent with a dynamically generated priority fee based
|
|
449
|
-
* on the current network conditions. It adds a `setComputeUnitPrice` instruction to the transaction
|
|
450
|
-
* and simulates the transaction to estimate the number of compute units it will consume.
|
|
451
|
-
* The returned transaction still needs to be signed and sent to the network.
|
|
452
|
-
*/
|
|
453
|
-
async prepareSmartTransaction(args) {
|
|
454
|
-
const { transaction, payerPublicKey, feeLevel = 'medium' } = args;
|
|
455
|
-
// Send simulation with placeholders so the value calculated is accurate
|
|
456
|
-
// placeholders kept low to avoid InsufficientFundsForFee error with the high cu budget limit
|
|
457
|
-
const simulationInstructions = [
|
|
458
|
-
web3_js.ComputeBudgetProgram.setComputeUnitPrice({
|
|
459
|
-
microLamports: 1,
|
|
460
|
-
}),
|
|
461
|
-
web3_js.ComputeBudgetProgram.setComputeUnitLimit({ units: 1_400_000 }),
|
|
462
|
-
...transaction.instructions,
|
|
463
|
-
];
|
|
464
|
-
// eslint-disable-next-line prefer-const
|
|
465
|
-
let [units, computeUnitPriceInstruction, recentBlockhash] = await Promise.all([
|
|
466
|
-
this.getSimulationUnits(this.connection, simulationInstructions, payerPublicKey),
|
|
467
|
-
this.createDynamicPriorityFeeInstruction(feeLevel),
|
|
468
|
-
this.connection.getLatestBlockhash(),
|
|
469
|
-
]);
|
|
470
|
-
transaction.add(computeUnitPriceInstruction);
|
|
471
|
-
if (units) {
|
|
472
|
-
units = Math.ceil(units * 1.05); // margin of error
|
|
473
|
-
transaction.add(web3_js.ComputeBudgetProgram.setComputeUnitLimit({ units }));
|
|
474
|
-
}
|
|
475
|
-
transaction.recentBlockhash = recentBlockhash.blockhash;
|
|
476
|
-
return transaction;
|
|
477
|
-
}
|
|
478
|
-
// Get the priority fee averages based on fee data from the latest blocks
|
|
479
|
-
async fetchEstimatePriorityFees(args = {}) {
|
|
480
|
-
const payload = {
|
|
481
|
-
method: 'qn_estimatePriorityFees',
|
|
482
|
-
params: { api_version: 2, ...args },
|
|
483
|
-
id: 1,
|
|
484
|
-
jsonrpc: '2.0',
|
|
485
|
-
};
|
|
486
|
-
const response = await fetch(this.endpointUrl, {
|
|
487
|
-
method: 'POST',
|
|
488
|
-
headers: {
|
|
489
|
-
'Content-Type': 'application/json',
|
|
490
|
-
},
|
|
491
|
-
body: JSON.stringify(payload),
|
|
492
|
-
});
|
|
493
|
-
if (!response.ok) {
|
|
494
|
-
if (response.status === 404) {
|
|
495
|
-
throw new Error(`The RPC method qn_estimatePriorityFees was not found on your endpoint! Your endpoint likely does not have the Priority Fee API add-on installed. Please visit https://marketplace.quicknode.com/add-on/solana-priority-fee to install the Priority Fee API and use this method to send your transactions with priority fees calculated with real-time data.`);
|
|
496
|
-
}
|
|
497
|
-
throw new Error('Failed to fetch priority fee estimates');
|
|
498
|
-
}
|
|
499
|
-
const data = await response.json();
|
|
500
|
-
return data;
|
|
501
|
-
}
|
|
502
|
-
async createDynamicPriorityFeeInstruction(feeType = 'medium') {
|
|
503
|
-
const { result } = await this.fetchEstimatePriorityFees({});
|
|
504
|
-
const priorityFee = feeType === 'recommended'
|
|
505
|
-
? result.recommended
|
|
506
|
-
: result.per_compute_unit[feeType];
|
|
507
|
-
const priorityFeeInstruction = web3_js.ComputeBudgetProgram.setComputeUnitPrice({
|
|
508
|
-
microLamports: priorityFee,
|
|
509
|
-
});
|
|
510
|
-
return priorityFeeInstruction;
|
|
511
|
-
}
|
|
512
|
-
async getSimulationUnits(connection, instructions, publicKey) {
|
|
513
|
-
const testVersionedTxn = new web3_js.VersionedTransaction(new web3_js.TransactionMessage({
|
|
514
|
-
instructions: instructions,
|
|
515
|
-
payerKey: publicKey,
|
|
516
|
-
recentBlockhash: web3_js.PublicKey.default.toString(), // just a placeholder
|
|
517
|
-
}).compileToV0Message());
|
|
518
|
-
const simulation = await connection.simulateTransaction(testVersionedTxn, {
|
|
519
|
-
replaceRecentBlockhash: true,
|
|
520
|
-
sigVerify: false,
|
|
521
|
-
});
|
|
522
|
-
if (simulation.value.err) {
|
|
523
|
-
console.error('Simulation error:', simulation.value.err);
|
|
524
|
-
throw new Error(`Failed to simulate transaction ${JSON.stringify(simulation.value.err)}`);
|
|
525
|
-
}
|
|
526
|
-
return simulation.value.unitsConsumed;
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
const QuickNode = {
|
|
531
|
-
Core: Core,
|
|
532
|
-
Solana: Solana,
|
|
533
|
-
};
|
|
534
|
-
|
|
535
|
-
exports.viem = viem__namespace;
|
|
536
|
-
exports.solanaWeb3 = web3_js__namespace;
|
|
537
|
-
exports.Core = Core;
|
|
538
|
-
exports.QNChainNotSupported = QNChainNotSupported;
|
|
539
|
-
exports.QNInputValidationError = QNInputValidationError;
|
|
540
|
-
exports.QNInvalidEndpointUrl = QNInvalidEndpointUrl;
|
|
541
|
-
exports.Solana = Solana;
|
|
542
|
-
exports["default"] = QuickNode;
|
package/cjs/package.json
DELETED
package/esm/client/client.js
DELETED
package/esm/client/index.js
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { formatErrors } from '../../../lib/validation/ValidateInput.js';
|
|
2
|
-
import { checkAddOnEnabled } from '../shared/helpers.js';
|
|
3
|
-
import { qnFetchNFTInputSchema } from './types/qn_fetchNFTs.js';
|
|
4
|
-
import { qnFetchNFTCollectionDetailsInputSchema } from './types/qn_fetchNFTCollectionDetails.js';
|
|
5
|
-
import { qnFetchNFTsByCollectionInputSchema } from './types/qn_fetchNFTsByCollection.js';
|
|
6
|
-
import { qnGetTransfersByNFTInputSchema } from './types/qn_getTransfersByNFT.js';
|
|
7
|
-
import { qnVerifyNFTsOwnerInputSchema } from './types/qn_verifyNFTsOwner.js';
|
|
8
|
-
import { qnGetTokenMetadataByCAInputSchema } from './types/qn_getTokenMetadataByContractAddress.js';
|
|
9
|
-
import { qnGetTokenMetadataBySymbolInputSchema } from './types/qn_getTokenMetadataBySymbol.js';
|
|
10
|
-
import { qnGetTransactionsByAddressInputSchema } from './types/qn_getTransactionsByAddress.js';
|
|
11
|
-
import { qnGetWalletTokenBalanceInputSchema } from './types/qn_getWalletTokenBalance.js';
|
|
12
|
-
import { qnGetWalletTokenTransactionsInputSchema } from './types/qn_getWalletTokenTransactions.js';
|
|
13
|
-
|
|
14
|
-
function nftAndTokenValidator(config, schema, args) {
|
|
15
|
-
checkAddOnEnabled(config.addOns?.nftTokenV2 ?? false, 'NFT And Token RPC API V2', 'nftTokenV2');
|
|
16
|
-
// Uses zod to validate schema at runtime
|
|
17
|
-
const validation = schema.safeParse(args);
|
|
18
|
-
if (!validation.success) {
|
|
19
|
-
const formattedErrors = formatErrors(validation.error);
|
|
20
|
-
if (formattedErrors)
|
|
21
|
-
throw formattedErrors;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
const nftAndTokenActions = (client, config) => ({
|
|
25
|
-
async qn_fetchNFTCollectionDetails(args) {
|
|
26
|
-
nftAndTokenValidator(config, qnFetchNFTCollectionDetailsInputSchema, args);
|
|
27
|
-
const response = await client.request({
|
|
28
|
-
method: 'qn_fetchNFTCollectionDetails',
|
|
29
|
-
params: [args],
|
|
30
|
-
});
|
|
31
|
-
return response;
|
|
32
|
-
},
|
|
33
|
-
async qn_fetchNFTs(args) {
|
|
34
|
-
nftAndTokenValidator(config, qnFetchNFTInputSchema, args);
|
|
35
|
-
const response = await client.request({
|
|
36
|
-
method: 'qn_fetchNFTs',
|
|
37
|
-
params: [args],
|
|
38
|
-
});
|
|
39
|
-
return response;
|
|
40
|
-
},
|
|
41
|
-
async qn_fetchNFTsByCollection(args) {
|
|
42
|
-
nftAndTokenValidator(config, qnFetchNFTsByCollectionInputSchema, args);
|
|
43
|
-
const response = await client.request({
|
|
44
|
-
method: 'qn_fetchNFTsByCollection',
|
|
45
|
-
params: [args],
|
|
46
|
-
});
|
|
47
|
-
return response;
|
|
48
|
-
},
|
|
49
|
-
async qn_getTransfersByNFT(args) {
|
|
50
|
-
nftAndTokenValidator(config, qnGetTransfersByNFTInputSchema, args);
|
|
51
|
-
const response = await client.request({
|
|
52
|
-
method: 'qn_getTransfersByNFT',
|
|
53
|
-
params: [args],
|
|
54
|
-
});
|
|
55
|
-
return response;
|
|
56
|
-
},
|
|
57
|
-
async qn_verifyNFTsOwner(args) {
|
|
58
|
-
nftAndTokenValidator(config, qnVerifyNFTsOwnerInputSchema, args);
|
|
59
|
-
const response = await client.request({
|
|
60
|
-
method: 'qn_verifyNFTsOwner',
|
|
61
|
-
params: [args],
|
|
62
|
-
});
|
|
63
|
-
return response;
|
|
64
|
-
},
|
|
65
|
-
async qn_getTokenMetadataByContractAddress(args) {
|
|
66
|
-
nftAndTokenValidator(config, qnGetTokenMetadataByCAInputSchema, args);
|
|
67
|
-
const response = await client.request({
|
|
68
|
-
method: 'qn_getTokenMetadataByContractAddress',
|
|
69
|
-
params: [args],
|
|
70
|
-
});
|
|
71
|
-
return response;
|
|
72
|
-
},
|
|
73
|
-
async qn_getTokenMetadataBySymbol(args) {
|
|
74
|
-
nftAndTokenValidator(config, qnGetTokenMetadataBySymbolInputSchema, args);
|
|
75
|
-
const response = await client.request({
|
|
76
|
-
method: 'qn_getTokenMetadataBySymbol',
|
|
77
|
-
params: [args],
|
|
78
|
-
});
|
|
79
|
-
return response;
|
|
80
|
-
},
|
|
81
|
-
async qn_getTransactionsByAddress(args) {
|
|
82
|
-
nftAndTokenValidator(config, qnGetTransactionsByAddressInputSchema, args);
|
|
83
|
-
const response = await client.request({
|
|
84
|
-
method: 'qn_getTransactionsByAddress',
|
|
85
|
-
params: [args],
|
|
86
|
-
});
|
|
87
|
-
return response;
|
|
88
|
-
},
|
|
89
|
-
async qn_getWalletTokenBalance(args) {
|
|
90
|
-
nftAndTokenValidator(config, qnGetWalletTokenBalanceInputSchema, args);
|
|
91
|
-
const response = await client.request({
|
|
92
|
-
method: 'qn_getWalletTokenBalance',
|
|
93
|
-
params: [args],
|
|
94
|
-
});
|
|
95
|
-
return response;
|
|
96
|
-
},
|
|
97
|
-
async qn_getWalletTokenTransactions(args) {
|
|
98
|
-
nftAndTokenValidator(config, qnGetWalletTokenTransactionsInputSchema, args);
|
|
99
|
-
const response = await client.request({
|
|
100
|
-
method: 'qn_getWalletTokenTransactions',
|
|
101
|
-
params: [args],
|
|
102
|
-
});
|
|
103
|
-
return response;
|
|
104
|
-
},
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
export { nftAndTokenActions };
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import { isEvmAddress } from '../../../../lib/validation/validators.js';
|
|
3
|
-
|
|
4
|
-
const qnFetchNFTCollectionDetailsInputSchema = z
|
|
5
|
-
.object({
|
|
6
|
-
contracts: z.array(isEvmAddress),
|
|
7
|
-
})
|
|
8
|
-
.strict();
|
|
9
|
-
|
|
10
|
-
export { qnFetchNFTCollectionDetailsInputSchema };
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import { isEvmAddress, rpcPaginationParams } from '../../../../lib/validation/validators.js';
|
|
3
|
-
|
|
4
|
-
const qnFetchNFTInputSchema = z
|
|
5
|
-
.object({
|
|
6
|
-
wallet: isEvmAddress,
|
|
7
|
-
contracts: z.array(isEvmAddress).nullish(),
|
|
8
|
-
omitFields: z.array(z.string()).nullish(),
|
|
9
|
-
})
|
|
10
|
-
.merge(rpcPaginationParams)
|
|
11
|
-
.strict();
|
|
12
|
-
|
|
13
|
-
export { qnFetchNFTInputSchema };
|