Skip to content

Paul/v3 rates and fixes#205

Open
paullinator wants to merge 17 commits intomasterfrom
paul/v3RatesAndFixes
Open

Paul/v3 rates and fixes#205
paullinator wants to merge 17 commits intomasterfrom
paul/v3RatesAndFixes

Conversation

@paullinator
Copy link
Member

@paullinator paullinator commented Nov 20, 2025

CHANGELOG

Does this branch warrant an entry to the CHANGELOG?

  • Yes
  • No

Dependencies

none

Description

none

Note

Introduces chain/token metadata and rate-calculation upgrades, plus minor stability/config changes.

  • Types/partners: Extend StandardTx with deposit/payoutChainPluginId, deposit/payoutEvmChainId, and deposit/payoutTokenId. Update most partners to include these fields; lifi now fully populates them and sets payoutTxid and usdValue correctly.
  • Rates: Add V3 rates flow in ratesEngine using pluginId/tokenId via https://rates3.edge.app/v3/rates; fallback path uses the v2 rates API with improved fiat handling and same-currency short-circuit.
  • DB/setup: Add Mango index for orderId; initDbs now requires couchUris and always uses pooled Couch; default couchUris provided in config.
  • Payments: moonpay adds revolut payment type and consolidates mapping; banxa adds ACH mapping.
  • Tooling/UI: Rename npm scripts to start.*; destroyPartition exits with codes on success/failure; demo tightens API key check.

See CHANGELOG.md for details.

Written by Cursor Bugbot for commit 579527a. This will update automatically on new commits. Configure here.

Comment on lines +23 to +26
"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",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But they are such a pain to type.

datelog(e)
process.exit(1)
}
process.exit(0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

try {
tx = asTransfer(rawTx)
} catch (e) {
datelog(e)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

createScopedLog already logs the date ISO string. So this try-catch is unnecessary.

}
return standardTx
} catch (e) {
datelog(e)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we catching just to log and rethrow when createScopedLog is already doing this?

default: {
// No token support:
// these chains don't support tokens
throw new Error('Tokens are not supported for this chain')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Plugin ID Token Support Details
eos Has customTokenTemplate - supports custom tokens via contract address
telos Has customTokenTemplate - supports custom tokens via contract address
wax Has customTokenTemplate - supports custom tokens via contract address
filecoin Has customTokenTemplate - supports custom tokens via contract address
zano Has builtinTokens (TALLY, BTCx) and customTokenTemplate for Asset IDs

These are tokens that Edge may have token support for that will cause this error to through if a transaction is detected with a token. Is that possible? Does the exchange plugins not support token swaps for these chains?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Exchange plugins do not support token swaps for the above chains. We want these to error so that we notice a plugin stops synchronizing, and then we could explicitly add support.

Comment on lines 240 to 259
transaction.depositChainPluginId != null &&
transaction.depositTokenId !== undefined &&
transaction.payoutChainPluginId != null &&
transaction.payoutTokenId !== undefined
) {
return await updateTxValuesV3(transaction)
}

if (
transaction.depositChainPluginId != null &&
transaction.depositTokenId !== undefined &&
isFiatCurrency(transaction.payoutCurrency)
) {
return await updateTxValuesV3(transaction)
}

if (
isFiatCurrency(transaction.depositCurrency) &&
transaction.payoutChainPluginId != null &&
transaction.payoutTokenId !== undefined
) {
return await updateTxValuesV3(transaction)
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not one if condition that is a disjunction of the three if conditions?

await setupDatabase(config.couchDbFullpath, setup, options)
)
)
if (config.couchUris == null) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're going to require couchUris, then make sure there is some default structure in the config? Otherwise, the commit prehook fails because the tests fail.

src/types.ts Outdated
})

// v3/rates response cleaner (matches GUI's shape)
const asV3CryptoAsset = asObject({
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would like these cleaners to be called asRatesV3*.

if (paymentMethod == null) {
throw new Error(`Unknown payment method: ${tx.paymentMethod} for ${tx.id}`)
}
return paymentMethod
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Fix in Cursor Fix in Web

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we want it to throw so the plugin fails, and we properly edit the code to add the new types.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 4 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

body: JSON.stringify(ratesRequest)
})
const ratesResponseJson = await ratesResponse.json()
const rates = asRatesV3Params(ratesResponseJson)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing HTTP response validation in V3 rates fetch

Medium Severity

The new updateTxValuesV3 function fetches rates from the V3 API but doesn't check ratesResponse.ok before parsing the response. Unlike the existing V2 getExchangeRate function (lines 379-386) which properly checks for HTTP errors and logs rate limiting, the V3 function proceeds directly to ratesResponse.json() and asRatesV3Params(). When the API returns an error (4xx, 5xx), this produces unhelpful cleaner errors instead of the actual API error message, and rate limiting goes undetected.

Fix in Cursor Fix in Web

transfers: asArray(asUnknown)
})

type Transfer = ReturnType<typeof asTransfer>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused type definition never referenced

Low Severity

The type Transfer is defined as ReturnType<typeof asTransfer> but is never used anywhere in the file. This is dead code that clutters the codebase and may confuse future developers who expect it to be used.

Fix in Cursor Fix in Web

tx.sending.gasToken?.symbol ??
depositToken?.coinKey ??
depositToken?.symbol
const payoutChainCodeUnmappped =
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in variable name with extra letter

Low Severity

The variable payoutChainCodeUnmappped has three 'p's in "Unmapped" instead of two. This is inconsistent with the correctly spelled depositChainCodeUnmapped variable. While functional, this typo makes the code harder to read and search for.

Additional Locations (1)

Fix in Cursor Fix in Web

: payoutEvmChainId

const depositTokenType = tokenTypes[depositChainPluginId ?? '']
const payoutTokenType = tokenTypes[payoutChainPluginId ?? '']
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary null coalescing after null guard

Low Severity

Lines 252, 256, 259, and 260 use ?? '' null coalescing on depositChainPluginId and payoutChainPluginId, but these variables are guaranteed to be non-null at this point because lines 244-246 throw an error if either is null. The fallback values can never be reached, making the ?? '' patterns unnecessary.

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants