Skip to content

fix: use UTF-8 byte length for Stellar MEMO_TEXT validation in RemittanceForm - #1587

Open
waterWang wants to merge 2 commits into
LabsCrypt:mainfrom
waterWang:fix/memo-utf8-bytes-validation
Open

fix: use UTF-8 byte length for Stellar MEMO_TEXT validation in RemittanceForm#1587
waterWang wants to merge 2 commits into
LabsCrypt:mainfrom
waterWang:fix/memo-utf8-bytes-validation

Conversation

@waterWang

Copy link
Copy Markdown

Fix Stellar MEMO_TEXT validation: use UTF-8 byte length instead of character count

Closes #1074

Problem

The memo field validated by character count (memo.length > 28), but Stellar MEMO_TEXT caps at 28 bytes, not 28 characters. Multibyte UTF-8 memos (accented characters, emoji, CJK) could pass the 28-character check and still exceed 28 bytes, failing at transaction submission time.

Changes

  • validateForm: Replaced memo.length > 28 with new TextEncoder().encode(memo).length > 28 (UTF-8 byte-length check)
  • Textarea: Removed maxLength={28} attribute (character-level cap) in favor of byte-aware validation at submit time
  • Counter: Updated from {memo.length}/28 characters to {new TextEncoder().encode(memo).length}/28 bytes
  • Error message: Updated to "Memo must be 28 bytes or less (Stellar MEMO_TEXT limit)"
  • Tests: Added multibyte rejection test (15×ñ = 30 bytes > 28); updated existing tests for new error message and byte counter

Acceptance Criteria

  • Memo validation uses UTF-8 byte length (new TextEncoder().encode(memo).length <= 28)
  • The textarea counter reflects bytes, not characters
  • A memo that's under 28 characters but over 28 bytes gets rejected with a clear message
  • Pure-ASCII memos up to 28 bytes still pass
  • Unit test covers the multibyte-over-28-bytes rejection and byte counter display

Files modified

  • frontend/src/app/components/remittance/RemittanceForm.tsx — validation, textarea, counter
  • frontend/src/app/components/remittance/RemittanceForm.test.tsx — updated + new test

…anceForm

Replace character-count validation (`memo.length > 28`) with UTF-8 byte-length
validation (`new TextEncoder().encode(memo).length > 28`) to correctly enforce
Stellar's 28-byte MEMO_TEXT limit. Multibyte characters (accents, emoji, CJK)
that pass the 28-character check but exceed 28 bytes now show a clear error
message at validation time instead of failing at transaction submission.

Changes:
- `validateForm` now checks `TextEncoder().encode(memo).length` instead of `memo.length`
- Removed `maxLength={28}` attribute from textarea in favor of byte-aware validation
- Character counter updated to show byte count ("{n}/28 bytes")
- Added test for multibyte rejection (15 × ñ = 30 bytes)
- Updated existing test assertions for new error message and byte counter

Closes LabsCrypt#1074
jsdom does not expose the TextEncoder global on all Node versions,
which breaks unit tests in RemittanceForm that now use
TextEncoder().encode() for UTF-8 byte-length memo validation.
Polyfill from node:util when the global is absent.
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.

[Frontend] Remittance memo is validated by character count instead of Stellar 28-byte limit

1 participant