Lissanro

Summary of changes for the Scopium backend

Aug 24th, 2025 (edited)
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.93 KB | None | 0 0
  1. ### Summary of Changes
  2.  
  3.  
  4. ### New Endpoints
  5.  
  6. The following new endpoints were added in `src/routes/token.js`:
  7.  
  8. 1. **GET /dev_ip_info**:
  9. - **Purpose**: Retrieves IP-related information for a token's developer/creator.
  10. - **Query Parameters**: `mintAddr` (required).
  11. - **Response**: Includes token details, developer IP information (address, VPN status, score, country), creator details, and bundled status.
  12.  
  13. 2. **GET /get_bundled_tokens**:
  14. - **Purpose**: Retrieves a list of tokens identified as bundled based on a timeframe.
  15. - **Query Parameters**: `timeframe` (default: 60 seconds), `limit` (default: 50), `offset` (default: 0).
  16. - **Response**: List of bundled tokens with details like name, ticker, creator info, trade details, and market cap.
  17.  
  18. 3. **GET /check_bundled_status**:
  19. - **Purpose**: Checks the bundled status of a specific token and triggers retroactive analysis if pending.
  20. - **Query Parameters**: `mintAddr` (required).
  21. - **Response**: Token details, bundled status, trade information, and creator details.
  22.  
  23. 4. **GET /bundled_stats**:
  24. - **Purpose**: Provides statistics on bundled tokens in the system.
  25. - **Query Parameters**: None.
  26. - **Response**: Detailed bundled token statistics (total, bundled, non-bundled, average time delta).
  27.  
  28. 5. **GET /check_ip**:
  29. - **Purpose**: Tests IP address checking for VPN status.
  30. - **Query Parameters**: `ip` (required).
  31. - **Response**: IP check results including VPN status, score, country, and cache status.
  32.  
  33. 6. **GET /test_ip_capture**:
  34. - **Purpose**: Tests IP capture from the client request.
  35. - **Query Parameters**: None.
  36. - **Response**: Client IP, VPN status, score, country, user agent, and timestamp.
  37.  
  38. 7. **GET /analyze_token**:
  39. - **Purpose**: Provides comprehensive analysis of a token.
  40. - **Query Parameters**: `mintAddr` (required).
  41. - **Response**: Detailed token analysis including creator info, holder distribution, bundled status, and risk factors.
  42.  
  43. 8. **GET /top_holders**:
  44. - **Purpose**: Retrieves the top token holders for a given mint address.
  45. - **Query Parameters**: `mintAddr` (required), `limit` (default: 25).
  46. - **Response**: List of top holders with wallet address, hold percentage, SOL amount, and wallet age.
  47.  
  48. 9. **GET /creator_analysis**:
  49. - **Purpose**: Analyzes the creator of a token.
  50. - **Query Parameters**: `mintAddr` (required).
  51. - **Response**: Creator details including wallet address, username, wallet age, IP information, and VPN status.
  52.  
  53. ### New Fields Added to Existing Endpoints
  54.  
  55. 1. **GET /get_token_info** (`src/engine/token.js`):
  56. - **New Fields in Response**:
  57. - `devIpAddress`: Developer's IP address.
  58. - `devIsVPN`: Boolean indicating if the developer's IP is a VPN.
  59. - `devVPNScore`: VPN probability score (0-1).
  60. - `devCountry`: Developer's country based on IP.
  61. - `devIpUpdateTime`: Timestamp of last IP update.
  62. - `creatorLoginCountry`: Creator's login country.
  63. - `creatorFirstIP`: Creator's first login IP.
  64. - `creatorWalletAge`: Object containing wallet age details (`ageInDays`, `createdAt`, `walletAgeFormatted`).
  65. - `isBundled`: Boolean indicating if the token is bundled.
  66. - `bundledStatus`: Status of bundled detection (`pending`, `bundled`, `not_bundled`).
  67. - `firstTradeTime`: Timestamp of the first trade.
  68. - `firstTradeIsBuy`: Boolean indicating if the first trade was a buy.
  69. - `bundledTimeDelta`: Time difference (ms) between token creation and first trade.
  70. - `firstTradeAmount`: Amount of the first trade.
  71. - `creatorFirstBuyAmount`: Creator's first buy amount.
  72. - `bundledDetectionTime`: Timestamp of bundled detection.
  73. - `creatorWalletAgeInDays`: Creator's wallet age in days.
  74. - `creatorWalletAgeFormatted`: Formatted creator wallet age.
  75. - `totalHolders`: Total number of token holders.
  76. - `bundledTokenPercentage`: Percentage of tokens in the system that are bundled.
  77.  
  78. ### Changelog
  79.  
  80. 1. **Database Models**:
  81. - Added a new `IPCache` model (`src/db/model.ip.check.js`) to store IP address check results, including VPN detection, country, ASN, and error tracking.
  82. - Enhanced `Token` model (`src/db/model.token.js`) with fields for developer IP tracking and bundled token detection.
  83. - Enhanced `User` model (`src/db/model.user.js`) with fields for IP tracking (first login IP, last login IP, login country, and total logins).
  84. - Updated `src/db/index.js` to include the new `IPCache` model in exports.
  85.  
  86. 2. **Authentication Enhancements**:
  87. - Modified `src/engine/auth.js` to capture client IP addresses during login and store IP-related information (IP address, country) in the `User` model.
  88.  
  89. 3. **Token Management Enhancements**:
  90. - Updated `src/engine/token.js` to:
  91. - Log client IP during token updates.
  92. - Include IP tracking and bundled token detection data in `getTokenInfo` responses.
  93. - Optimize user ID parsing with `cleanObjectId`.
  94. - Fix query parameter in `getFeedData` from `tokenId` to `mintAddr`.
  95. - Enhance `getThreadData` to handle `cleanedUserId` safely.
  96.  
  97. 4. **New IP Service**:
  98. - Added `src/services/ipService.js`, implementing an `IPService` class to:
  99. - Extract client IP from requests.
  100. - Check IP addresses for VPN usage via GetIPIntel API with rate limiting and caching.
  101. - Cache IP check results in the `IPCache` model.
  102. - Provide statistics on IP checks.
  103.  
  104. 5. **Token Analysis**:
  105. - Added `src/engine/tokenAnalysis.js` to provide comprehensive token analysis, including:
  106. - Bundled token statistics.
  107. - Holder pattern analysis (e.g., high concentration, new wallets, low SOL amounts).
  108. - Comprehensive token analysis combining token, creator, and holder data.
  109.  
  110. 6. **Solana Engine Enhancements**:
  111. - Updated `src/solana/engine.js` to:
  112. - Add `limit` parameter to `getTokenHolderDistribution` for flexible holder queries.
  113. - Implement `getWalletAge` with caching to calculate wallet age efficiently.
  114. - Enhance holder distribution with additional fields like wallet age and user avatar.
  115.  
  116. 7. **Solana Web3 Enhancements**:
  117. - Updated `src/solana/solana_web3.js` to:
  118. - Handle `bs58` import issues and provide fallback for invalid `ADMIN_PRIVKEY`.
  119. - Add bundled trade detection logic in `onTradeEvent`, identifying tokens with trades within 60 seconds of creation.
  120.  
  121. 7. **New Routes**:
  122. - Added multiple new endpoints in `src/routes/token.js` for IP tracking, bundled token detection, and token analysis.
  123.  
  124.  
  125. ### Additional Notes
  126. - **IP Tracking**: The addition of IP tracking (via `ipService.js`) enhances security by monitoring user and developer IP addresses for VPN usage and geographic information, cached in the `IPCache` model to reduce API calls.
  127. - **Bundled Token Detection**: New logic in `src/solana/solana_web3.js` and `src/engine/tokenAnalysis.js` identifies tokens with trades within 60 seconds of creation as potentially bundled, improving fraud detection.
  128. - **Performance Optimizations**: Caching (e.g., wallet age, IP checks) and batch processing (e.g., in `getTokenHolderDistribution`) improve efficiency.
  129. - **Error Handling**: Enhanced error handling in new endpoints and services ensures robust responses to invalid inputs or API failures.
  130.  
  131.  
  132. ### Example responses of API endpoints
  133.  
  134. #### /api/token/get_token_info?mintAddr=DYnYitMA5KVS43F9U5ku3SZ7bnfgZTfJcf6f6GriFame
  135. {
  136. "id": "6867cf8e6645c852166e57d8",
  137. "name": "Test3",
  138. "ticker": "TES",
  139. "mintAddr": "DYnYitMA5KVS43F9U5ku3SZ7bnfgZTfJcf6f6GriFame",
  140. "desc": "sdf",
  141. "logo": "https://arweave.net/sAMQRBJoBL80Ax0dSqmEb2OOHDHXRgK6Wy49rxfek7k",
  142. "banner": null,
  143. "twitter": null,
  144. "telegram": null,
  145. "website": null,
  146. "cdate": "2025-07-04T12:56:48.186Z",
  147. "marketCap": 35,
  148. "price": {
  149. "_id": "6867cf8e6645c852166e57da",
  150. "baseReserve": 800000000000000,
  151. "quoteReserve": 28000000000,
  152. "price": 3.5e-8
  153. },
  154. "virtLiq": 56000000000,
  155. "walletAddr": "21g6VKka2r4qbmqnHskyLLuEt4YrBbdMnx94ZojSaoBL",
  156. "username": "21g6VK",
  157. "avatar": null,
  158. "tokenBalance": 0,
  159. "solBalance": 0,
  160. "replies": 0,
  161. "bondingCurveProgress": 0,
  162. "kingOfTheHillProgress": 0,
  163. "crownDate": null,
  164. "tokensAvailableForSale": 640000000,
  165. "realQuoteReserve": 0,
  166. "tokenHolderDistribution": [
  167. {
  168. "walletAddr": "CUZZmeuB8HLD3cuukCnHfLaKd5kGs3SX1FmBmnBazRMr",
  169. "username": "CUZZme",
  170. "bio": null,
  171. "holdPercent": 79.5686413621852,
  172. "solAmount": 0.00189312,
  173. "createdAt": 1751633804,
  174. "walletAgeInDays": 51,
  175. "walletAgeFormatted": "51 days",
  176. "isDev": false,
  177. "isKnownUser": false,
  178. "userAvatar": null
  179. },
  180. {
  181. "walletAddr": "4tp3Rgd9HwrZxY4oxeGV1FPG3JSeWtNRu1a217r698Fx",
  182. "username": "4tp3Rg",
  183. "bio": null,
  184. "holdPercent": 20,
  185. "solAmount": 0,
  186. "createdAt": 1755278973,
  187. "walletAgeInDays": 8,
  188. "walletAgeFormatted": "8 days",
  189. "isDev": false,
  190. "isKnownUser": false,
  191. "userAvatar": null
  192. },
  193. {
  194. "walletAddr": "21g6VKka2r4qbmqnHskyLLuEt4YrBbdMnx94ZojSaoBL",
  195. "username": "21g6VK",
  196. "bio": "dev",
  197. "holdPercent": 0.4313586378148,
  198. "solAmount": 42.20951092,
  199. "createdAt": 1751633804,
  200. "walletAgeInDays": 51,
  201. "walletAgeFormatted": "51 days",
  202. "isDev": true,
  203. "isKnownUser": true,
  204. "userAvatar": null
  205. }
  206. ],
  207. "isFavorited": false,
  208. "isWatchListed": false,
  209. "devIpAddress": null,
  210. "devIsVPN": null,
  211. "devVPNScore": null,
  212. "devCountry": null,
  213. "devIpUpdateTime": null,
  214. "creatorLoginCountry": null,
  215. "creatorFirstIP": null,
  216. "creatorWalletAge": {
  217. "ageInDays": 51,
  218. "createdAt": 1751633804,
  219. "walletAgeFormatted": "51 days"
  220. },
  221. "isBundled": false,
  222. "bundledStatus": "not_bundled",
  223. "firstTradeTime": null,
  224. "firstTradeIsBuy": null,
  225. "bundledTimeDelta": null,
  226. "firstTradeAmount": 0,
  227. "creatorFirstBuyAmount": 0,
  228. "bundledDetectionTime": null,
  229. "creatorWalletAgeInDays": 51,
  230. "creatorWalletAgeFormatted": "51 days",
  231. "totalHolders": 3,
  232. "bundledTokenPercentage": 0
  233. }
  234.  
  235.  
  236. #### /api/token/dev_ip_info?mintAddr=DYnYitMA5KVS43F9U5ku3SZ7bnfgZTfJcf6f6GriFame
  237. {
  238. "success": true,
  239. "data": {
  240. "mintAddr": "DYnYitMA5KVS43F9U5ku3SZ7bnfgZTfJcf6f6GriFame",
  241. "tokenName": "Test3",
  242. "ticker": "TES",
  243. "devIpAddress": null,
  244. "devIsVPN": null,
  245. "devVPNScore": null,
  246. "devCountry": null,
  247. "devIpUpdateTime": null,
  248. "creatorWallet": "21g6VKka2r4qbmqnHskyLLuEt4YrBbdMnx94ZojSaoBL",
  249. "creatorUsername": "21g6VK",
  250. "creatorFirstIP": null,
  251. "creatorLastLoginIP": null,
  252. "creatorLoginCountry": null,
  253. "creatorTotalLogins": 0,
  254. "isBundled": false,
  255. "bundledStatus": "not_bundled",
  256. "firstTradeTime": null,
  257. "bundledTimeDelta": null
  258. }
  259. }
  260.  
  261.  
  262. #### /api/token/check_bundled_status?mintAddr=DYnYitMA5KVS43F9U5ku3SZ7bnfgZTfJcf6f6GriFame
  263. {
  264. "mintAddr": "DYnYitMA5KVS43F9U5ku3SZ7bnfgZTfJcf6f6GriFame",
  265. "name": "Test3",
  266. "isBundled": false,
  267. "bundledStatus": "not_bundled",
  268. "bundledTimeDelta": null,
  269. "firstTradeIsBuy": null,
  270. "firstTradeTime": null,
  271. "firstTradeAmount": 0,
  272. "creationTime": "2025-07-04T12:56:48.186Z",
  273. "creatorWallet": "21g6VKka2r4qbmqnHskyLLuEt4YrBbdMnx94ZojSaoBL",
  274. "creatorUsername": "21g6VK",
  275. "firstTrader": null
  276. }
  277.  
  278. > /api/token/check_ip?ip=1.1.1.1
  279. {
  280. "success": true,
  281. "data": {
  282. "ip": "1.1.1.1",
  283. "isVPN": true,
  284. "vpnScore": 1,
  285. "country": null,
  286. "fromCache": true,
  287. "checkTime": "2025-08-24T13:41:55.172Z"
  288. }
  289. }
  290.  
  291. #### /api/token/test_ip_capture
  292. {
  293. "success": true,
  294. "data": {
  295. "ip": "::1",
  296. "isVPN": false,
  297. "vpnScore": 0,
  298. "country": "localhost",
  299. "userAgent": "curl/8.12.1",
  300. "timestamp": "2025-08-24T13:43:06.247Z"
  301. }
  302. }
  303.  
  304.  
  305. #### /api/token/top_holders?mintAddr=DYnYitMA5KVS43F9U5ku3SZ7bnfgZTfJcf6f6GriFame&limit=25
  306. {
  307. "success": true,
  308. "data": {
  309. "mintAddr": "DYnYitMA5KVS43F9U5ku3SZ7bnfgZTfJcf6f6GriFame",
  310. "holders": [
  311. {
  312. "walletAddr": "CUZZmeuB8HLD3cuukCnHfLaKd5kGs3SX1FmBmnBazRMr",
  313. "username": "CUZZme",
  314. "bio": null,
  315. "holdPercent": 79.5686413621852,
  316. "solAmount": 0.00189312,
  317. "createdAt": 1751633804,
  318. "walletAgeInDays": 51,
  319. "walletAgeFormatted": "51 days",
  320. "isDev": false,
  321. "isKnownUser": false,
  322. "userAvatar": null
  323. },
  324. {
  325. "walletAddr": "4tp3Rgd9HwrZxY4oxeGV1FPG3JSeWtNRu1a217r698Fx",
  326. "username": "4tp3Rg",
  327. "bio": null,
  328. "holdPercent": 20,
  329. "solAmount": 0,
  330. "createdAt": 1755278973,
  331. "walletAgeInDays": 8,
  332. "walletAgeFormatted": "8 days",
  333. "isDev": false,
  334. "isKnownUser": false,
  335. "userAvatar": null
  336. },
  337. {
  338. "walletAddr": "21g6VKka2r4qbmqnHskyLLuEt4YrBbdMnx94ZojSaoBL",
  339. "username": "21g6VK",
  340. "bio": "dev",
  341. "holdPercent": 0.4313586378148,
  342. "solAmount": 42.20951092,
  343. "createdAt": 1751633804,
  344. "walletAgeInDays": 51,
  345. "walletAgeFormatted": "51 days",
  346. "isDev": true,
  347. "isKnownUser": true,
  348. "userAvatar": null
  349. }
  350. ],
  351. "count": 3
  352. }
  353. }
  354.  
  355.  
  356. #### /api/token/creator_analysis?mintAddr=DYnYitMA5KVS43F9U5ku3SZ7bnfgZTfJcf6f6GriFame
  357. {
  358. "success": true,
  359. "data": {
  360. "creatorWallet": "21g6VKka2r4qbmqnHskyLLuEt4YrBbdMnx94ZojSaoBL",
  361. "creatorUsername": "21g6VK",
  362. "creatorWalletAge": {
  363. "ageInDays": 51,
  364. "createdAt": 1751633804,
  365. "walletAgeFormatted": "51 days"
  366. },
  367. "creatorFirstIP": null,
  368. "creatorLoginCountry": null,
  369. "creatorIsVPN": null,
  370. "creatorVPNScore": null,
  371. "creationTime": "2025-07-04T12:56:48.186Z"
  372. }
  373. }
  374.  
  375.  
  376. #### /api/token/get_bundled_tokens
  377. {
  378. "count": 0,
  379. "tokens": [],
  380. "timeframe": "60s",
  381. "timestamp": "2025-08-24T13:39:42.624Z"
  382. }
  383.  
  384.  
  385. #### /api/token/bundled_stats
  386. {
  387. "success": true,
  388. "data": {
  389. "totalTokens": 3,
  390. "bundledTokens": 0,
  391. "bundledPercentage": 0,
  392. "nonBundledTokens": 3,
  393. "averageTimeDelta": 0
  394. }
  395. }
Advertisement
Add Comment
Please, Sign In to add comment