Skip to content

Conversation

@yushih
Copy link
Collaborator

@yushih yushih commented Dec 11, 2025

Note

Introduces a per-wallet Single Address Mode with a settings toggle, persistent local storage, and a new receive page that displays a single address with QR and copy actions; updates routing and context accordingly.

  • Receive Address Feature
    • Add per-wallet Single Address Mode toggle UI in WalletSettingsPage via EnableSingleAddressSettings.
    • New single-address receive view SingleAddressReceivePage and UI component components/wallet/receive/SingleAddress (QR, explorer link, copy).
    • Wrap wallets receive route with ReceiveContextProvider and conditionally route in containers/wallet/Receive to single-address page when enabled.
  • State & Persistence
    • Persist mode per wallet in local storage (api/localStorage: SINGLE_ADDRESS_MODE, getters/setters, SingleAddressMode type).
    • Load/save mode in WalletStore (singleAddressMode observable, isSelectedWalletSingleAddress getter, updater action).
  • I18n
    • Add strings/IDs for Single Address Mode settings and receive instructions in en-US.json and useStrings hook.
  • Scaffolding
    • Introduce ReceiveContextProvider (selected wallet in context) and placeholder use-cases (SingleAddressMode.tsx, MultiAddressMode.tsx).

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

const firstAddress = stores.wallets.selectedOrFail.allAddresses.utxoAddresses.find(
a => a.address.Type === CoreAddressTypes.CARDANO_BASE
);
const walletAddress = addressHexToBech32(firstAddress.address.Hash);
Copy link

Choose a reason for hiding this comment

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

Bug: Potential null access on address lookup result

The find() call for CARDANO_BASE address returns undefined if no matching address exists, but the result is used without a null check on line 13 (firstAddress.address.Hash) and line 25 (firstAddress.IsUsed). This can cause a runtime crash if a wallet somehow has no base addresses.

Fix in Cursor Fix in Web

});

export const useReceive = () =>
React.useContext(ReceiveContext) ?? console.log('useReceive: needs to be wrapped in a Receive ContextProvider');
Copy link

Choose a reason for hiding this comment

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

Bug: Hook returns undefined instead of throwing error

The useReceive hook uses the nullish coalescing operator with console.log() as the fallback. Since console.log returns undefined, when the context is not available, the hook returns undefined instead of throwing an error or providing a useful fallback. This can cause silent failures and confusing runtime errors for consumers who expect a valid context object.

Fix in Cursor Fix in Web

+onCopyAddressTooltip: string => void,
|};

export default class SingleAddress extends Component<Props> {
Copy link
Contributor

Choose a reason for hiding this comment

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

@yushih This single Address mode page should be added in new UI feature folder if I'm not mistaken and not in the old UI as its new

export default class SingleAddress extends Component<Props> {
static contextType: any = IntlContext;

render(): Node {
Copy link
Contributor

Choose a reason for hiding this comment

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

And refactored to a functional component as well in the new UI

import { addressHexToBech32 } from '../../api/ada/lib/cardanoCrypto/utils';
import { CoreAddressTypes } from '../../api/ada/lib/storage/database/primitives/enums';

export default class SingleAddressReceivePage extends Component<StoresProps> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here - the new page should be added in the new UI - pages for wallet - receive, if we don't have it we should create a new page for this and refactored to a functional component

async updateSelectedWalletSingleAddressMode(mode: boolean): Promise<void> {
runInAction(() => {
this.singleAddressMode[String(this.selectedOrFail.publicDeriverId)] = mode;
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we can use the Receive Context Provider to add this logic as we will gradually try to reduce the use of the mobX stores in the future as much as we can - or we can create a hook for this in receive feature (new UI)

@Nebyt Nebyt self-requested a review December 11, 2025 09:56
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.

4 participants