Add optional recipient field for intent outputs#41
Conversation
Allows users to specify a custom EVM output recipient address, independent of the connected wallet. Defaults to the connected wallet when left blank.
…asem/V2-116/add-recipient-field
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Closes: V2-116 |
6233eda
into
asem/V2-109/accommodate-intent.ts-solana-changes
* accommodate intent.ts standardise-order-classes API changes - add containerToIntent() helper in utils/intent.ts that wraps orderToIntent with automatic namespace detection (solana vs eip155) from OrderContainer - replace all orderToIntent(container) call sites with containerToIntent() - alias StandardOrderIntent as StandardEVMIntent in intentExecution.ts - add local idToToken() in intentList.ts (removed from @lifi/intent exports) * Update @lifi/intent to 0.0.4 and fix breaking API changes - Bump @lifi/intent from 0.0.3-alpha.1 to 0.0.4 - Add chainNamespace field to CoreToken in toCoreTokenContext - Fix containerToIntent: use 'in' narrowing for proper TypeScript overload resolution - Add StandardSolanaIntent guards in IntentFactory compact/escrow methods - Add StandardSolanaIntent guard in Solver.claim before finaliseIntent * fix: CI/CD tests to use secret variables * Merge pull request #41 from lifinance/feature/v2-116-add-recipient-field-on-lintentorg Add optional recipient field for intent outputs --------- Co-authored-by: Alexander <git@lindgren.xyz> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
🔍 QA Review — V2-116
🧠 What this ticket doesAdds an optional Recipient address field to the lintent.org intent issuance UI. The field accepts any EVM address and, when populated, threads
📋 Ticket SummaryAdd Recipient field on lintent.org Acceptance Criteria:
Testing Notes:
🏷️ PR Naming — ❌ Fail
✅ Ticket Coverage — MediumAC item is met — field is present and wired up correctly through the intent options (both compact and escrow paths). However, the test plan confirms E2E intent submission with a non-default recipient is unverified. The threading path (
|
| # | Severity | Type | Issue / File |
|---|---|---|---|
| 1 | 🟠 Medium | Test gap | No test verifying outputRecipient threads through to the submitted order's outputs — tests/unit/recipientField.test.ts |
| 2 | 🟢 Low | Code | resolveRecipient duplicates resolveExclusiveFor in IssueIntent.svelte |
🟠 [Medium] No test verifying outputRecipient threads through to order outputs — tests/unit/recipientField.test.ts
The existing recipientField.test.ts covers resolveRecipient() in isolation (address validation helper). The test plan's final item — "Submit an intent with a custom recipient and verify the order's output recipient reflects the input address" — is unchecked. No test verifies the full path: store.recipient set → resolveRecipient() produces address → intentOptions.outputRecipient populated → toCoreCreateIntentOptions() passes it through → the created order's output contains the custom recipient.
Add to tests/unit/recipientField.test.ts or tests/unit/intentFactory.test.ts (new):
toCoreCreateIntentOptions()withoutputRecipient: "0xABCD..."→CreateIntentOptions.outputRecipientequals"0xABCD..."toCoreCreateIntentOptions()withoutoutputRecipient→CreateIntentOptions.outputRecipientisundefined(default behaviour preserved)
🟢 [Low] resolveRecipient in IssueIntent.svelte duplicates resolveExclusiveFor
Both helpers are identical one-liners:
const resolveExclusiveFor = (value: string): `0x${string}` | undefined =>
isAddress(value, { strict: false }) ? value : undefined;
const resolveRecipient = (value: string): `0x${string}` | undefined =>
isAddress(value, { strict: false }) ? value : undefined;Extract to a shared utility (e.g. $lib/utils/address.ts → resolveAddress()) to avoid drift if validation logic changes.
🧪 Test Coverage
| Layer | Score | Files reviewed |
|---|---|---|
| Unit | Partial | tests/unit/recipientField.test.ts |
| Integration | N/A | UI library |
| E2e | None | Manual test plan — final item unchecked |
Unit gaps:
[Medium]Full intent-factory threading test foroutputRecipient(see issue Overhaul UI to have better logic flow and separation #1 above)
🔗 Downstream Impact
No blocking relations. Stacked on V2-109 (lintent PR #39) — V2-109 must land first.
QA Agent (lifi-qa-agent[bot]) — 2026-05-06
Linear: https://linear.app/lifi-linear/issue/V2-116/add-recipient-field-on-lintentorg
Summary
recipientfield to global store (state.svelte.ts)outputRecipientthroughintentFactory.tstotoCoreCreateIntentOptionsfor both compact and escrow pathsNotes
asem/V2-109/accommodate-intent.ts-solana-changesTest plan
recipientreflects the input addressExpected output
Screen.Recording.2026-04-07.at.1.15.16.PM.mov