Skip to content

Commit 56d9855

Browse files
authored
Merge pull request #116 from EdgeApp/sync-doc
Add hardcoded and manual crosschain mappings
2 parents 679159a + 136c3f5 commit 56d9855

File tree

11 files changed

+230
-116
lines changed

11 files changed

+230
-116
lines changed

src/v3/providers/allProviders.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { coingecko } from './coingecko/coingecko'
33
import { coinmarketcap } from './coinmarketcap/coinmarketcap'
44
// import { coinmonitor } from './coinmonitor'
55
import { coinstore } from './coinstore'
6+
import { constantRates } from './constantRates'
67
import { couch } from './couch'
78
import { currencyconverter } from './currencyconverter'
89
import { edgerates } from './edgerates/edgerates'
@@ -19,6 +20,7 @@ const looselyOrderedProviders: RateProvider[] = [
1920
wazirx,
2021
coinmarketcap,
2122
coingecko,
23+
constantRates,
2224
currencyconverter,
2325
couch,
2426
redis

src/v3/providers/coingecko/coingecko.ts

Lines changed: 50 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ import {
1616
type RateEngine,
1717
type RateProvider,
1818
type TokenMap,
19-
type TokenTypeMap,
2019
wasCrossChainDoc,
2120
wasExistingMappings
2221
} from '../../types'
2322
import {
23+
create30MinuteSyncInterval,
2424
createTokenId,
2525
expandReturnedCryptoRates,
2626
isCurrent,
@@ -74,7 +74,7 @@ const asCoingeckoAssetResponse = asArray(
7474

7575
const 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)
123117
manualTokenMappingsSyncDoc.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)

src/v3/providers/coingecko/defaultPluginIdMapping.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { StringNullMap } from '../../types'
22

33
export const coingeckoMainnetCurrencyMapping: StringNullMap = {
4+
abstract: 'ethereum',
45
algorand: 'algorand',
56
arbitrum: 'ethereum',
67
avalanche: 'avalanche-2',
@@ -13,6 +14,7 @@ export const coingeckoMainnetCurrencyMapping: StringNullMap = {
1314
bitcoingold: 'bitcoin-gold',
1415
bitcoinsv: 'bitcoin-cash-sv',
1516
bobevm: 'ethereum',
17+
botanix: 'bitcoin',
1618
cardano: 'cardano',
1719
celo: 'celo',
1820
coreum: 'coreum',
@@ -59,7 +61,7 @@ export const coingeckoMainnetCurrencyMapping: StringNullMap = {
5961
ton: 'the-open-network',
6062
tron: 'tron',
6163
ufo: null,
62-
vertcoin: null,
64+
vertcoin: 'vertcoin',
6365
wax: null,
6466
zcash: 'zcash',
6567
zcoin: 'zcoin',
@@ -68,6 +70,7 @@ export const coingeckoMainnetCurrencyMapping: StringNullMap = {
6870
}
6971

7072
export const coingeckoPlatformIdMapping: StringNullMap = {
73+
abstract: 'abstract',
7174
algorand: 'algorand',
7275
arbitrum: 'arbitrum-one',
7376
avalanche: 'avalanche',
@@ -80,6 +83,7 @@ export const coingeckoPlatformIdMapping: StringNullMap = {
8083
bitcoingold: null,
8184
bitcoinsv: null,
8285
bobevm: 'bob-network',
86+
botanix: 'botanix',
8387
cardano: 'cardano',
8488
celo: 'celo',
8589
coreum: 'coreum',

src/v3/providers/coinmarketcap/coinmarketcap.ts

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
wasExistingMappings
2323
} from '../../types'
2424
import {
25+
create30MinuteSyncInterval,
2526
createTokenId,
2627
expandReturnedCryptoRates,
2728
isCurrent,
@@ -144,15 +145,9 @@ const platformIdMappingSyncDoc = syncedDocument(
144145
'coinmarketcap:platforms',
145146
asStringNullMap
146147
)
147-
userTokenMappingsSyncDoc.sync(dbSettings).catch(e => {
148-
console.error('manualTokenMappingsSyncDoc sync error', e)
149-
})
150-
automatedTokenMappingsSyncDoc.sync(dbSettings).catch(e => {
151-
console.error('automatedTokenMappingsSyncDoc sync error', e)
152-
})
153-
platformIdMappingSyncDoc.sync(dbSettings).catch(e => {
154-
console.error('platformIdMappingSyncDoc sync error', e)
155-
})
148+
create30MinuteSyncInterval(userTokenMappingsSyncDoc, dbSettings)
149+
create30MinuteSyncInterval(automatedTokenMappingsSyncDoc, dbSettings)
150+
create30MinuteSyncInterval(platformIdMappingSyncDoc, dbSettings)
156151
userTokenMappingsSyncDoc.onChange(userMappings => {
157152
coinmarketcapTokenIdMap = {
158153
...automatedTokenMappingsSyncDoc.doc,

src/v3/providers/coinmarketcap/defaultPluginIdMapping.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { StringNullMap } from '../../types'
22

33
export const coinmarketcapMainnetCurrencyMapping: StringNullMap = {
4+
abstract: '1027',
45
algorand: '4030',
56
arbitrum: '1027',
67
avalanche: '5805',
@@ -13,6 +14,7 @@ export const coinmarketcapMainnetCurrencyMapping: StringNullMap = {
1314
bitcoingold: '2083',
1415
bitcoinsv: '3602',
1516
bobevm: '1027',
17+
botanix: '1',
1618
cardano: '2010',
1719
celo: '5567',
1820
coreum: '16399',
@@ -68,6 +70,7 @@ export const coinmarketcapMainnetCurrencyMapping: StringNullMap = {
6870
}
6971

7072
export const coinmarketcapPlatformIdMapping: StringNullMap = {
73+
abstract: '247',
7174
algorand: '17',
7275
arbitrum: '51',
7376
avalanche: '28',
@@ -80,6 +83,7 @@ export const coinmarketcapPlatformIdMapping: StringNullMap = {
8083
bitcoingold: null,
8184
bitcoinsv: null,
8285
bobevm: null,
86+
botanix: null,
8387
cardano: '29',
8488
celo: '35',
8589
coreum: null,

0 commit comments

Comments
 (0)