tx-indexer 0.5.2 → 0.5.4
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 +5 -5
- package/dist/{client-DdzTiKZ4.d.ts → client-xmDVjOy4.d.ts} +13 -1
- package/dist/client.d.ts +2 -2
- package/dist/client.js +548 -63
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +109 -5
- package/dist/index.js +570 -66
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +4 -4
- package/package.json +4 -2
- package/dist/{classification.types-Cn9IGtEC.d.ts → classification.types-h046WjuF.d.ts} +7 -7
package/dist/index.js
CHANGED
|
@@ -15,12 +15,43 @@ function parseSignature(sig) {
|
|
|
15
15
|
|
|
16
16
|
// ../domain/src/money/token-registry.ts
|
|
17
17
|
var KNOWN_TOKENS = {
|
|
18
|
+
// Native
|
|
18
19
|
SOL: "So11111111111111111111111111111111111111112",
|
|
20
|
+
// Stablecoins
|
|
19
21
|
USDC: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
|
22
|
+
USDT: "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
|
|
23
|
+
PYUSD: "2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo",
|
|
24
|
+
USDG: "2u1tszSeqZ3qBWF3uNGPFc8TzMk2tdiwknnRMWGWjGWH",
|
|
20
25
|
USDC_BRIDGED: "A9mUU4qviSctJVPJdBJWkb28deg915LYJKrzQ19ji3FM",
|
|
21
|
-
|
|
26
|
+
DAI: "EjmyN6qEC1Tf1JxiG1ae7UTJhUxSwk1TCCi3Z4dPuFhh",
|
|
27
|
+
// Major tokens
|
|
28
|
+
JUP: "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN",
|
|
29
|
+
JTO: "jtojtomepa8beP8AuQc6eXt5FriJwfFMwQx2v2f9mCL",
|
|
30
|
+
PYTH: "HZ1JovNiVvGrGNiiYvEozEVgZ58xaU3RKwX8eACQBCt3",
|
|
31
|
+
BONK: "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
|
|
32
|
+
WIF: "EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm",
|
|
33
|
+
RENDER: "rndrizKT3MK1iimdxRdWabcF7Zg7AR5T4nud4EkHBof",
|
|
34
|
+
HNT: "hntyVP6YFm1Hg25TN9WGLqM12b8TQmcknKrdu1oxWux",
|
|
35
|
+
RAY: "4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R",
|
|
36
|
+
ORCA: "orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE",
|
|
37
|
+
MNGO: "MangoCzJ36AjZyKwVj3VnYU4GTonjfVEnJmvvWaxLac",
|
|
38
|
+
MSOL: "mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So",
|
|
39
|
+
JITOSOL: "J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn",
|
|
40
|
+
BSOL: "bSo13r4TkiE4KumL71LsHTPpL2euBYLFx6h9HP3piy1",
|
|
41
|
+
// Memecoins
|
|
42
|
+
POPCAT: "7GCihgDB8fe6KNjn2MYtkzZcRjQy3t9GHdC8uHYmW2hr",
|
|
43
|
+
MEW: "MEW1gQWJ3nEXg2qgERiKu7FAFj79PHvQVREQUzScPP5",
|
|
44
|
+
PNUT: "2qEHjDLDLbuBgRYvsxhc5D6uDWAivNFZGan56P1tpump",
|
|
45
|
+
FARTCOIN: "9BB6NFEcjBCtnNLFko2FqVQBq8HHM13kCyYcdQbgpump",
|
|
46
|
+
AI16Z: "HeLp6NuQkmYB4pYWo2zYs22mESHXPQYzXbB8n4V98jwC",
|
|
47
|
+
// Wrapped tokens
|
|
48
|
+
WBTC: "3NZ9JMVBmGAqocybic2c7LQCJScmgsAZ6vQqTDzcqmJh",
|
|
49
|
+
WETH: "7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs",
|
|
50
|
+
WSOL: "So11111111111111111111111111111111111111112"
|
|
51
|
+
// Same as SOL (wrapped)
|
|
22
52
|
};
|
|
23
53
|
var TOKEN_INFO = {
|
|
54
|
+
// Native SOL
|
|
24
55
|
[KNOWN_TOKENS.SOL]: {
|
|
25
56
|
mint: KNOWN_TOKENS.SOL,
|
|
26
57
|
symbol: "SOL",
|
|
@@ -28,6 +59,7 @@ var TOKEN_INFO = {
|
|
|
28
59
|
decimals: 9,
|
|
29
60
|
logoURI: "https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/So11111111111111111111111111111111111111112/logo.png"
|
|
30
61
|
},
|
|
62
|
+
// Stablecoins
|
|
31
63
|
[KNOWN_TOKENS.USDC]: {
|
|
32
64
|
mint: KNOWN_TOKENS.USDC,
|
|
33
65
|
symbol: "USDC",
|
|
@@ -35,30 +67,211 @@ var TOKEN_INFO = {
|
|
|
35
67
|
decimals: 6,
|
|
36
68
|
logoURI: "https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v/logo.png"
|
|
37
69
|
},
|
|
38
|
-
[KNOWN_TOKENS.
|
|
39
|
-
mint: KNOWN_TOKENS.
|
|
40
|
-
symbol: "
|
|
41
|
-
name: "
|
|
42
|
-
decimals: 6
|
|
70
|
+
[KNOWN_TOKENS.USDT]: {
|
|
71
|
+
mint: KNOWN_TOKENS.USDT,
|
|
72
|
+
symbol: "USDT",
|
|
73
|
+
name: "Tether USD",
|
|
74
|
+
decimals: 6,
|
|
75
|
+
logoURI: "https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB/logo.svg"
|
|
76
|
+
},
|
|
77
|
+
[KNOWN_TOKENS.PYUSD]: {
|
|
78
|
+
mint: KNOWN_TOKENS.PYUSD,
|
|
79
|
+
symbol: "PYUSD",
|
|
80
|
+
name: "PayPal USD",
|
|
81
|
+
decimals: 6,
|
|
82
|
+
logoURI: "https://img.fotofolio.xyz/?url=https%3A%2F%2Fraw.githubusercontent.com%2Fsolana-labs%2Ftoken-list%2Fmain%2Fassets%2Fmainnet%2F2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo%2Flogo.png"
|
|
43
83
|
},
|
|
44
84
|
[KNOWN_TOKENS.USDG]: {
|
|
45
85
|
mint: KNOWN_TOKENS.USDG,
|
|
46
86
|
symbol: "USDG",
|
|
47
87
|
name: "USD Glitter",
|
|
48
88
|
decimals: 6
|
|
89
|
+
},
|
|
90
|
+
[KNOWN_TOKENS.USDC_BRIDGED]: {
|
|
91
|
+
mint: KNOWN_TOKENS.USDC_BRIDGED,
|
|
92
|
+
symbol: "USDCet",
|
|
93
|
+
name: "USDC (Wormhole)",
|
|
94
|
+
decimals: 6
|
|
95
|
+
},
|
|
96
|
+
[KNOWN_TOKENS.DAI]: {
|
|
97
|
+
mint: KNOWN_TOKENS.DAI,
|
|
98
|
+
symbol: "DAI",
|
|
99
|
+
name: "DAI (Wormhole)",
|
|
100
|
+
decimals: 8
|
|
101
|
+
},
|
|
102
|
+
// Major tokens
|
|
103
|
+
[KNOWN_TOKENS.JUP]: {
|
|
104
|
+
mint: KNOWN_TOKENS.JUP,
|
|
105
|
+
symbol: "JUP",
|
|
106
|
+
name: "Jupiter",
|
|
107
|
+
decimals: 6,
|
|
108
|
+
logoURI: "https://static.jup.ag/jup/icon.png"
|
|
109
|
+
},
|
|
110
|
+
[KNOWN_TOKENS.JTO]: {
|
|
111
|
+
mint: KNOWN_TOKENS.JTO,
|
|
112
|
+
symbol: "JTO",
|
|
113
|
+
name: "Jito",
|
|
114
|
+
decimals: 9,
|
|
115
|
+
logoURI: "https://metadata.jito.network/token/jto/image"
|
|
116
|
+
},
|
|
117
|
+
[KNOWN_TOKENS.PYTH]: {
|
|
118
|
+
mint: KNOWN_TOKENS.PYTH,
|
|
119
|
+
symbol: "PYTH",
|
|
120
|
+
name: "Pyth Network",
|
|
121
|
+
decimals: 6,
|
|
122
|
+
logoURI: "https://pyth.network/token.svg"
|
|
123
|
+
},
|
|
124
|
+
[KNOWN_TOKENS.BONK]: {
|
|
125
|
+
mint: KNOWN_TOKENS.BONK,
|
|
126
|
+
symbol: "BONK",
|
|
127
|
+
name: "Bonk",
|
|
128
|
+
decimals: 5,
|
|
129
|
+
logoURI: "https://arweave.net/hQiPZOsRZXGXBJd_82PhVdlM_hACsT_q6wqwf5cSY7I"
|
|
130
|
+
},
|
|
131
|
+
[KNOWN_TOKENS.WIF]: {
|
|
132
|
+
mint: KNOWN_TOKENS.WIF,
|
|
133
|
+
symbol: "WIF",
|
|
134
|
+
name: "dogwifhat",
|
|
135
|
+
decimals: 6,
|
|
136
|
+
logoURI: "https://bafkreibk3covs5ltyqxa272uodhber6kcclnlgrbwjee4kyqhstwmjqpfa.ipfs.nftstorage.link/"
|
|
137
|
+
},
|
|
138
|
+
[KNOWN_TOKENS.RENDER]: {
|
|
139
|
+
mint: KNOWN_TOKENS.RENDER,
|
|
140
|
+
symbol: "RENDER",
|
|
141
|
+
name: "Render Token",
|
|
142
|
+
decimals: 8,
|
|
143
|
+
logoURI: "https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/rndrizKT3MK1iimdxRdWabcF7Zg7AR5T4nud4EkHBof/logo.png"
|
|
144
|
+
},
|
|
145
|
+
[KNOWN_TOKENS.HNT]: {
|
|
146
|
+
mint: KNOWN_TOKENS.HNT,
|
|
147
|
+
symbol: "HNT",
|
|
148
|
+
name: "Helium",
|
|
149
|
+
decimals: 8,
|
|
150
|
+
logoURI: "https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/hntyVP6YFm1Hg25TN9WGLqM12b8TQmcknKrdu1oxWux/logo.png"
|
|
151
|
+
},
|
|
152
|
+
[KNOWN_TOKENS.RAY]: {
|
|
153
|
+
mint: KNOWN_TOKENS.RAY,
|
|
154
|
+
symbol: "RAY",
|
|
155
|
+
name: "Raydium",
|
|
156
|
+
decimals: 6,
|
|
157
|
+
logoURI: "https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R/logo.png"
|
|
158
|
+
},
|
|
159
|
+
[KNOWN_TOKENS.ORCA]: {
|
|
160
|
+
mint: KNOWN_TOKENS.ORCA,
|
|
161
|
+
symbol: "ORCA",
|
|
162
|
+
name: "Orca",
|
|
163
|
+
decimals: 6,
|
|
164
|
+
logoURI: "https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE/logo.png"
|
|
165
|
+
},
|
|
166
|
+
[KNOWN_TOKENS.MNGO]: {
|
|
167
|
+
mint: KNOWN_TOKENS.MNGO,
|
|
168
|
+
symbol: "MNGO",
|
|
169
|
+
name: "Mango",
|
|
170
|
+
decimals: 6,
|
|
171
|
+
logoURI: "https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/MangoCzJ36AjZyKwVj3VnYU4GTonjfVEnJmvvWaxLac/logo.png"
|
|
172
|
+
},
|
|
173
|
+
// Liquid staking tokens
|
|
174
|
+
[KNOWN_TOKENS.MSOL]: {
|
|
175
|
+
mint: KNOWN_TOKENS.MSOL,
|
|
176
|
+
symbol: "mSOL",
|
|
177
|
+
name: "Marinade Staked SOL",
|
|
178
|
+
decimals: 9,
|
|
179
|
+
logoURI: "https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So/logo.png"
|
|
180
|
+
},
|
|
181
|
+
[KNOWN_TOKENS.JITOSOL]: {
|
|
182
|
+
mint: KNOWN_TOKENS.JITOSOL,
|
|
183
|
+
symbol: "JitoSOL",
|
|
184
|
+
name: "Jito Staked SOL",
|
|
185
|
+
decimals: 9,
|
|
186
|
+
logoURI: "https://storage.googleapis.com/token-metadata/JitoSOL-256.png"
|
|
187
|
+
},
|
|
188
|
+
[KNOWN_TOKENS.BSOL]: {
|
|
189
|
+
mint: KNOWN_TOKENS.BSOL,
|
|
190
|
+
symbol: "bSOL",
|
|
191
|
+
name: "BlazeStake Staked SOL",
|
|
192
|
+
decimals: 9,
|
|
193
|
+
logoURI: "https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/bSo13r4TkiE4KumL71LsHTPpL2euBYLFx6h9HP3piy1/logo.png"
|
|
194
|
+
},
|
|
195
|
+
// Memecoins
|
|
196
|
+
[KNOWN_TOKENS.POPCAT]: {
|
|
197
|
+
mint: KNOWN_TOKENS.POPCAT,
|
|
198
|
+
symbol: "POPCAT",
|
|
199
|
+
name: "Popcat",
|
|
200
|
+
decimals: 9,
|
|
201
|
+
logoURI: "https://bafkreidvkvuzyslw5jh5z242lgzwzhbi2kxxnpkm73fkuqzasyr34jj2o4.ipfs.nftstorage.link/"
|
|
202
|
+
},
|
|
203
|
+
[KNOWN_TOKENS.MEW]: {
|
|
204
|
+
mint: KNOWN_TOKENS.MEW,
|
|
205
|
+
symbol: "MEW",
|
|
206
|
+
name: "cat in a dogs world",
|
|
207
|
+
decimals: 5,
|
|
208
|
+
logoURI: "https://bafkreidlwyr565dxtao2ipsze6bmzpszqzybz7sqi2zaet5fs7k53henju.ipfs.nftstorage.link/"
|
|
209
|
+
},
|
|
210
|
+
[KNOWN_TOKENS.PNUT]: {
|
|
211
|
+
mint: KNOWN_TOKENS.PNUT,
|
|
212
|
+
symbol: "Peanut",
|
|
213
|
+
name: "Peanut the Squirrel",
|
|
214
|
+
decimals: 6,
|
|
215
|
+
logoURI: "https://ipfs.io/ipfs/QmNS3Hdb6pMheFzRdwXr3PPCrXcBohzhLrKHqEUV1n3HnJ"
|
|
216
|
+
},
|
|
217
|
+
[KNOWN_TOKENS.FARTCOIN]: {
|
|
218
|
+
mint: KNOWN_TOKENS.FARTCOIN,
|
|
219
|
+
symbol: "FARTCOIN",
|
|
220
|
+
name: "Fartcoin",
|
|
221
|
+
decimals: 6,
|
|
222
|
+
logoURI: "https://ipfs.io/ipfs/QmQHY6t8TxucH3F9LGPBBqqRLbyWx7NxWvrnoZKcq9ErrR"
|
|
223
|
+
},
|
|
224
|
+
[KNOWN_TOKENS.AI16Z]: {
|
|
225
|
+
mint: KNOWN_TOKENS.AI16Z,
|
|
226
|
+
symbol: "ai16z",
|
|
227
|
+
name: "ai16z",
|
|
228
|
+
decimals: 9,
|
|
229
|
+
logoURI: "https://ipfs.io/ipfs/QmRbm1mprqHmJ7PvCTrSNydkquLi5r41wq8kWbHvoRm3FX"
|
|
230
|
+
},
|
|
231
|
+
// Wrapped tokens
|
|
232
|
+
[KNOWN_TOKENS.WBTC]: {
|
|
233
|
+
mint: KNOWN_TOKENS.WBTC,
|
|
234
|
+
symbol: "WBTC",
|
|
235
|
+
name: "Wrapped BTC (Wormhole)",
|
|
236
|
+
decimals: 8,
|
|
237
|
+
logoURI: "https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/3NZ9JMVBmGAqocybic2c7LQCJScmgsAZ6vQqTDzcqmJh/logo.png"
|
|
238
|
+
},
|
|
239
|
+
[KNOWN_TOKENS.WETH]: {
|
|
240
|
+
mint: KNOWN_TOKENS.WETH,
|
|
241
|
+
symbol: "WETH",
|
|
242
|
+
name: "Wrapped ETH (Wormhole)",
|
|
243
|
+
decimals: 8,
|
|
244
|
+
logoURI: "https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs/logo.png"
|
|
49
245
|
}
|
|
50
246
|
};
|
|
51
247
|
function getTokenInfo(mint) {
|
|
52
248
|
return TOKEN_INFO[mint];
|
|
53
249
|
}
|
|
54
|
-
|
|
250
|
+
function createUnknownToken(mint, decimals) {
|
|
251
|
+
return {
|
|
252
|
+
mint,
|
|
253
|
+
symbol: mint.slice(0, 8),
|
|
254
|
+
name: `Unknown Token (${mint.slice(0, 8)}...)`,
|
|
255
|
+
decimals
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
var SUPPORTED_STABLECOINS = [
|
|
55
259
|
KNOWN_TOKENS.USDC,
|
|
260
|
+
KNOWN_TOKENS.USDT,
|
|
261
|
+
KNOWN_TOKENS.PYUSD,
|
|
262
|
+
KNOWN_TOKENS.USDG,
|
|
56
263
|
KNOWN_TOKENS.USDC_BRIDGED,
|
|
57
|
-
KNOWN_TOKENS.
|
|
264
|
+
KNOWN_TOKENS.DAI
|
|
58
265
|
];
|
|
59
266
|
[
|
|
60
267
|
KNOWN_TOKENS.SOL,
|
|
61
|
-
KNOWN_TOKENS.USDC
|
|
268
|
+
KNOWN_TOKENS.USDC,
|
|
269
|
+
KNOWN_TOKENS.USDT
|
|
270
|
+
];
|
|
271
|
+
var LIQUID_STAKING_TOKENS = [
|
|
272
|
+
KNOWN_TOKENS.MSOL,
|
|
273
|
+
KNOWN_TOKENS.JITOSOL,
|
|
274
|
+
KNOWN_TOKENS.BSOL
|
|
62
275
|
];
|
|
63
276
|
|
|
64
277
|
// ../solana/src/constants/program-ids.ts
|
|
@@ -942,21 +1155,38 @@ function determineTokenRole(change, tx, feePayer) {
|
|
|
942
1155
|
}
|
|
943
1156
|
|
|
944
1157
|
// ../classification/src/classifiers/transfer-classifier.ts
|
|
1158
|
+
function findBestTransferPair(legs) {
|
|
1159
|
+
const senderLegs = legs.filter(
|
|
1160
|
+
(l) => l.accountId.startsWith("external:") && l.side === "debit" && l.role === "sent"
|
|
1161
|
+
);
|
|
1162
|
+
if (senderLegs.length === 0) return null;
|
|
1163
|
+
let bestPair = null;
|
|
1164
|
+
let bestAmount = 0;
|
|
1165
|
+
for (const senderLeg of senderLegs) {
|
|
1166
|
+
const receiverLeg = legs.find(
|
|
1167
|
+
(l) => l.accountId.startsWith("external:") && l.side === "credit" && l.role === "received" && l.amount.token.mint === senderLeg.amount.token.mint && l.accountId !== senderLeg.accountId
|
|
1168
|
+
// Must be different account
|
|
1169
|
+
);
|
|
1170
|
+
if (receiverLeg) {
|
|
1171
|
+
const amount = senderLeg.amount.amountUi;
|
|
1172
|
+
if (amount > bestAmount) {
|
|
1173
|
+
bestAmount = amount;
|
|
1174
|
+
bestPair = { senderLeg, receiverLeg };
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
return bestPair;
|
|
1179
|
+
}
|
|
945
1180
|
var TransferClassifier = class {
|
|
946
1181
|
name = "transfer";
|
|
947
1182
|
priority = 20;
|
|
948
1183
|
classify(context) {
|
|
949
1184
|
const { legs, tx } = context;
|
|
950
1185
|
const facilitator = tx.accountKeys ? detectFacilitator(tx.accountKeys) : null;
|
|
951
|
-
const
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
if (!senderLeg) return null;
|
|
1186
|
+
const pair = findBestTransferPair(legs);
|
|
1187
|
+
if (!pair) return null;
|
|
1188
|
+
const { senderLeg, receiverLeg } = pair;
|
|
955
1189
|
const sender = senderLeg.accountId.replace("external:", "");
|
|
956
|
-
const receiverLeg = legs.find(
|
|
957
|
-
(l) => l.accountId.startsWith("external:") && l.side === "credit" && l.role === "received" && l.amount.token.mint === senderLeg.amount.token.mint
|
|
958
|
-
);
|
|
959
|
-
if (!receiverLeg) return null;
|
|
960
1190
|
const receiver = receiverLeg.accountId.replace("external:", "");
|
|
961
1191
|
return {
|
|
962
1192
|
primaryType: "transfer",
|
|
@@ -1435,6 +1665,27 @@ var FeeOnlyClassifier = class {
|
|
|
1435
1665
|
};
|
|
1436
1666
|
|
|
1437
1667
|
// ../classification/src/classifiers/solana-pay-classifier.ts
|
|
1668
|
+
function findBestTransferPair2(legs) {
|
|
1669
|
+
const senderLegs = legs.filter(
|
|
1670
|
+
(l) => l.accountId.startsWith("external:") && l.side === "debit" && l.role === "sent"
|
|
1671
|
+
);
|
|
1672
|
+
if (senderLegs.length === 0) return null;
|
|
1673
|
+
let bestPair = null;
|
|
1674
|
+
let bestAmount = 0;
|
|
1675
|
+
for (const senderLeg of senderLegs) {
|
|
1676
|
+
const receiverLeg = legs.find(
|
|
1677
|
+
(l) => l.accountId.startsWith("external:") && l.side === "credit" && l.role === "received" && l.amount.token.mint === senderLeg.amount.token.mint && l.accountId !== senderLeg.accountId
|
|
1678
|
+
);
|
|
1679
|
+
if (receiverLeg) {
|
|
1680
|
+
const amount = senderLeg.amount.amountUi;
|
|
1681
|
+
if (amount > bestAmount) {
|
|
1682
|
+
bestAmount = amount;
|
|
1683
|
+
bestPair = { senderLeg, receiverLeg };
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
return bestPair;
|
|
1688
|
+
}
|
|
1438
1689
|
var SolanaPayClassifier = class {
|
|
1439
1690
|
name = "solana-pay";
|
|
1440
1691
|
priority = 95;
|
|
@@ -1444,12 +1695,9 @@ var SolanaPayClassifier = class {
|
|
|
1444
1695
|
return null;
|
|
1445
1696
|
}
|
|
1446
1697
|
const memo = parseSolanaPayMemo(tx.memo);
|
|
1447
|
-
const
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
const receiverLeg = legs.find(
|
|
1451
|
-
(leg) => leg.accountId.startsWith("external:") && leg.side === "credit" && leg.role === "received"
|
|
1452
|
-
);
|
|
1698
|
+
const pair = findBestTransferPair2(legs);
|
|
1699
|
+
const senderLeg = pair?.senderLeg ?? null;
|
|
1700
|
+
const receiverLeg = pair?.receiverLeg ?? null;
|
|
1453
1701
|
const sender = senderLeg?.accountId.replace("external:", "") ?? null;
|
|
1454
1702
|
const receiver = receiverLeg?.accountId.replace("external:", "") ?? null;
|
|
1455
1703
|
const primaryAmount = senderLeg?.amount ?? receiverLeg?.amount ?? null;
|
|
@@ -1739,6 +1987,125 @@ function filterSpamTransactions(transactions, config) {
|
|
|
1739
1987
|
);
|
|
1740
1988
|
}
|
|
1741
1989
|
|
|
1990
|
+
// ../domain/src/money/token-fetcher.ts
|
|
1991
|
+
var DEFAULT_JUPITER_API_URL = "https://tokens.jup.ag/tokens?tags=verified";
|
|
1992
|
+
var DEFAULT_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
1993
|
+
function createTokenFetcher(options = {}) {
|
|
1994
|
+
const {
|
|
1995
|
+
jupiterApiUrl = DEFAULT_JUPITER_API_URL,
|
|
1996
|
+
cacheTtlMs = DEFAULT_CACHE_TTL_MS,
|
|
1997
|
+
prefetch = false
|
|
1998
|
+
} = options;
|
|
1999
|
+
const jupiterCache = /* @__PURE__ */ new Map();
|
|
2000
|
+
let lastFetchTime = 0;
|
|
2001
|
+
let fetchPromise = null;
|
|
2002
|
+
async function fetchJupiterTokens() {
|
|
2003
|
+
if (fetchPromise) {
|
|
2004
|
+
return fetchPromise;
|
|
2005
|
+
}
|
|
2006
|
+
if (Date.now() - lastFetchTime < cacheTtlMs && jupiterCache.size > 0) {
|
|
2007
|
+
return;
|
|
2008
|
+
}
|
|
2009
|
+
fetchPromise = (async () => {
|
|
2010
|
+
try {
|
|
2011
|
+
const response = await fetch(jupiterApiUrl);
|
|
2012
|
+
if (!response.ok) {
|
|
2013
|
+
console.warn(
|
|
2014
|
+
`Jupiter API returned ${response.status}: ${response.statusText}`
|
|
2015
|
+
);
|
|
2016
|
+
return;
|
|
2017
|
+
}
|
|
2018
|
+
const tokens = await response.json();
|
|
2019
|
+
jupiterCache.clear();
|
|
2020
|
+
for (const token of tokens) {
|
|
2021
|
+
jupiterCache.set(token.address, {
|
|
2022
|
+
mint: token.address,
|
|
2023
|
+
symbol: token.symbol,
|
|
2024
|
+
name: token.name,
|
|
2025
|
+
decimals: token.decimals,
|
|
2026
|
+
logoURI: token.logoURI
|
|
2027
|
+
});
|
|
2028
|
+
}
|
|
2029
|
+
lastFetchTime = Date.now();
|
|
2030
|
+
} catch (error) {
|
|
2031
|
+
console.warn("Failed to fetch Jupiter tokens:", error);
|
|
2032
|
+
} finally {
|
|
2033
|
+
fetchPromise = null;
|
|
2034
|
+
}
|
|
2035
|
+
})();
|
|
2036
|
+
return fetchPromise;
|
|
2037
|
+
}
|
|
2038
|
+
async function getToken(mint, decimals = 9) {
|
|
2039
|
+
const staticToken = TOKEN_INFO[mint];
|
|
2040
|
+
if (staticToken) {
|
|
2041
|
+
return staticToken;
|
|
2042
|
+
}
|
|
2043
|
+
const cachedToken = jupiterCache.get(mint);
|
|
2044
|
+
if (cachedToken) {
|
|
2045
|
+
return cachedToken;
|
|
2046
|
+
}
|
|
2047
|
+
await fetchJupiterTokens();
|
|
2048
|
+
const fetchedToken = jupiterCache.get(mint);
|
|
2049
|
+
if (fetchedToken) {
|
|
2050
|
+
return fetchedToken;
|
|
2051
|
+
}
|
|
2052
|
+
return createUnknownToken(mint, decimals);
|
|
2053
|
+
}
|
|
2054
|
+
async function getTokens(mints, defaultDecimals = 9) {
|
|
2055
|
+
const result = /* @__PURE__ */ new Map();
|
|
2056
|
+
const missingMints = [];
|
|
2057
|
+
for (const mint of mints) {
|
|
2058
|
+
const staticToken = TOKEN_INFO[mint];
|
|
2059
|
+
if (staticToken) {
|
|
2060
|
+
result.set(mint, staticToken);
|
|
2061
|
+
continue;
|
|
2062
|
+
}
|
|
2063
|
+
const cachedToken = jupiterCache.get(mint);
|
|
2064
|
+
if (cachedToken) {
|
|
2065
|
+
result.set(mint, cachedToken);
|
|
2066
|
+
continue;
|
|
2067
|
+
}
|
|
2068
|
+
missingMints.push(mint);
|
|
2069
|
+
}
|
|
2070
|
+
if (missingMints.length > 0) {
|
|
2071
|
+
await fetchJupiterTokens();
|
|
2072
|
+
for (const mint of missingMints) {
|
|
2073
|
+
const fetchedToken = jupiterCache.get(mint);
|
|
2074
|
+
if (fetchedToken) {
|
|
2075
|
+
result.set(mint, fetchedToken);
|
|
2076
|
+
} else {
|
|
2077
|
+
result.set(mint, createUnknownToken(mint, defaultDecimals));
|
|
2078
|
+
}
|
|
2079
|
+
}
|
|
2080
|
+
}
|
|
2081
|
+
return result;
|
|
2082
|
+
}
|
|
2083
|
+
async function refresh() {
|
|
2084
|
+
lastFetchTime = 0;
|
|
2085
|
+
await fetchJupiterTokens();
|
|
2086
|
+
}
|
|
2087
|
+
function getCacheSize() {
|
|
2088
|
+
return jupiterCache.size;
|
|
2089
|
+
}
|
|
2090
|
+
if (prefetch) {
|
|
2091
|
+
fetchJupiterTokens().catch(() => {
|
|
2092
|
+
});
|
|
2093
|
+
}
|
|
2094
|
+
return {
|
|
2095
|
+
getToken,
|
|
2096
|
+
getTokens,
|
|
2097
|
+
refresh,
|
|
2098
|
+
getCacheSize
|
|
2099
|
+
};
|
|
2100
|
+
}
|
|
2101
|
+
var defaultFetcher = null;
|
|
2102
|
+
function getDefaultTokenFetcher() {
|
|
2103
|
+
if (!defaultFetcher) {
|
|
2104
|
+
defaultFetcher = createTokenFetcher();
|
|
2105
|
+
}
|
|
2106
|
+
return defaultFetcher;
|
|
2107
|
+
}
|
|
2108
|
+
|
|
1742
2109
|
// src/nft.ts
|
|
1743
2110
|
async function fetchNftMetadata(rpcUrl, mintAddress) {
|
|
1744
2111
|
const response = await fetch(rpcUrl, {
|
|
@@ -1783,6 +2150,102 @@ async function fetchNftMetadataBatch(rpcUrl, mintAddresses) {
|
|
|
1783
2150
|
|
|
1784
2151
|
// src/client.ts
|
|
1785
2152
|
var NFT_TRANSACTION_TYPES = ["nft_mint", "nft_purchase", "nft_sale"];
|
|
2153
|
+
async function enrichTokenMetadata(tokenFetcher, classified) {
|
|
2154
|
+
const mints = /* @__PURE__ */ new Set();
|
|
2155
|
+
const decimalsMap = /* @__PURE__ */ new Map();
|
|
2156
|
+
for (const leg of classified.legs) {
|
|
2157
|
+
const mint = leg.amount.token.mint;
|
|
2158
|
+
mints.add(mint);
|
|
2159
|
+
decimalsMap.set(mint, leg.amount.token.decimals);
|
|
2160
|
+
}
|
|
2161
|
+
if (classified.classification.primaryAmount?.token.mint) {
|
|
2162
|
+
const mint = classified.classification.primaryAmount.token.mint;
|
|
2163
|
+
mints.add(mint);
|
|
2164
|
+
decimalsMap.set(
|
|
2165
|
+
mint,
|
|
2166
|
+
classified.classification.primaryAmount.token.decimals
|
|
2167
|
+
);
|
|
2168
|
+
}
|
|
2169
|
+
if (classified.classification.secondaryAmount?.token.mint) {
|
|
2170
|
+
const mint = classified.classification.secondaryAmount.token.mint;
|
|
2171
|
+
mints.add(mint);
|
|
2172
|
+
decimalsMap.set(
|
|
2173
|
+
mint,
|
|
2174
|
+
classified.classification.secondaryAmount.token.decimals
|
|
2175
|
+
);
|
|
2176
|
+
}
|
|
2177
|
+
if (mints.size === 0) {
|
|
2178
|
+
return classified;
|
|
2179
|
+
}
|
|
2180
|
+
const tokenInfoMap = await tokenFetcher.getTokens(
|
|
2181
|
+
Array.from(mints),
|
|
2182
|
+
9
|
|
2183
|
+
// default decimals
|
|
2184
|
+
);
|
|
2185
|
+
function enrichAmount(amount) {
|
|
2186
|
+
if (!amount) return amount;
|
|
2187
|
+
const enrichedToken = tokenInfoMap.get(amount.token.mint);
|
|
2188
|
+
if (!enrichedToken || enrichedToken.symbol === amount.token.symbol) {
|
|
2189
|
+
return amount;
|
|
2190
|
+
}
|
|
2191
|
+
return {
|
|
2192
|
+
...amount,
|
|
2193
|
+
token: {
|
|
2194
|
+
...enrichedToken,
|
|
2195
|
+
// Keep the decimals from the original (from RPC) as they're authoritative
|
|
2196
|
+
decimals: amount.token.decimals
|
|
2197
|
+
}
|
|
2198
|
+
};
|
|
2199
|
+
}
|
|
2200
|
+
function enrichLeg(leg) {
|
|
2201
|
+
const enrichedToken = tokenInfoMap.get(leg.amount.token.mint);
|
|
2202
|
+
if (!enrichedToken || enrichedToken.symbol === leg.amount.token.symbol) {
|
|
2203
|
+
return leg;
|
|
2204
|
+
}
|
|
2205
|
+
return {
|
|
2206
|
+
...leg,
|
|
2207
|
+
amount: {
|
|
2208
|
+
...leg.amount,
|
|
2209
|
+
token: {
|
|
2210
|
+
...enrichedToken,
|
|
2211
|
+
decimals: leg.amount.token.decimals
|
|
2212
|
+
}
|
|
2213
|
+
}
|
|
2214
|
+
};
|
|
2215
|
+
}
|
|
2216
|
+
const enrichedLegs = classified.legs.map(enrichLeg);
|
|
2217
|
+
const enrichedClassification = {
|
|
2218
|
+
...classified.classification,
|
|
2219
|
+
primaryAmount: enrichAmount(classified.classification.primaryAmount) ?? null,
|
|
2220
|
+
secondaryAmount: enrichAmount(classified.classification.secondaryAmount)
|
|
2221
|
+
};
|
|
2222
|
+
return {
|
|
2223
|
+
tx: classified.tx,
|
|
2224
|
+
legs: enrichedLegs,
|
|
2225
|
+
classification: enrichedClassification
|
|
2226
|
+
};
|
|
2227
|
+
}
|
|
2228
|
+
async function enrichTokenMetadataBatch(tokenFetcher, transactions) {
|
|
2229
|
+
const mints = /* @__PURE__ */ new Set();
|
|
2230
|
+
for (const classified of transactions) {
|
|
2231
|
+
for (const leg of classified.legs) {
|
|
2232
|
+
mints.add(leg.amount.token.mint);
|
|
2233
|
+
}
|
|
2234
|
+
if (classified.classification.primaryAmount?.token.mint) {
|
|
2235
|
+
mints.add(classified.classification.primaryAmount.token.mint);
|
|
2236
|
+
}
|
|
2237
|
+
if (classified.classification.secondaryAmount?.token.mint) {
|
|
2238
|
+
mints.add(classified.classification.secondaryAmount.token.mint);
|
|
2239
|
+
}
|
|
2240
|
+
}
|
|
2241
|
+
if (mints.size === 0) {
|
|
2242
|
+
return transactions;
|
|
2243
|
+
}
|
|
2244
|
+
await tokenFetcher.getTokens(Array.from(mints));
|
|
2245
|
+
return Promise.all(
|
|
2246
|
+
transactions.map((tx) => enrichTokenMetadata(tokenFetcher, tx))
|
|
2247
|
+
);
|
|
2248
|
+
}
|
|
1786
2249
|
async function enrichNftClassification(rpcUrl, classified) {
|
|
1787
2250
|
const { classification } = classified;
|
|
1788
2251
|
if (!NFT_TRANSACTION_TYPES.includes(classification.primaryType)) {
|
|
@@ -1815,51 +2278,74 @@ async function enrichNftClassification(rpcUrl, classified) {
|
|
|
1815
2278
|
function createIndexer(options) {
|
|
1816
2279
|
const rpcUrl = "client" in options ? "" : options.rpcUrl;
|
|
1817
2280
|
const client = "client" in options ? options.client : createSolanaClient(options.rpcUrl, options.wsUrl);
|
|
2281
|
+
const tokenFetcher = createTokenFetcher();
|
|
1818
2282
|
return {
|
|
1819
2283
|
rpc: client.rpc,
|
|
1820
2284
|
async getBalance(walletAddress, tokenMints) {
|
|
1821
2285
|
return fetchWalletBalance(client.rpc, walletAddress, tokenMints);
|
|
1822
2286
|
},
|
|
1823
2287
|
async getTransactions(walletAddress, options2 = {}) {
|
|
1824
|
-
const {
|
|
2288
|
+
const {
|
|
2289
|
+
limit = 10,
|
|
2290
|
+
before,
|
|
2291
|
+
until,
|
|
2292
|
+
filterSpam = true,
|
|
2293
|
+
spamConfig,
|
|
2294
|
+
enrichNftMetadata = true,
|
|
2295
|
+
enrichTokenMetadata: enrichTokens = true
|
|
2296
|
+
} = options2;
|
|
1825
2297
|
async function enrichBatch(transactions) {
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
const nftMints = transactions.filter((t) => NFT_TRANSACTION_TYPES.includes(t.classification.primaryType)).map((t) => t.classification.metadata?.nft_mint).filter(Boolean);
|
|
1830
|
-
if (nftMints.length === 0) {
|
|
1831
|
-
return transactions;
|
|
2298
|
+
let result2 = transactions;
|
|
2299
|
+
if (enrichTokens) {
|
|
2300
|
+
result2 = await enrichTokenMetadataBatch(tokenFetcher, result2);
|
|
1832
2301
|
}
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
nft_cdn_image: nftData.cdnImage,
|
|
1849
|
-
nft_collection: nftData.collection,
|
|
1850
|
-
nft_symbol: nftData.symbol,
|
|
1851
|
-
nft_attributes: nftData.attributes
|
|
2302
|
+
if (enrichNftMetadata && rpcUrl) {
|
|
2303
|
+
const nftMints = result2.filter(
|
|
2304
|
+
(t) => NFT_TRANSACTION_TYPES.includes(
|
|
2305
|
+
t.classification.primaryType
|
|
2306
|
+
)
|
|
2307
|
+
).map((t) => t.classification.metadata?.nft_mint).filter(Boolean);
|
|
2308
|
+
if (nftMints.length > 0) {
|
|
2309
|
+
const nftMetadataMap = await fetchNftMetadataBatch(
|
|
2310
|
+
rpcUrl,
|
|
2311
|
+
nftMints
|
|
2312
|
+
);
|
|
2313
|
+
result2 = result2.map((t) => {
|
|
2314
|
+
const nftMint = t.classification.metadata?.nft_mint;
|
|
2315
|
+
if (!nftMint || !nftMetadataMap.has(nftMint)) {
|
|
2316
|
+
return t;
|
|
1852
2317
|
}
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
2318
|
+
const nftData = nftMetadataMap.get(nftMint);
|
|
2319
|
+
return {
|
|
2320
|
+
...t,
|
|
2321
|
+
classification: {
|
|
2322
|
+
...t.classification,
|
|
2323
|
+
metadata: {
|
|
2324
|
+
...t.classification.metadata,
|
|
2325
|
+
nft_name: nftData.name,
|
|
2326
|
+
nft_image: nftData.image,
|
|
2327
|
+
nft_cdn_image: nftData.cdnImage,
|
|
2328
|
+
nft_collection: nftData.collection,
|
|
2329
|
+
nft_symbol: nftData.symbol,
|
|
2330
|
+
nft_attributes: nftData.attributes
|
|
2331
|
+
}
|
|
2332
|
+
}
|
|
2333
|
+
};
|
|
2334
|
+
});
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2337
|
+
return result2;
|
|
1856
2338
|
}
|
|
1857
2339
|
if (!filterSpam) {
|
|
1858
|
-
const signatures = await fetchWalletSignatures(
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
2340
|
+
const signatures = await fetchWalletSignatures(
|
|
2341
|
+
client.rpc,
|
|
2342
|
+
walletAddress,
|
|
2343
|
+
{
|
|
2344
|
+
limit,
|
|
2345
|
+
before,
|
|
2346
|
+
until
|
|
2347
|
+
}
|
|
2348
|
+
);
|
|
1863
2349
|
if (signatures.length === 0) {
|
|
1864
2350
|
return [];
|
|
1865
2351
|
}
|
|
@@ -1874,7 +2360,11 @@ function createIndexer(options) {
|
|
|
1874
2360
|
const classified = transactions.map((tx) => {
|
|
1875
2361
|
tx.protocol = detectProtocol(tx.programIds);
|
|
1876
2362
|
const legs = transactionToLegs(tx);
|
|
1877
|
-
const classification = classifyTransaction(
|
|
2363
|
+
const classification = classifyTransaction(
|
|
2364
|
+
legs,
|
|
2365
|
+
tx,
|
|
2366
|
+
walletAddressStr2
|
|
2367
|
+
);
|
|
1878
2368
|
return { tx, classification, legs };
|
|
1879
2369
|
});
|
|
1880
2370
|
return enrichBatch(classified);
|
|
@@ -1887,11 +2377,15 @@ function createIndexer(options) {
|
|
|
1887
2377
|
while (accumulated.length < limit && iteration < MAX_ITERATIONS) {
|
|
1888
2378
|
iteration++;
|
|
1889
2379
|
const batchSize = iteration === 1 ? limit : limit * 2;
|
|
1890
|
-
const signatures = await fetchWalletSignatures(
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
2380
|
+
const signatures = await fetchWalletSignatures(
|
|
2381
|
+
client.rpc,
|
|
2382
|
+
walletAddress,
|
|
2383
|
+
{
|
|
2384
|
+
limit: batchSize,
|
|
2385
|
+
before: currentBefore,
|
|
2386
|
+
until
|
|
2387
|
+
}
|
|
2388
|
+
);
|
|
1895
2389
|
if (signatures.length === 0) {
|
|
1896
2390
|
break;
|
|
1897
2391
|
}
|
|
@@ -1905,7 +2399,11 @@ function createIndexer(options) {
|
|
|
1905
2399
|
const classified = transactions.map((tx) => {
|
|
1906
2400
|
tx.protocol = detectProtocol(tx.programIds);
|
|
1907
2401
|
const legs = transactionToLegs(tx);
|
|
1908
|
-
const classification = classifyTransaction(
|
|
2402
|
+
const classification = classifyTransaction(
|
|
2403
|
+
legs,
|
|
2404
|
+
tx,
|
|
2405
|
+
walletAddressStr
|
|
2406
|
+
);
|
|
1909
2407
|
return { tx, classification, legs };
|
|
1910
2408
|
});
|
|
1911
2409
|
const nonSpam = filterSpamTransactions(classified, spamConfig);
|
|
@@ -1921,7 +2419,10 @@ function createIndexer(options) {
|
|
|
1921
2419
|
return enrichBatch(result);
|
|
1922
2420
|
},
|
|
1923
2421
|
async getTransaction(signature2, options2 = {}) {
|
|
1924
|
-
const {
|
|
2422
|
+
const {
|
|
2423
|
+
enrichNftMetadata = true,
|
|
2424
|
+
enrichTokenMetadata: enrichTokens = true
|
|
2425
|
+
} = options2;
|
|
1925
2426
|
const tx = await fetchTransaction(client.rpc, signature2);
|
|
1926
2427
|
if (!tx) {
|
|
1927
2428
|
return null;
|
|
@@ -1930,6 +2431,9 @@ function createIndexer(options) {
|
|
|
1930
2431
|
const legs = transactionToLegs(tx);
|
|
1931
2432
|
const classification = classifyTransaction(legs, tx);
|
|
1932
2433
|
let classified = { tx, classification, legs };
|
|
2434
|
+
if (enrichTokens) {
|
|
2435
|
+
classified = await enrichTokenMetadata(tokenFetcher, classified);
|
|
2436
|
+
}
|
|
1933
2437
|
if (enrichNftMetadata && rpcUrl) {
|
|
1934
2438
|
classified = await enrichNftClassification(rpcUrl, classified);
|
|
1935
2439
|
}
|
|
@@ -2000,6 +2504,6 @@ function groupLegsByToken(legs) {
|
|
|
2000
2504
|
return grouped;
|
|
2001
2505
|
}
|
|
2002
2506
|
|
|
2003
|
-
export { JUPITER_V4_PROGRAM_ID, JUPITER_V6_PROGRAM_ID, KNOWN_TOKENS, SPL_MEMO_PROGRAM_ID, SYSTEM_PROGRAM_ID, TOKEN_INFO, TOKEN_PROGRAM_ID, buildAccountId, classifyTransaction, createIndexer, createSolanaClient, detectFacilitator, detectProtocol, extractMemo, fetchNftMetadata, fetchNftMetadataBatch, fetchTransaction, fetchTransactionsBatch, fetchWalletBalance, fetchWalletSignatures, filterSpamTransactions, getTokenInfo, groupLegsByAccount, groupLegsByToken, isSolanaPayTransaction, isSpamTransaction, parseAccountId, parseAddress, parseSignature, parseSolanaPayMemo, transactionToLegs, validateLegsBalance };
|
|
2507
|
+
export { JUPITER_V4_PROGRAM_ID, JUPITER_V6_PROGRAM_ID, KNOWN_TOKENS, LIQUID_STAKING_TOKENS, SPL_MEMO_PROGRAM_ID, SUPPORTED_STABLECOINS, SYSTEM_PROGRAM_ID, TOKEN_INFO, TOKEN_PROGRAM_ID, buildAccountId, classifyTransaction, createIndexer, createSolanaClient, createTokenFetcher, createUnknownToken, detectFacilitator, detectProtocol, extractMemo, fetchNftMetadata, fetchNftMetadataBatch, fetchTransaction, fetchTransactionsBatch, fetchWalletBalance, fetchWalletSignatures, filterSpamTransactions, getDefaultTokenFetcher, getTokenInfo, groupLegsByAccount, groupLegsByToken, isSolanaPayTransaction, isSpamTransaction, parseAccountId, parseAddress, parseSignature, parseSolanaPayMemo, transactionToLegs, validateLegsBalance };
|
|
2004
2508
|
//# sourceMappingURL=index.js.map
|
|
2005
2509
|
//# sourceMappingURL=index.js.map
|