tx-indexer 0.4.0 → 0.4.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 +36 -3
- package/dist/{classification.types-DlJe6bDZ.d.ts → classification.types-Cn9IGtEC.d.ts} +13 -12
- package/dist/{client-yGDWPKKf.d.ts → client-iLW2_DnL.d.ts} +39 -3
- package/dist/client.d.ts +2 -2
- package/dist/client.js +129 -5
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +130 -6
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -28,8 +28,42 @@ const txs = await indexer.getTransactions("YourWalletAddress...", {
|
|
|
28
28
|
filterSpam: true
|
|
29
29
|
});
|
|
30
30
|
|
|
31
|
-
// Get single transaction
|
|
32
|
-
const tx = await indexer.getTransaction("signature..."
|
|
31
|
+
// Get single transaction (no wallet required)
|
|
32
|
+
const tx = await indexer.getTransaction("signature...");
|
|
33
|
+
|
|
34
|
+
// Classification includes sender/receiver
|
|
35
|
+
console.log(tx.classification.primaryType); // "transfer", "swap", "nft_mint", etc.
|
|
36
|
+
console.log(tx.classification.sender); // sender address
|
|
37
|
+
console.log(tx.classification.receiver); // receiver address
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Transaction Types
|
|
41
|
+
|
|
42
|
+
- `transfer` - Wallet-to-wallet transfers
|
|
43
|
+
- `swap` - Token exchanges (Jupiter, Raydium, Orca)
|
|
44
|
+
- `nft_mint` - NFT minting (Metaplex, Candy Machine, Bubblegum)
|
|
45
|
+
- `stake_deposit` - SOL staking deposits
|
|
46
|
+
- `stake_withdraw` - SOL staking withdrawals
|
|
47
|
+
- `bridge_in` - Receiving from bridge (Wormhole, deBridge, Allbridge)
|
|
48
|
+
- `bridge_out` - Sending to bridge
|
|
49
|
+
- `airdrop` - Token distributions
|
|
50
|
+
- `fee_only` - Transactions with only network fees
|
|
51
|
+
|
|
52
|
+
## Frontend Integration
|
|
53
|
+
|
|
54
|
+
Classification is wallet-agnostic. Determine perspective in your frontend:
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
const { classification } = await indexer.getTransaction(signature);
|
|
58
|
+
const connectedWallet = wallet?.address;
|
|
59
|
+
|
|
60
|
+
if (connectedWallet === classification.sender) {
|
|
61
|
+
// "You sent..."
|
|
62
|
+
} else if (connectedWallet === classification.receiver) {
|
|
63
|
+
// "You received..."
|
|
64
|
+
} else {
|
|
65
|
+
// "Address X sent to Address Y"
|
|
66
|
+
}
|
|
33
67
|
```
|
|
34
68
|
|
|
35
69
|
## Bundle Size
|
|
@@ -78,4 +112,3 @@ bun run size:why
|
|
|
78
112
|
## License
|
|
79
113
|
|
|
80
114
|
MIT
|
|
81
|
-
|
|
@@ -8,11 +8,11 @@ declare const TxDirectionSchema: z.ZodEnum<{
|
|
|
8
8
|
neutral: "neutral";
|
|
9
9
|
}>;
|
|
10
10
|
declare const TxPrimaryTypeSchema: z.ZodEnum<{
|
|
11
|
-
|
|
12
|
-
swap: "swap";
|
|
11
|
+
nft_mint: "nft_mint";
|
|
13
12
|
nft_purchase: "nft_purchase";
|
|
14
13
|
nft_sale: "nft_sale";
|
|
15
|
-
|
|
14
|
+
transfer: "transfer";
|
|
15
|
+
swap: "swap";
|
|
16
16
|
stake_deposit: "stake_deposit";
|
|
17
17
|
stake_withdraw: "stake_withdraw";
|
|
18
18
|
token_deposit: "token_deposit";
|
|
@@ -50,6 +50,7 @@ declare const RawTransactionSchema: z.ZodObject<{
|
|
|
50
50
|
signature: z.ZodCustom<Signature, Signature>;
|
|
51
51
|
slot: z.ZodUnion<readonly [z.ZodNumber, z.ZodBigInt]>;
|
|
52
52
|
blockTime: z.ZodNullable<z.ZodUnion<readonly [z.ZodNumber, z.ZodBigInt]>>;
|
|
53
|
+
fee: z.ZodOptional<z.ZodNumber>;
|
|
53
54
|
err: z.ZodNullable<z.ZodAny>;
|
|
54
55
|
programIds: z.ZodArray<z.ZodString>;
|
|
55
56
|
protocol: z.ZodNullable<z.ZodObject<{
|
|
@@ -91,11 +92,11 @@ declare const TxLegSideSchema: z.ZodEnum<{
|
|
|
91
92
|
credit: "credit";
|
|
92
93
|
}>;
|
|
93
94
|
declare const TxLegRoleSchema: z.ZodEnum<{
|
|
94
|
-
unknown: "unknown";
|
|
95
95
|
reward: "reward";
|
|
96
|
+
unknown: "unknown";
|
|
97
|
+
fee: "fee";
|
|
96
98
|
sent: "sent";
|
|
97
99
|
received: "received";
|
|
98
|
-
fee: "fee";
|
|
99
100
|
protocol_deposit: "protocol_deposit";
|
|
100
101
|
protocol_withdraw: "protocol_withdraw";
|
|
101
102
|
principal: "principal";
|
|
@@ -143,11 +144,11 @@ declare const TxLegSchema: z.ZodObject<{
|
|
|
143
144
|
} | undefined;
|
|
144
145
|
}>;
|
|
145
146
|
role: z.ZodEnum<{
|
|
146
|
-
unknown: "unknown";
|
|
147
147
|
reward: "reward";
|
|
148
|
+
unknown: "unknown";
|
|
149
|
+
fee: "fee";
|
|
148
150
|
sent: "sent";
|
|
149
151
|
received: "received";
|
|
150
|
-
fee: "fee";
|
|
151
152
|
protocol_deposit: "protocol_deposit";
|
|
152
153
|
protocol_withdraw: "protocol_withdraw";
|
|
153
154
|
principal: "principal";
|
|
@@ -165,11 +166,11 @@ type TxLeg = z.infer<typeof TxLegSchema>;
|
|
|
165
166
|
|
|
166
167
|
declare const TransactionClassificationSchema: z.ZodObject<{
|
|
167
168
|
primaryType: z.ZodEnum<{
|
|
168
|
-
|
|
169
|
-
swap: "swap";
|
|
169
|
+
nft_mint: "nft_mint";
|
|
170
170
|
nft_purchase: "nft_purchase";
|
|
171
171
|
nft_sale: "nft_sale";
|
|
172
|
-
|
|
172
|
+
transfer: "transfer";
|
|
173
|
+
swap: "swap";
|
|
173
174
|
stake_deposit: "stake_deposit";
|
|
174
175
|
stake_withdraw: "stake_withdraw";
|
|
175
176
|
token_deposit: "token_deposit";
|
|
@@ -187,12 +188,12 @@ declare const TransactionClassificationSchema: z.ZodObject<{
|
|
|
187
188
|
receiver: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
188
189
|
counterparty: z.ZodNullable<z.ZodObject<{
|
|
189
190
|
type: z.ZodEnum<{
|
|
190
|
-
unknown: "unknown";
|
|
191
|
-
protocol: "protocol";
|
|
192
191
|
person: "person";
|
|
193
192
|
merchant: "merchant";
|
|
194
193
|
exchange: "exchange";
|
|
194
|
+
protocol: "protocol";
|
|
195
195
|
own_wallet: "own_wallet";
|
|
196
|
+
unknown: "unknown";
|
|
196
197
|
}>;
|
|
197
198
|
address: z.ZodString;
|
|
198
199
|
name: z.ZodOptional<z.ZodString>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Rpc, GetBalanceApi, GetTokenAccountsByOwnerApi, GetSignaturesForAddressApi, GetTransactionApi, RpcSubscriptions, Address, Signature } from '@solana/kit';
|
|
2
|
-
import { R as RawTransaction, T as TxLeg, a as TransactionClassification } from './classification.types-
|
|
2
|
+
import { R as RawTransaction, T as TxLeg, a as TransactionClassification } from './classification.types-Cn9IGtEC.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Union type of all RPC APIs used by the transaction indexer.
|
|
@@ -152,6 +152,36 @@ interface TokenAccountBalance {
|
|
|
152
152
|
*/
|
|
153
153
|
declare function fetchWalletBalance(rpc: Rpc<GetBalanceApi & GetTokenAccountsByOwnerApi>, walletAddress: Address, tokenMints?: readonly string[]): Promise<WalletBalance>;
|
|
154
154
|
|
|
155
|
+
interface NftMetadata {
|
|
156
|
+
mint: string;
|
|
157
|
+
name: string;
|
|
158
|
+
symbol: string;
|
|
159
|
+
image: string;
|
|
160
|
+
cdnImage?: string;
|
|
161
|
+
description?: string;
|
|
162
|
+
collection?: string;
|
|
163
|
+
attributes?: Array<{
|
|
164
|
+
trait_type: string;
|
|
165
|
+
value: string;
|
|
166
|
+
}>;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Fetches NFT metadata from Helius DAS API.
|
|
170
|
+
*
|
|
171
|
+
* @param rpcUrl - Helius RPC endpoint URL
|
|
172
|
+
* @param mintAddress - NFT mint address
|
|
173
|
+
* @returns NFT metadata including name, image, collection, and attributes, or null if not found
|
|
174
|
+
*/
|
|
175
|
+
declare function fetchNftMetadata(rpcUrl: string, mintAddress: string): Promise<NftMetadata | null>;
|
|
176
|
+
/**
|
|
177
|
+
* Fetches NFT metadata for multiple mints in parallel.
|
|
178
|
+
*
|
|
179
|
+
* @param rpcUrl - Helius RPC endpoint URL
|
|
180
|
+
* @param mintAddresses - Array of NFT mint addresses
|
|
181
|
+
* @returns Map of mint address to NFT metadata (only includes successful fetches)
|
|
182
|
+
*/
|
|
183
|
+
declare function fetchNftMetadataBatch(rpcUrl: string, mintAddresses: string[]): Promise<Map<string, NftMetadata>>;
|
|
184
|
+
|
|
155
185
|
type TxIndexerOptions = {
|
|
156
186
|
rpcUrl: string;
|
|
157
187
|
wsUrl?: string;
|
|
@@ -164,6 +194,10 @@ interface GetTransactionsOptions {
|
|
|
164
194
|
until?: Signature;
|
|
165
195
|
filterSpam?: boolean;
|
|
166
196
|
spamConfig?: SpamFilterConfig;
|
|
197
|
+
enrichNftMetadata?: boolean;
|
|
198
|
+
}
|
|
199
|
+
interface GetTransactionOptions {
|
|
200
|
+
enrichNftMetadata?: boolean;
|
|
167
201
|
}
|
|
168
202
|
interface ClassifiedTransaction {
|
|
169
203
|
tx: RawTransaction;
|
|
@@ -174,9 +208,11 @@ interface TxIndexer {
|
|
|
174
208
|
rpc: ReturnType<typeof createSolanaClient>["rpc"];
|
|
175
209
|
getBalance(walletAddress: Address, tokenMints?: readonly string[]): Promise<WalletBalance>;
|
|
176
210
|
getTransactions(walletAddress: Address, options?: GetTransactionsOptions): Promise<ClassifiedTransaction[]>;
|
|
177
|
-
getTransaction(signature: Signature): Promise<ClassifiedTransaction | null>;
|
|
211
|
+
getTransaction(signature: Signature, options?: GetTransactionOptions): Promise<ClassifiedTransaction | null>;
|
|
178
212
|
getRawTransaction(signature: Signature): Promise<RawTransaction | null>;
|
|
213
|
+
getNftMetadata(mintAddress: string): Promise<NftMetadata | null>;
|
|
214
|
+
getNftMetadataBatch(mintAddresses: string[]): Promise<Map<string, NftMetadata>>;
|
|
179
215
|
}
|
|
180
216
|
declare function createIndexer(options: TxIndexerOptions): TxIndexer;
|
|
181
217
|
|
|
182
|
-
export { type ClassifiedTransaction as C, type FetchTransactionsConfig as F, type GetTransactionsOptions as G, type IndexerRpcApi as I, type SolanaClient as S, type TxIndexer as T, type WalletBalance as W, type TxIndexerOptions as a,
|
|
218
|
+
export { type ClassifiedTransaction as C, type FetchTransactionsConfig as F, type GetTransactionsOptions as G, type IndexerRpcApi as I, type NftMetadata as N, type SolanaClient as S, type TxIndexer as T, type WalletBalance as W, type TxIndexerOptions as a, type GetTransactionOptions as b, createIndexer as c, createSolanaClient as d, parseSignature as e, fetchWalletBalance as f, type TokenAccountBalance as g, fetchWalletSignatures as h, fetchTransaction as i, fetchTransactionsBatch as j, isSpamTransaction as k, filterSpamTransactions as l, type SpamFilterConfig as m, fetchNftMetadata as n, fetchNftMetadataBatch as o, parseAddress as p, transactionToLegs as t };
|
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import '@solana/kit';
|
|
2
|
-
export { C as ClassifiedTransaction, F as FetchTransactionsConfig, G as GetTransactionsOptions, T as TxIndexer, a as TxIndexerOptions, c as createIndexer } from './client-
|
|
3
|
-
import './classification.types-
|
|
2
|
+
export { C as ClassifiedTransaction, F as FetchTransactionsConfig, b as GetTransactionOptions, G as GetTransactionsOptions, T as TxIndexer, a as TxIndexerOptions, c as createIndexer } from './client-iLW2_DnL.js';
|
|
3
|
+
import './classification.types-Cn9IGtEC.js';
|
|
4
4
|
import 'zod';
|
package/dist/client.js
CHANGED
|
@@ -416,6 +416,7 @@ async function fetchTransaction(rpc, signature2, commitment = "confirmed") {
|
|
|
416
416
|
signature: signature2,
|
|
417
417
|
slot: response.slot,
|
|
418
418
|
blockTime: response.blockTime,
|
|
419
|
+
fee: Number(response.meta?.fee ?? 0),
|
|
419
420
|
err: response.meta?.err ?? null,
|
|
420
421
|
programIds: extractProgramIds(response.transaction),
|
|
421
422
|
protocol: null,
|
|
@@ -1314,8 +1315,81 @@ function filterSpamTransactions(transactions, config) {
|
|
|
1314
1315
|
);
|
|
1315
1316
|
}
|
|
1316
1317
|
|
|
1318
|
+
// src/nft.ts
|
|
1319
|
+
async function fetchNftMetadata(rpcUrl, mintAddress) {
|
|
1320
|
+
const response = await fetch(rpcUrl, {
|
|
1321
|
+
method: "POST",
|
|
1322
|
+
headers: { "Content-Type": "application/json" },
|
|
1323
|
+
body: JSON.stringify({
|
|
1324
|
+
jsonrpc: "2.0",
|
|
1325
|
+
id: "get-asset",
|
|
1326
|
+
method: "getAsset",
|
|
1327
|
+
params: { id: mintAddress }
|
|
1328
|
+
})
|
|
1329
|
+
});
|
|
1330
|
+
const data = await response.json();
|
|
1331
|
+
if (data.error || !data.result?.content?.metadata) {
|
|
1332
|
+
return null;
|
|
1333
|
+
}
|
|
1334
|
+
const { result } = data;
|
|
1335
|
+
const { content, grouping } = result;
|
|
1336
|
+
return {
|
|
1337
|
+
mint: mintAddress,
|
|
1338
|
+
name: content.metadata.name,
|
|
1339
|
+
symbol: content.metadata.symbol,
|
|
1340
|
+
image: content.links.image ?? content.files?.[0]?.uri ?? "",
|
|
1341
|
+
cdnImage: content.files?.[0]?.cdn_uri,
|
|
1342
|
+
description: content.metadata.description,
|
|
1343
|
+
collection: grouping?.find((g) => g.group_key === "collection")?.group_value,
|
|
1344
|
+
attributes: content.metadata.attributes
|
|
1345
|
+
};
|
|
1346
|
+
}
|
|
1347
|
+
async function fetchNftMetadataBatch(rpcUrl, mintAddresses) {
|
|
1348
|
+
const results = await Promise.all(
|
|
1349
|
+
mintAddresses.map((mint) => fetchNftMetadata(rpcUrl, mint))
|
|
1350
|
+
);
|
|
1351
|
+
const map = /* @__PURE__ */ new Map();
|
|
1352
|
+
results.forEach((metadata, index) => {
|
|
1353
|
+
if (metadata) {
|
|
1354
|
+
map.set(mintAddresses[index], metadata);
|
|
1355
|
+
}
|
|
1356
|
+
});
|
|
1357
|
+
return map;
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1317
1360
|
// src/client.ts
|
|
1361
|
+
var NFT_TRANSACTION_TYPES = ["nft_mint", "nft_purchase", "nft_sale"];
|
|
1362
|
+
async function enrichNftClassification(rpcUrl, classified) {
|
|
1363
|
+
const { classification } = classified;
|
|
1364
|
+
if (!NFT_TRANSACTION_TYPES.includes(classification.primaryType)) {
|
|
1365
|
+
return classified;
|
|
1366
|
+
}
|
|
1367
|
+
const nftMint = classification.metadata?.nft_mint;
|
|
1368
|
+
if (!nftMint) {
|
|
1369
|
+
return classified;
|
|
1370
|
+
}
|
|
1371
|
+
const nftData = await fetchNftMetadata(rpcUrl, nftMint);
|
|
1372
|
+
if (!nftData) {
|
|
1373
|
+
return classified;
|
|
1374
|
+
}
|
|
1375
|
+
return {
|
|
1376
|
+
...classified,
|
|
1377
|
+
classification: {
|
|
1378
|
+
...classification,
|
|
1379
|
+
metadata: {
|
|
1380
|
+
...classification.metadata,
|
|
1381
|
+
nft_name: nftData.name,
|
|
1382
|
+
nft_image: nftData.image,
|
|
1383
|
+
nft_cdn_image: nftData.cdnImage,
|
|
1384
|
+
nft_collection: nftData.collection,
|
|
1385
|
+
nft_symbol: nftData.symbol,
|
|
1386
|
+
nft_attributes: nftData.attributes
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
};
|
|
1390
|
+
}
|
|
1318
1391
|
function createIndexer(options) {
|
|
1392
|
+
const rpcUrl = "client" in options ? "" : options.rpcUrl;
|
|
1319
1393
|
const client = "client" in options ? options.client : createSolanaClient(options.rpcUrl, options.wsUrl);
|
|
1320
1394
|
return {
|
|
1321
1395
|
rpc: client.rpc,
|
|
@@ -1323,7 +1397,39 @@ function createIndexer(options) {
|
|
|
1323
1397
|
return fetchWalletBalance(client.rpc, walletAddress, tokenMints);
|
|
1324
1398
|
},
|
|
1325
1399
|
async getTransactions(walletAddress, options2 = {}) {
|
|
1326
|
-
const { limit = 10, before, until, filterSpam = true, spamConfig } = options2;
|
|
1400
|
+
const { limit = 10, before, until, filterSpam = true, spamConfig, enrichNftMetadata = true } = options2;
|
|
1401
|
+
async function enrichBatch(transactions) {
|
|
1402
|
+
if (!enrichNftMetadata || !rpcUrl) {
|
|
1403
|
+
return transactions;
|
|
1404
|
+
}
|
|
1405
|
+
const nftMints = transactions.filter((t) => NFT_TRANSACTION_TYPES.includes(t.classification.primaryType)).map((t) => t.classification.metadata?.nft_mint).filter(Boolean);
|
|
1406
|
+
if (nftMints.length === 0) {
|
|
1407
|
+
return transactions;
|
|
1408
|
+
}
|
|
1409
|
+
const nftMetadataMap = await fetchNftMetadataBatch(rpcUrl, nftMints);
|
|
1410
|
+
return transactions.map((t) => {
|
|
1411
|
+
const nftMint = t.classification.metadata?.nft_mint;
|
|
1412
|
+
if (!nftMint || !nftMetadataMap.has(nftMint)) {
|
|
1413
|
+
return t;
|
|
1414
|
+
}
|
|
1415
|
+
const nftData = nftMetadataMap.get(nftMint);
|
|
1416
|
+
return {
|
|
1417
|
+
...t,
|
|
1418
|
+
classification: {
|
|
1419
|
+
...t.classification,
|
|
1420
|
+
metadata: {
|
|
1421
|
+
...t.classification.metadata,
|
|
1422
|
+
nft_name: nftData.name,
|
|
1423
|
+
nft_image: nftData.image,
|
|
1424
|
+
nft_cdn_image: nftData.cdnImage,
|
|
1425
|
+
nft_collection: nftData.collection,
|
|
1426
|
+
nft_symbol: nftData.symbol,
|
|
1427
|
+
nft_attributes: nftData.attributes
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
};
|
|
1431
|
+
});
|
|
1432
|
+
}
|
|
1327
1433
|
if (!filterSpam) {
|
|
1328
1434
|
const signatures = await fetchWalletSignatures(client.rpc, walletAddress, {
|
|
1329
1435
|
limit,
|
|
@@ -1346,7 +1452,7 @@ function createIndexer(options) {
|
|
|
1346
1452
|
const classification = classifyTransaction(legs, tx);
|
|
1347
1453
|
return { tx, classification, legs };
|
|
1348
1454
|
});
|
|
1349
|
-
return classified;
|
|
1455
|
+
return enrichBatch(classified);
|
|
1350
1456
|
}
|
|
1351
1457
|
const accumulated = [];
|
|
1352
1458
|
let currentBefore = before;
|
|
@@ -1385,9 +1491,11 @@ function createIndexer(options) {
|
|
|
1385
1491
|
break;
|
|
1386
1492
|
}
|
|
1387
1493
|
}
|
|
1388
|
-
|
|
1494
|
+
const result = accumulated.slice(0, limit);
|
|
1495
|
+
return enrichBatch(result);
|
|
1389
1496
|
},
|
|
1390
|
-
async getTransaction(signature2) {
|
|
1497
|
+
async getTransaction(signature2, options2 = {}) {
|
|
1498
|
+
const { enrichNftMetadata = true } = options2;
|
|
1391
1499
|
const tx = await fetchTransaction(client.rpc, signature2);
|
|
1392
1500
|
if (!tx) {
|
|
1393
1501
|
return null;
|
|
@@ -1395,10 +1503,26 @@ function createIndexer(options) {
|
|
|
1395
1503
|
tx.protocol = detectProtocol(tx.programIds);
|
|
1396
1504
|
const legs = transactionToLegs(tx);
|
|
1397
1505
|
const classification = classifyTransaction(legs, tx);
|
|
1398
|
-
|
|
1506
|
+
let classified = { tx, classification, legs };
|
|
1507
|
+
if (enrichNftMetadata && rpcUrl) {
|
|
1508
|
+
classified = await enrichNftClassification(rpcUrl, classified);
|
|
1509
|
+
}
|
|
1510
|
+
return classified;
|
|
1399
1511
|
},
|
|
1400
1512
|
async getRawTransaction(signature2) {
|
|
1401
1513
|
return fetchTransaction(client.rpc, signature2);
|
|
1514
|
+
},
|
|
1515
|
+
async getNftMetadata(mintAddress) {
|
|
1516
|
+
if (!rpcUrl) {
|
|
1517
|
+
throw new Error("getNftMetadata requires rpcUrl to be set");
|
|
1518
|
+
}
|
|
1519
|
+
return fetchNftMetadata(rpcUrl, mintAddress);
|
|
1520
|
+
},
|
|
1521
|
+
async getNftMetadataBatch(mintAddresses) {
|
|
1522
|
+
if (!rpcUrl) {
|
|
1523
|
+
throw new Error("getNftMetadataBatch requires rpcUrl to be set");
|
|
1524
|
+
}
|
|
1525
|
+
return fetchNftMetadataBatch(rpcUrl, mintAddresses);
|
|
1402
1526
|
}
|
|
1403
1527
|
};
|
|
1404
1528
|
}
|