Skip to content

Commit 3655bf4

Browse files
committed
Use ratex v3 if transactions has full pluginId/tokenId values
1 parent 1e2e025 commit 3655bf4

File tree

2 files changed

+174
-2
lines changed

2 files changed

+174
-2
lines changed

src/ratesEngine.ts

Lines changed: 151 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ import { config } from './config'
66
import {
77
asDbCurrencyCodeMappings,
88
asDbTx,
9+
asV3RatesParams,
910
CurrencyCodeMappings,
10-
DbTx
11+
DbTx,
12+
V3RatesParams
1113
} from './types'
1214
import { datelog, safeParseFloat, standardizeNames } from './util'
1315
import { isFiatCurrency } from './util/fiatCurrency'
@@ -108,10 +110,157 @@ export async function ratesEngine(): Promise<void> {
108110
}
109111
}
110112

111-
export async function updateTxValues(
113+
async function updateTxValuesV3(transaction: DbTx): Promise<void> {
114+
const {
115+
isoDate,
116+
depositCurrency,
117+
depositChainPluginId,
118+
depositTokenId,
119+
depositAmount,
120+
payoutChainPluginId,
121+
payoutTokenId,
122+
payoutCurrency,
123+
payoutAmount
124+
} = transaction
125+
126+
let depositIsFiat = false
127+
let payoutIsFiat = false
128+
const ratesRequest: V3RatesParams = {
129+
targetFiat: 'USD',
130+
crypto: [],
131+
fiat: []
132+
}
133+
if (depositChainPluginId != null && depositTokenId !== undefined) {
134+
ratesRequest.crypto.push({
135+
isoDate: new Date(isoDate),
136+
asset: {
137+
pluginId: depositChainPluginId,
138+
tokenId: depositTokenId
139+
},
140+
rate: undefined
141+
})
142+
} else if (isFiatCurrency(depositCurrency) && depositCurrency !== 'USD') {
143+
depositIsFiat = true
144+
ratesRequest.fiat.push({
145+
isoDate: new Date(isoDate),
146+
fiatCode: depositCurrency,
147+
rate: undefined
148+
})
149+
} else {
150+
console.error(
151+
`Deposit asset is not a crypto asset or fiat currency ${depositCurrency} ${depositChainPluginId} ${depositTokenId}`
152+
)
153+
return
154+
}
155+
156+
if (payoutChainPluginId != null && payoutTokenId !== undefined) {
157+
ratesRequest.crypto.push({
158+
isoDate: new Date(isoDate),
159+
asset: {
160+
pluginId: payoutChainPluginId,
161+
tokenId: payoutTokenId
162+
},
163+
rate: undefined
164+
})
165+
} else if (isFiatCurrency(payoutCurrency) && payoutCurrency !== 'USD') {
166+
payoutIsFiat = true
167+
ratesRequest.fiat.push({
168+
isoDate: new Date(isoDate),
169+
fiatCode: payoutCurrency,
170+
rate: undefined
171+
})
172+
} else {
173+
console.error(
174+
`Payout asset is not a crypto asset or fiat currency ${payoutCurrency} ${payoutChainPluginId} ${payoutTokenId}`
175+
)
176+
return
177+
}
178+
179+
const ratesResponse = await fetch('https://rates3.edge.app/v3/rates', {
180+
method: 'POST',
181+
headers: {
182+
'Content-Type': 'application/json'
183+
},
184+
body: JSON.stringify(ratesRequest)
185+
})
186+
const ratesResponseJson = await ratesResponse.json()
187+
const rates = asV3RatesParams(ratesResponseJson)
188+
const depositRateObf = depositIsFiat
189+
? rates.fiat.find(rate => rate.fiatCode === depositCurrency)
190+
: rates.crypto.find(
191+
rate =>
192+
rate.asset.pluginId === depositChainPluginId &&
193+
(rate.asset.tokenId ?? null) === depositTokenId
194+
)
195+
const payoutRateObf = payoutIsFiat
196+
? rates.fiat.find(rate => rate.fiatCode === payoutCurrency)
197+
: rates.crypto.find(
198+
rate =>
199+
rate.asset.pluginId === payoutChainPluginId &&
200+
(rate.asset.tokenId ?? null) === payoutTokenId
201+
)
202+
203+
const depositRate = depositRateObf?.rate
204+
const payoutRate = payoutRateObf?.rate
205+
206+
// Calculate and fill out payoutAmount if it is zero
207+
if (payoutAmount === 0) {
208+
if (depositRate == null) {
209+
console.error(
210+
`No rate found for deposit ${depositCurrency} ${depositChainPluginId} ${depositTokenId}`
211+
)
212+
}
213+
214+
if (payoutRate == null) {
215+
console.error(
216+
`No rate found for payout ${payoutCurrency} ${payoutChainPluginId} ${payoutTokenId}`
217+
)
218+
}
219+
if (depositRate != null && payoutRate != null) {
220+
transaction.payoutAmount = (depositAmount * depositRate) / payoutRate
221+
}
222+
}
223+
224+
// Calculate the usdValue first trying to use the deposit amount. If that's not available
225+
// then try to use the payout amount.
226+
if (transaction.usdValue == null || transaction.usdValue <= 0) {
227+
if (depositRate != null) {
228+
transaction.usdValue = depositAmount * depositRate
229+
} else if (payoutRate != null) {
230+
transaction.usdValue = transaction.payoutAmount * payoutRate
231+
}
232+
}
233+
}
234+
235+
async function updateTxValues(
112236
transaction: DbTx,
113237
mappings: CurrencyCodeMappings
114238
): Promise<void> {
239+
if (
240+
transaction.depositChainPluginId != null &&
241+
transaction.depositTokenId !== undefined &&
242+
transaction.payoutChainPluginId != null &&
243+
transaction.payoutTokenId !== undefined
244+
) {
245+
return await updateTxValuesV3(transaction)
246+
}
247+
248+
if (
249+
transaction.depositChainPluginId != null &&
250+
transaction.depositTokenId !== undefined &&
251+
isFiatCurrency(transaction.payoutCurrency)
252+
) {
253+
return await updateTxValuesV3(transaction)
254+
}
255+
256+
if (
257+
isFiatCurrency(transaction.depositCurrency) &&
258+
transaction.payoutChainPluginId != null &&
259+
transaction.payoutTokenId !== undefined
260+
) {
261+
return await updateTxValuesV3(transaction)
262+
}
263+
115264
let success = false
116265
const date: string = transaction.isoDate
117266
if (mappings[transaction.depositCurrency] != null) {

src/types.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
asArray,
3+
asDate,
34
asEither,
45
asMap,
56
asNull,
@@ -210,6 +211,28 @@ export const asAnalyticsResult = asObject({
210211
end: asNumber
211212
})
212213

214+
// v3/rates response cleaner (matches GUI's shape)
215+
const asV3CryptoAsset = asObject({
216+
pluginId: asString,
217+
tokenId: asOptional(asEither(asString, asNull))
218+
})
219+
const asV3CryptoRate = asObject({
220+
isoDate: asOptional(asDate),
221+
asset: asV3CryptoAsset,
222+
rate: asOptional(asNumber)
223+
})
224+
const asV3FiatRate = asObject({
225+
isoDate: asOptional(asDate),
226+
fiatCode: asString,
227+
rate: asOptional(asNumber)
228+
})
229+
export const asV3RatesParams = asObject({
230+
targetFiat: asString,
231+
crypto: asArray(asV3CryptoRate),
232+
fiat: asArray(asV3FiatRate)
233+
})
234+
235+
export type V3RatesParams = ReturnType<typeof asV3RatesParams>
213236
export type Bucket = ReturnType<typeof asBucket>
214237
export type AnalyticsResult = ReturnType<typeof asAnalyticsResult>
215238

0 commit comments

Comments
 (0)