@@ -16,11 +16,11 @@ import {
1616 type RateEngine ,
1717 type RateProvider ,
1818 type TokenMap ,
19- type TokenTypeMap ,
2019 wasCrossChainDoc ,
2120 wasExistingMappings
2221} from '../../types'
2322import {
23+ create30MinuteSyncInterval ,
2424 createTokenId ,
2525 expandReturnedCryptoRates ,
2626 isCurrent ,
@@ -74,7 +74,7 @@ const asCoingeckoAssetResponse = asArray(
7474
7575const asGeckoBulkUsdResponse = asObject (
7676 asObject ( {
77- usd : asNumber
77+ usd : asMaybe ( asNumber )
7878 } )
7979)
8080
@@ -111,15 +111,9 @@ const platformIdMappingSyncDoc = syncedDocument(
111111 'coingecko:platforms' ,
112112 asStringNullMap
113113)
114- manualTokenMappingsSyncDoc . sync ( dbSettings ) . catch ( e => {
115- console . error ( 'manualTokenMappingsSyncDoc sync error' , e )
116- } )
117- automatedTokenMappingsSyncDoc . sync ( dbSettings ) . catch ( e => {
118- console . error ( 'automatedTokenMappingsSyncDoc sync error' , e )
119- } )
120- platformIdMappingSyncDoc . sync ( dbSettings ) . catch ( e => {
121- console . error ( 'platformIdMappingSyncDoc sync error' , e )
122- } )
114+ create30MinuteSyncInterval ( manualTokenMappingsSyncDoc , dbSettings )
115+ create30MinuteSyncInterval ( automatedTokenMappingsSyncDoc , dbSettings )
116+ create30MinuteSyncInterval ( platformIdMappingSyncDoc , dbSettings )
123117manualTokenMappingsSyncDoc . onChange ( manualMappings => {
124118 coingeckoTokenIdMap = {
125119 ...automatedTokenMappingsSyncDoc . doc ,
@@ -133,25 +127,40 @@ automatedTokenMappingsSyncDoc.onChange(automatedMappings => {
133127 }
134128} )
135129
136- const coingeckoToCrossChainMapping = async (
137- coingeckoAssets : ReturnType < typeof asCoingeckoAssetResponse > ,
138- tokenTypes : TokenTypeMap
139- ) : Promise < CrossChainMapping > => {
130+ const tokenMapping : RateEngine = async ( ) => {
131+ const uidMapping : TokenMap = { }
132+ const crossChainMapping : CrossChainMapping = { }
133+
134+ // Add the mainnet currency mapping
135+ for ( const [ key , value ] of Object . entries ( coingeckoMainnetCurrencyMapping ) ) {
136+ if ( value === null ) continue
137+ uidMapping [ key ] = {
138+ id : value ,
139+ displayName : key
140+ }
141+ }
142+
143+ const json = await fetchCoingecko (
144+ `${ config . providers . coingeckopro . uri } /api/v3/coins/list?include_platform=true`
145+ )
146+ const tokenTypes = asCouchDoc ( asTokenTypeMap ) (
147+ await dbSettings . get ( TOKEN_TYPES_KEY )
148+ )
149+
150+ const data = asCoingeckoAssetResponse ( json )
151+
140152 const invertPlatformMapping : Record < string , string > = { }
141153 for ( const [ key , value ] of Object . entries ( platformIdMappingSyncDoc . doc ) ) {
142154 if ( value === null ) continue
143155 invertPlatformMapping [ value ] = key
144156 }
157+
145158 const platformPriorityDoc = await dbSettings . get ( 'platformPriority' )
146159 const platformPriority = asCouchDoc ( asNumberMap ) ( platformPriorityDoc ) . doc
147160 const getPriority = ( k : string ) : number =>
148161 platformPriority [ k ] ?? Number . MAX_SAFE_INTEGER
149162
150- const out : CrossChainMapping = { }
151-
152- for ( const asset of coingeckoAssets ) {
153- let destAsset : { destChain : string ; edgeTokenId : string } | undefined
154-
163+ for ( const asset of data ) {
155164 const platforms = Object . entries ( asset . platforms )
156165
157166 const sortedPlatforms = platforms . sort (
@@ -160,24 +169,32 @@ const coingeckoToCrossChainMapping = async (
160169 getPriority ( invertPlatformMapping [ b [ 0 ] ] )
161170 )
162171
172+ let destAsset : { destChain : string ; edgeTokenId : string } | undefined
173+
163174 for ( const [ platform , address ] of sortedPlatforms ) {
164175 const edgePluginId = invertPlatformMapping [ platform ]
165176 if ( edgePluginId == null ) continue
166177
167- const tokenType = tokenTypes [ edgePluginId ]
178+ const tokenType = tokenTypes . doc [ edgePluginId ]
168179 if ( tokenType == null ) continue
169180
170181 try {
171182 const tokenId = createTokenId ( tokenType , asset . symbol , address )
172183 if ( tokenId == null ) continue
173184
185+ // Build cross-chain mappings and track the best platform
174186 if ( destAsset == null ) {
175187 destAsset = {
176188 destChain : edgePluginId ,
177189 edgeTokenId : tokenId
178190 }
191+ // Create UID mapping for the best (first) platform
192+ uidMapping [ toCryptoKey ( { pluginId : edgePluginId , tokenId } ) ] = {
193+ id : asset . id ,
194+ displayName : asset . name
195+ }
179196 } else {
180- out [ `${ edgePluginId } _${ tokenId } ` ] = {
197+ crossChainMapping [ `${ edgePluginId } _${ tokenId } ` ] = {
181198 sourceChain : edgePluginId ,
182199 destChain : destAsset . destChain ,
183200 currencyCode : asset . symbol ,
@@ -191,67 +208,9 @@ const coingeckoToCrossChainMapping = async (
191208 }
192209 }
193210
194- return out
195- }
196-
197- const tokenMapping : RateEngine = async ( ) => {
198- const mapping : TokenMap = { }
199-
200- // Add the mainnet currency mapping
201- for ( const [ key , value ] of Object . entries ( coingeckoMainnetCurrencyMapping ) ) {
202- if ( value === null ) continue
203- mapping [ key ] = {
204- id : value ,
205- displayName : key
206- }
207- }
208-
209- const json = await fetchCoingecko (
210- `${ config . providers . coingeckopro . uri } /api/v3/coins/list?include_platform=true`
211- )
212- const tokenTypes = asCouchDoc ( asTokenTypeMap ) (
213- await dbSettings . get ( TOKEN_TYPES_KEY )
214- )
215-
216- const data = asCoingeckoAssetResponse ( json )
217-
218- const invertPlatformMapping : Record < string , string > = { }
219- for ( const [ key , value ] of Object . entries ( platformIdMappingSyncDoc . doc ) ) {
220- if ( value === null ) continue
221- invertPlatformMapping [ value ] = key
222- }
223-
224- for ( const asset of data ) {
225- const firstPlatform : [ string , string ] | undefined = Object . entries (
226- asset . platforms
227- ) [ 0 ]
228- if ( firstPlatform == null ) continue
229-
230- const [ platform , contractAddress ] = firstPlatform
231-
232- const pluginId = invertPlatformMapping [ platform ]
233- if ( pluginId == null ) continue
234-
235- try {
236- const tokenId = createTokenId (
237- tokenTypes . doc [ pluginId ] ,
238- asset . symbol ,
239- contractAddress
240- )
241- if ( tokenId == null ) continue
242-
243- mapping [ toCryptoKey ( { pluginId, tokenId } ) ] = {
244- id : asset . id ,
245- displayName : asset . name
246- }
247- } catch ( e ) {
248- // skip assets that we cannot create token id for
249- }
250- }
251-
252211 const combinedTokenMappings : TokenMap = {
253212 ...automatedTokenMappingsSyncDoc . doc ,
254- ...mapping
213+ ...uidMapping
255214 }
256215
257216 await dbSettings . insert (
@@ -262,17 +221,15 @@ const tokenMapping: RateEngine = async () => {
262221 } )
263222 )
264223
265- const crossChainDocument = await dbSettings . get ( 'crosschain:automated' )
266- const crossChainDoc = asCrossChainDoc ( crossChainDocument )
267- const crossChainMappings = await coingeckoToCrossChainMapping (
268- data ,
269- tokenTypes . doc as TokenTypeMap
270- )
224+ const crossChainDefaultDocument = await dbSettings . get ( 'crosschain' )
225+ const crossChainDefaultDoc = asCrossChainDoc ( crossChainDefaultDocument )
226+ const crossChainAutoDocument = await dbSettings . get ( 'crosschain:automated' )
227+ const crossChainAutoDoc = asCrossChainDoc ( crossChainAutoDocument )
271228 await dbSettings . insert (
272229 wasCrossChainDoc ( {
273- id : crossChainDoc . id ,
274- rev : crossChainDoc . rev ,
275- doc : crossChainMappings
230+ id : crossChainAutoDoc . id ,
231+ rev : crossChainAutoDoc . rev ,
232+ doc : { ... crossChainMapping , ... crossChainDefaultDoc . doc }
276233 } )
277234 )
278235}
@@ -287,7 +244,9 @@ const getCurrentRates = async (ids: Set<string>): Promise<NumberMap> => {
287244 )
288245 const data = asGeckoBulkUsdResponse ( json )
289246 for ( const [ key , value ] of Object . entries ( data ) ) {
290- out [ key ] = value . usd
247+ if ( value . usd != null ) {
248+ out [ key ] = value . usd
249+ }
291250 }
292251 } catch ( e ) {
293252 console . error ( 'coingecko current query error:' , e )
0 commit comments