Conversation
9b55194 to
f9c86ae
Compare
f9c86ae to
1932ac3
Compare
| "start.cache": "node -r sucrase/register src/indexCache.ts", | ||
| "start.rates": "node -r sucrase/register src/indexRates.ts", | ||
| "start.api": "node -r sucrase/register src/indexApi.ts", | ||
| "start.destroyPartition": "node -r sucrase/register src/bin/destroyPartition.ts", |
There was a problem hiding this comment.
Optional
I'd argue to keep the colon over the dot as a separator just because colon has become the de facto standard. Not worth being different from the rest of codebases here.
There was a problem hiding this comment.
But they are such a pain to type.
| datelog(e) | ||
| process.exit(1) | ||
| } | ||
| process.exit(0) |
There was a problem hiding this comment.
The reason why this was hanging is because of we don't cleanup the setTimeout in promiseTimeout util. This should be fixed as a separate commit.
Add revolut
Have all plugins just set to undefined for now
1932ac3 to
6de5280
Compare
| if (paymentMethod == null) { | ||
| throw new Error(`Unknown payment method: ${tx.paymentMethod} for ${tx.id}`) | ||
| } | ||
| return paymentMethod |
There was a problem hiding this comment.
Moonpay mobile_wallet case now throws instead of returning null
High Severity
The refactored getFiatPaymentType function has a behavioral regression for the mobile_wallet payment method. When cardType is not 'apple_pay' or 'google_pay' (e.g., it's 'card' or missing), paymentMethod is set to null. The check on line 309 then throws an error for this case. The original implementation would return null without throwing, allowing these transactions to process with a null payment type.
There was a problem hiding this comment.
we want it to throw so the plugin fails, and we properly edit the code to add the new types.
6de5280 to
579527a
Compare
d08e16a to
579527a
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Autofix Details
Bugbot Autofix prepared fixes for both issues found in the latest run.
- ✅ Fixed: V3 rate failures cause infinite transaction reprocessing loop
updateTxValuesV3now marks transactions as failed by setting_idto undefined on invalid assets, V3 fetch/parse errors, and when no payout or USD update was applied.
- ✅ Fixed: Lifi chain plugin ID lookup ignores token fallback
- LiFi chain plugin lookups now use the existing chain-code fallback values derived from gas token or token fields, so missing gas tokens no longer break plugin-id resolution.
Or push these changes by commenting:
@cursor push 0986684dec
Preview (0986684dec)
diff --git a/src/partners/lifi.ts b/src/partners/lifi.ts
--- a/src/partners/lifi.ts
+++ b/src/partners/lifi.ts
@@ -232,14 +232,10 @@
// Try using the gas token code first, then chain id if we have one.
const depositChainPluginId =
REVERSE_EVM_CHAIN_IDS[depositEvmChainId ?? 0] ??
- MAINNET_CODE_TRANSCRIPTION[
- tx.sending.gasToken?.coinKey ?? tx.sending.gasToken?.symbol ?? ''
- ]
+ MAINNET_CODE_TRANSCRIPTION[depositChainCode ?? '']
const payoutChainPluginId =
REVERSE_EVM_CHAIN_IDS[payoutEvmChainId ?? 0] ??
- MAINNET_CODE_TRANSCRIPTION[
- tx.receiving.gasToken?.coinKey ?? tx.receiving.gasToken?.symbol ?? ''
- ]
+ MAINNET_CODE_TRANSCRIPTION[payoutChainCode ?? '']
if (depositChainPluginId == null || payoutChainPluginId == null) {
throw new Error('Missing chain plugin id')
diff --git a/src/ratesEngine.ts b/src/ratesEngine.ts
--- a/src/ratesEngine.ts
+++ b/src/ratesEngine.ts
@@ -111,6 +111,11 @@
}
async function updateTxValuesV3(transaction: DbTx): Promise<void> {
+ let updated = false
+ const fail = (): void => {
+ transaction._id = undefined
+ }
+
const {
isoDate,
depositCurrency,
@@ -154,6 +159,7 @@
console.error(
`Deposit asset is not a crypto asset or fiat currency ${depositCurrency} ${depositChainPluginId} ${depositTokenId}`
)
+ fail()
return
}
@@ -179,18 +185,26 @@
console.error(
`Payout asset is not a crypto asset or fiat currency ${payoutCurrency} ${payoutChainPluginId} ${payoutTokenId}`
)
+ fail()
return
}
- const ratesResponse = await fetch('https://rates3.edge.app/v3/rates', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json'
- },
- body: JSON.stringify(ratesRequest)
- })
- const ratesResponseJson = await ratesResponse.json()
- const rates = asRatesV3Params(ratesResponseJson)
+ let rates: RatesV3Params
+ try {
+ const ratesResponse = await fetch('https://rates3.edge.app/v3/rates', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify(ratesRequest)
+ })
+ const ratesResponseJson = await ratesResponse.json()
+ rates = asRatesV3Params(ratesResponseJson)
+ } catch (e) {
+ console.error('Error fetching V3 rates', e)
+ fail()
+ return
+ }
const depositRateObf = depositIsFiat
? rates.fiat.find(rate => rate.fiatCode === depositCurrency)
: rates.crypto.find(
@@ -225,6 +239,7 @@
}
if (depositRate != null && payoutRate != null) {
transaction.payoutAmount = (depositAmount * depositRate) / payoutRate
+ updated = true
}
}
@@ -233,10 +248,16 @@
if (transaction.usdValue == null || transaction.usdValue <= 0) {
if (depositRate != null) {
transaction.usdValue = depositAmount * depositRate
+ updated = true
} else if (payoutRate != null) {
transaction.usdValue = transaction.payoutAmount * payoutRate
+ updated = true
}
}
+
+ if (!updated) {
+ fail()
+ }
}
async function updateTxValues(579527a to
64afdaf
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Autofix Details
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Missing
hyperevmchain ID inEVM_CHAIN_IDSmapping- Added
hyperevm: 999toEVM_CHAIN_IDSso Li.Fi HyperEVM transfers now resolve and populate EVM chain IDs consistently.
- Added
Or push these changes by commenting:
@cursor push 05008ed393
Preview (05008ed393)
diff --git a/src/util/chainIds.ts b/src/util/chainIds.ts
--- a/src/util/chainIds.ts
+++ b/src/util/chainIds.ts
@@ -12,6 +12,7 @@
ethereumpow: 10001,
fantom: 250,
filecoinfevm: 314,
+ hyperevm: 999,
optimism: 10,
polygon: 137,
pulsechain: 369,Clear the timeout when the promise resolves or rejects to prevent the process from hanging due to uncancelled timers.
64afdaf to
2eb5444
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: V3 rate path lacks zero-rate guard before division
- Added positive-rate guards in the V3 payout and USD calculations so zero rates no longer produce Infinity or overwrite sentinel values.
Or push these changes by commenting:
@cursor push 94ec4a166c
Preview (94ec4a166c)
diff --git a/src/ratesEngine.ts b/src/ratesEngine.ts
--- a/src/ratesEngine.ts
+++ b/src/ratesEngine.ts
@@ -229,7 +229,12 @@
`No rate found for payout ${payoutCurrency} ${payoutChainPluginId} ${payoutTokenId}`
)
}
- if (depositRate != null && payoutRate != null) {
+ if (
+ depositRate != null &&
+ depositRate > 0 &&
+ payoutRate != null &&
+ payoutRate > 0
+ ) {
transaction.payoutAmount = (depositAmount * depositRate) / payoutRate
}
}
@@ -237,9 +242,9 @@
// Calculate the usdValue first trying to use the deposit amount. If that's not available
// then try to use the payout amount.
if (transaction.usdValue == null || transaction.usdValue <= 0) {
- if (depositRate != null) {
+ if (depositRate != null && depositRate > 0) {
transaction.usdValue = depositAmount * depositRate
- } else if (payoutRate != null) {
+ } else if (payoutRate != null && payoutRate > 0) {
transaction.usdValue = transaction.payoutAmount * payoutRate
}
}| } | ||
| if (depositRate != null && payoutRate != null) { | ||
| transaction.payoutAmount = (depositAmount * depositRate) / payoutRate | ||
| } |
There was a problem hiding this comment.
V3 rate path lacks zero-rate guard before division
Medium Severity
The V3 rates path in updateTxValuesV3 only checks payoutRate != null before dividing by it at line 233, unlike the V2 path which consistently guards with exchangeRate > 0. If the rates API returns a rate of 0 for a payout asset, (depositAmount * depositRate) / payoutRate produces Infinity, which would be persisted to the database. Similarly, a depositRate of 0 would write usdValue = 0, which differs from the initial -1 sentinel and could prevent the transaction from being re-queried for rate updates.
Additional Locations (1)
samholmes
left a comment
There was a problem hiding this comment.
I approve after the final cursor bot divide by zero fix is in



CHANGELOG
Does this branch warrant an entry to the CHANGELOG?
Dependencies
noneDescription
noneNote
Medium Risk
Medium risk because it changes the persisted
StandardTxschema across many partner adapters and rewrites rate-calculation logic to call a new externalrates3endpoint, which can affect valuation and backfills if mappings are wrong.Overview
Adds chain/token awareness to transactions.
StandardTxnow includesdeposit/payoutChainPluginId,deposit/payoutEvmChainId, anddeposit/payoutTokenId, and all partner processors are updated to populate these (mostly asundefined), with Li.Fi now deriving real values via new token-id and EVM chain-id helpers.Updates rate calculation behavior. The rates engine now uses the
rates3.edge.app/v3/ratesAPI when transactions include plugin/token identifiers (or fiat/crypto mixes), and updates the legacy rates lookup to hitrates2v2 withiso:fiat prefixes plus a same-currency fast-path.Misc fixes/ops. Adds a CouchDB mango index on
orderId, expands Moonpay payment method support (including Revolut) and Banxa ACH mapping, tightens DB init to requirecouchUris(with a default), improves timeout cleanup, and normalizes a few CLI/script behaviors (exit codes, npm script names).Written by Cursor Bugbot for commit 2eb5444. This will update automatically on new commits. Configure here.