@@ -8,85 +8,72 @@ const {
88} = require ( '../helpers' ) ;
99
1010const COLLECTION_NAME = 'kadenaTokens' ;
11-
1211const dbName = process . env . MONGO_DB || 'dextools' ;
1312
1413let mongoClient = null ;
1514let db = null ;
1615
17- const updateKadenaTokens = async ( chainId ) => {
16+ const getTokensBatch = async ( chainId ) => {
1817 const pactCode = `(let
1918 ((all-tokens
2019 (lambda (contract:object)
2120 (let*
2221 ((module-name (at 'name contract))
23- (interfaces (if (contains 'interfaces contract) (at 'interfaces contract) (if (contains 'interface contract) (at 'interface contract) [])))
22+ (interfaces (if (contains 'interfaces contract)
23+ (at 'interfaces contract)
24+ (if (contains 'interface contract)
25+ (at 'interface contract)
26+ [])))
2427 (is-implementing-fungible-v2 (contains "fungible-v2" interfaces))
2528 )
26- (if is-implementing-fungible-v2 module-name "")
29+ (if is-implementing-fungible-v2 module-name "")
2730 )
2831 )
2932 )
3033 )
3134 (filter (!= "") (map (all-tokens) (map (describe-module) (list-modules))))
3235 )` ;
33- const invalidChainTokens = [ ] ;
3436
35- try {
36- const { db } = await mongoConnect ( ) ;
37- const collection = db . collection ( COLLECTION_NAME ) ;
37+ const res = await makePactCall ( chainId . toString ( ) , pactCode ) ;
3838
39- const res = await makePactCall ( chainId . toString ( ) , pactCode ) ;
40- if ( res ?. result ?. data ?. length > 0 ) {
41- console . log ( `[CHAIN ${ chainId } ] FOUND ${ res ?. result ?. data ?. length } tokens` ) ;
42- const storedTokens = await getStoredKadenaTokensByChain ( chainId ) ;
43- console . log ( `[CHAIN ${ chainId } ] ${ storedTokens ?. length } tokens already saved` ) ;
44- const difference = res ?. result ?. data ?. filter ( ( t ) => ! storedTokens . includes ( t ) ) ;
45-
46- if ( difference . length ) {
47- console . log ( `[CHAIN ${ chainId } ] FOUNDED ${ difference . length } new tokens: ${ difference . join ( ', ' ) } ` ) ;
48- const validChainTokens = storedTokens ;
49- let tokenCount = 1 ;
50-
51- for ( const token of difference ) {
52- try {
53- const isTokenWorking = await makePactCall ( chainId . toString ( ) , `(${ token } .get-balance "k:alice")` ) ;
54- await sleep ( 500 ) ;
55- if ( isTokenWorking ?. result ?. status === 'success' || isTokenWorking ?. result ?. error ?. message ?. includes ( 'row not found' ) ) {
56- validChainTokens . push ( token ) ;
57- } else {
58- console . error ( `[CHAIN ${ chainId } ] TOKEN ${ token } IS NOT VALID` ) ;
59- invalidChainTokens . push ( token ) ;
60- }
61- } catch ( err ) {
62- console . error ( `FETCH ERROR ${ token } :` , err ) ;
63- }
64-
65- tokenCount += 1 ;
66- }
39+ if ( res ?. result ?. status === 'success' && Array . isArray ( res ?. result ?. data ) ) {
40+ return res . result . data ;
41+ } else {
42+ throw new Error ( `Batch approach failed on chain ${ chainId } : ${ res ?. result ?. error ?. message } ` ) ;
43+ }
44+ } ;
6745
68- console . log ( `[CHAIN ${ chainId } ] invalid TOKENS: ${ invalidChainTokens . length } /${ res ?. result ?. data ?. length } ` ) ;
69-
70- // Upsert in MongoDB
71- await collection . updateOne (
72- { chainId : chainId . toString ( ) } ,
73- {
74- $set : {
75- tokens : stringify ( validChainTokens ) ,
76- lastUpdate : new Date ( ) . toISOString ( ) ,
77- } ,
78- } ,
79- { upsert : true }
80- ) ;
81- console . log ( 'UPLOADING TOKENS ON CHAIN ' + chainId ) ;
46+ const getTokensFallback = async ( chainId ) => {
47+ console . log ( `[CHAIN ${ chainId } ] Fallback: describing each module...` ) ;
48+ const listRes = await makePactCall ( chainId . toString ( ) , '(list-modules)' ) ;
49+ if ( listRes ?. result ?. status !== 'success' || ! Array . isArray ( listRes . result ?. data ) ) {
50+ console . error ( `[CHAIN ${ chainId } ] Fallback list-modules failed` ) ;
51+ return [ ] ;
52+ }
53+
54+ const modules = listRes . result . data ;
55+ console . log ( `[CHAIN ${ chainId } ] Fallback found ${ modules . length } modules` ) ;
56+ const fungibleTokens = [ ] ;
57+ let i = 1 ;
58+ for ( const mod of modules ) {
59+ try {
60+ const descRes = await makePactCall ( chainId . toString ( ) , `(describe-module "${ mod } ")` ) ;
61+ if ( descRes ?. result ?. status === 'success' ) {
62+ const data = descRes . result ?. data ;
63+ const interfaces = data ?. interfaces || data ?. interface || [ ] ;
64+ if ( interfaces . includes ( 'fungible-v2' ) ) {
65+ console . log ( `[CHAIN ${ chainId } ] ${ i } /${ modules . length } Found fungible token: ${ data . name } ` ) ;
66+ fungibleTokens . push ( data . name ) ;
67+ } else {
68+ console . log ( `[CHAIN ${ chainId } ] ${ i } /${ modules . length } Skipping non-fungible token: ${ data . name } ` ) ;
69+ }
8270 }
83- } else {
84- console . error ( `NO TOKENS FOUNDED ON CHAIN ${ chainId } ` , res ) ;
71+ } catch ( err ) {
72+ console . error ( `[CHAIN ${ chainId } ] Fallback error describing ${ mod } ` , err ) ;
8573 }
86- } catch ( err ) {
87- console . error ( `ERROR FETCHING TOKENS ON CHAIN ${ chainId } ` ) ;
88- console . log ( err ) ;
74+ i ++ ;
8975 }
76+ return fungibleTokens ;
9077} ;
9178
9279const getStoredKadenaTokensByChain = async ( chainId ) => {
@@ -102,6 +89,82 @@ const getStoredKadenaTokensByChain = async (chainId) => {
10289 }
10390} ;
10491
92+ const updateKadenaTokens = async ( chainId ) => {
93+ const invalidChainTokens = [ ] ;
94+ let tokens = [ ] ;
95+
96+ try {
97+ tokens = await getTokensBatch ( chainId ) ;
98+ console . log ( `[CHAIN ${ chainId } ] BATCH FOUND ${ tokens ?. length } tokens` ) ;
99+ } catch ( err ) {
100+ console . error ( `[CHAIN ${ chainId } ] Batch approach failed or returned no data:` , err . message ) ;
101+ tokens = await getTokensFallback ( chainId ) ;
102+ console . log ( `[CHAIN ${ chainId } ] Fallback found ${ tokens . length } tokens` ) ;
103+ }
104+
105+ if ( ! tokens . length ) {
106+ console . error ( `NO TOKENS FOUNDED ON CHAIN ${ chainId } ` ) ;
107+ return ;
108+ }
109+
110+ const storedTokens = await getStoredKadenaTokensByChain ( chainId ) ;
111+ console . log ( `[CHAIN ${ chainId } ] ${ storedTokens ?. length } tokens already saved` ) ;
112+ const difference = tokens . filter ( ( t ) => ! storedTokens . includes ( t ) ) ;
113+
114+ if ( ! difference . length ) {
115+ console . log ( `[CHAIN ${ chainId } ] No new tokens to add.` ) ;
116+ return ;
117+ }
118+
119+ console . log ( `[CHAIN ${ chainId } ] FOUND ${ difference . length } new tokens: ${ difference . join ( ', ' ) } ` ) ;
120+
121+ const validChainTokens = [ ...storedTokens ] ;
122+ let tokenCount = 1 ;
123+
124+ for ( const token of difference ) {
125+ try {
126+ const isTokenWorking = await makePactCall ( chainId . toString ( ) , `(${ token } .get-balance "k:alice")` ) ;
127+ // await sleep(500);
128+ if (
129+ isTokenWorking ?. result ?. status === 'success' ||
130+ isTokenWorking ?. result ?. error ?. message ?. includes ( 'row not found' ) ||
131+ isTokenWorking ?. result ?. error ?. message ?. includes ( 'No value found in table' )
132+ ) {
133+ console . log ( `[CHAIN ${ chainId } ] TOKEN ${ tokenCount } /${ tokens . length } : ${ token } IS VALID` ) ;
134+ validChainTokens . push ( token ) ;
135+ } else {
136+ console . error ( `[CHAIN ${ chainId } ] TOKEN ${ tokenCount } /${ tokens . length } : ${ token } IS NOT VALID` ) ;
137+ invalidChainTokens . push ( token ) ;
138+ }
139+ } catch ( err ) {
140+ console . error ( `FETCH ERROR ${ token } :` , err ) ;
141+ }
142+
143+ tokenCount += 1 ;
144+ }
145+
146+ console . log ( `[CHAIN ${ chainId } ] invalid TOKENS: ${ invalidChainTokens . length } /${ tokens . length } ` ) ;
147+
148+ try {
149+ const { db } = await mongoConnect ( ) ;
150+ const collection = db . collection ( COLLECTION_NAME ) ;
151+
152+ await collection . updateOne (
153+ { chainId : chainId . toString ( ) } ,
154+ {
155+ $set : {
156+ tokens : stringify ( validChainTokens ) ,
157+ lastUpdate : new Date ( ) . toISOString ( ) ,
158+ } ,
159+ } ,
160+ { upsert : true }
161+ ) ;
162+ console . log ( `[CHAIN ${ chainId } ] SAVED TOKENS => ${ validChainTokens . length } total` ) ;
163+ } catch ( dbErr ) {
164+ console . error ( `[CHAIN ${ chainId } ] Error saving to Mongo:` , dbErr ) ;
165+ }
166+ } ;
167+
105168const allKadenaTokenUpdate = async ( ) => {
106169 try {
107170 for ( let chainId = 0 ; chainId < KADENA_CHAINS_COUNT ; chainId ++ ) {
@@ -116,4 +179,7 @@ const allKadenaTokenUpdate = async () => {
116179 }
117180} ;
118181
119- module . exports = { allKadenaTokenUpdate, getStoredKadenaTokensByChain } ;
182+ module . exports = {
183+ allKadenaTokenUpdate,
184+ getStoredKadenaTokensByChain,
185+ } ;
0 commit comments