Skip to content

Conversation

@peachbits
Copy link
Contributor

@peachbits peachbits commented Nov 24, 2025

CHANGELOG

Does this branch warrant an entry to the CHANGELOG?

  • Yes
  • No

Dependencies

none

Description

none

Note

Adds tokenId-based denomination conversion methods to wallets and extends swap data with payoutTokenId, including upgrade logic.

  • Wallet API:
    • Add convertDenominatedToNative(tokenId) and convertNativeToDenominated(tokenId) on EdgeCurrencyWallet.
    • makeSpend now cleans swapData and upgrades it when present.
  • Currency selectors:
    • Add getTokenMultiplier; mark getCurrencyMultiplier as deprecated in favor of it.
  • Types:
    • Add payoutTokenId to EdgeTxSwap and corresponding cleaner.
    • Extend EdgeCurrencyWallet interface with the new conversion methods.
  • Helpers:
    • Add upgradeSwapData(tx) to backfill swapData.payoutTokenId from savedAction when missing.
  • Tests/fixtures:
    • Update unit tests and fake transactions to include payoutTokenId and exercise new behavior.
  • Changelog:
    • Document new conversion utils and payoutTokenId addition.

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


// Address information:
payoutAddress: asString,
payoutCurrencyCode: asString,
payoutTokenId: asEdgeTokenId,
Copy link

Choose a reason for hiding this comment

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

Bug: Required field breaks loading old transaction files

The payoutTokenId field in asEdgeTxSwap is required but old transaction files saved to disk won't have this field. When loading existing transactions via transactionFile.load, the cleaner will fail validation. The field needs to be wrapped with asOptional to handle backward compatibility with existing data, since upgradeSwapData only runs during makeSpend and not when loading persisted transactions.

Fix in Cursor Fix in Web

Copy link
Contributor

Choose a reason for hiding this comment

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

This, exactly. We cannot add new mandatory fields to old data. If we truly wanted to go down this path, we would first have to add the tokenId as an optional field, and then incorporate a migration path for old data.

However, since this is a strict save-and-return workflow, I would propose not to add a migration path, but to simply add the payoutTokenId: asOptional(asEdgeTokenId), and a payoutTokenId?: EdgeTokenId to the types. That way we don't mess with old data, and the GUI is the one who has to deal with any backwards-compatibility issues. This backwards-compatibility is not terribly complex, since the GUI pretty much just shows this value as-is on the tx details scene.

// Address information:
payoutAddress: asString,
payoutCurrencyCode: asString,
payoutTokenId: asEdgeTokenId,
Copy link
Contributor

Choose a reason for hiding this comment

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

This, exactly. We cannot add new mandatory fields to old data. If we truly wanted to go down this path, we would first have to add the tokenId as an optional field, and then incorporate a migration path for old data.

However, since this is a strict save-and-return workflow, I would propose not to add a migration path, but to simply add the payoutTokenId: asOptional(asEdgeTokenId), and a payoutTokenId?: EdgeTokenId to the types. That way we don't mess with old data, and the GUI is the one who has to deal with any backwards-compatibility issues. This backwards-compatibility is not terribly complex, since the GUI pretty much just shows this value as-is on the tx details scene.

Comment on lines +34 to +58
export function getTokenMultiplier(
currencyInfo: EdgeCurrencyInfo,
allTokens: EdgeTokenMap,
tokenId: EdgeTokenId
): string {
if (tokenId == null) {
for (const denomination of currencyInfo.denominations) {
if (denomination.name === currencyInfo.currencyCode) {
return denomination.multiplier
}
}
} else {
const token: EdgeToken | undefined = allTokens[tokenId]
if (token != null) {
for (const denomination of token.denominations) {
if (denomination.name === token.currencyCode) {
return denomination.multiplier
}
}
}
}

return '1'
}

Copy link
Contributor

@swansontec swansontec Nov 25, 2025

Choose a reason for hiding this comment

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

The core should not provide utility functions like this, since everything goes over an expensive bridge. The denominationToNative and nativeToDenomination functions were historical accidents, and deprecation message says to "Use the information in EdgeCurrencyInfo / EdgeToken". We want to delete these guys, not replace them.

These types of utilities should move into edge-currency-accountbased and edge-react-gui in some sort of /utils file, since then they can be fast & synchronous.

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.

3 participants