Skip to content

Conversation

@youngkidwarrior
Copy link
Collaborator

feat(notifications): add retries, rate limiting, receipts & token hygiene

  • Add concurrency limiting (max 6 chunks in parallel) to Expo push sending
  • Implement retry with exponential backoff for rate-limited messages (MessageRateExceeded)
  • Collect ticket IDs from successful sends for receipt checking
  • Track tokens to deactivate when DeviceNotRegistered errors occur
  • Add checkExpoPushReceipts function for delayed receipt verification
  • Create receiptCheckWorkflow Temporal workflow for delayed receipt checking (~15 min delay)
  • Add checkPushReceiptsActivity and deactivateTokensActivity
  • Integrate automatic token deactivation in sendPushNotificationActivity
  • Mask tokens in logs to avoid exposing sensitive values
  • Update tests for new response fields (ticketIds, tokensToDeactivate)

Co-Authored-By: Warp agent@warp.dev

Harden transfer workflow notification payloads

  • Add MAX_NOTE_LENGTH (256), MAX_BODY_LENGTH (500), MAX_TITLE_LENGTH (100) constants
  • Add truncate() helper and sanitizeDataPayload() for push notification safety
  • Truncate note field in notification body to prevent MessageTooBig errors
  • Separate in-app notification data (full note preserved) from push data (truncated)
  • Pass workflowId to notification activities for idempotency tracking
  • Add workflowId to TransferNotificationParams type

Co-Authored-By: Warp agent@warp.dev

fix(notifications): align Expo receipts + TS shims\n\nCo-Authored-By: Warp agent@warp.dev

fix(notifications): stabilize push registration UX

  • De-dupe Expo token fetch + guard registerToken on permission\n- Scope notification prompt dismissal cooldown per user\n- Include hooks/navigation/types in app tsconfig to satisfy ESLint project parsing\n\nCo-Authored-By: Warp agent@warp.dev

fix(notifications): wire tap navigation + native config

  • Use useNotificationHandler in Expo root layout

  • Initialize Android channels / iOS categories on startup

  • Remove duplicate response listeners from useNotifications

  • Harden payload parsing + cancel delayed navigation on unmount

Co-Authored-By: Warp agent@warp.dev

fix(workflows): correct expo push concurrency limiter

Co-Authored-By: Warp agent@warp.dev

Copy link
Collaborator Author

youngkidwarrior commented Jan 10, 2026

@youngkidwarrior youngkidwarrior force-pushed the implement-expo-push-send-integ branch from bb60747 to ba1bca2 Compare January 10, 2026 04:31
@youngkidwarrior youngkidwarrior force-pushed the add-retries-rate-limiting-rece branch 2 times, most recently from 1d76b31 to 3f76a68 Compare January 10, 2026 04:36
@youngkidwarrior youngkidwarrior force-pushed the implement-expo-push-send-integ branch from ba1bca2 to 069cc21 Compare January 10, 2026 04:36
Victor Ginelli and others added 6 commits January 9, 2026 20:55
…iene

- Add concurrency limiting (max 6 chunks in parallel) to Expo push sending
- Implement retry with exponential backoff for rate-limited messages (MessageRateExceeded)
- Collect ticket IDs from successful sends for receipt checking
- Track tokens to deactivate when DeviceNotRegistered errors occur
- Add checkExpoPushReceipts function for delayed receipt verification
- Create receiptCheckWorkflow Temporal workflow for delayed receipt checking (~15 min delay)
- Add checkPushReceiptsActivity and deactivateTokensActivity
- Integrate automatic token deactivation in sendPushNotificationActivity
- Mask tokens in logs to avoid exposing sensitive values
- Update tests for new response fields (ticketIds, tokensToDeactivate)

Co-Authored-By: Warp <agent@warp.dev>
- Add MAX_NOTE_LENGTH (256), MAX_BODY_LENGTH (500), MAX_TITLE_LENGTH (100) constants
- Add truncate() helper and sanitizeDataPayload() for push notification safety
- Truncate note field in notification body to prevent MessageTooBig errors
- Separate in-app notification data (full note preserved) from push data (truncated)
- Pass workflowId to notification activities for idempotency tracking
- Add workflowId to TransferNotificationParams type

Co-Authored-By: Warp <agent@warp.dev>
- De-dupe Expo token fetch + guard registerToken on permission\n- Scope notification prompt dismissal cooldown per user\n- Include hooks/navigation/types in app tsconfig to satisfy ESLint project parsing\n\nCo-Authored-By: Warp <agent@warp.dev>
- Use useNotificationHandler in Expo root layout

- Initialize Android channels / iOS categories on startup

- Remove duplicate response listeners from useNotifications

- Harden payload parsing + cancel delayed navigation on unmount

Co-Authored-By: Warp <agent@warp.dev>
Co-Authored-By: Warp <agent@warp.dev>
@youngkidwarrior youngkidwarrior force-pushed the implement-expo-push-send-integ branch from 069cc21 to 8b2f1a8 Compare January 10, 2026 04:58
@youngkidwarrior youngkidwarrior force-pushed the add-retries-rate-limiting-rece branch from 3f76a68 to 102202b Compare January 10, 2026 04:58
@github-actions
Copy link

@github-actions
Copy link

Playwright Report

Artifacts: View all artifacts | JSON Report: json-report--attempt-1 | HTML Report: html-report--attempt-1

Summary

Passed Skipped Failed Flaky Duration Pass Rate
56 2 32 1 942.04s 62.9%

Suites

account-sendtag-add.onboarded.spec.ts (5/5 passed)

can visit add sendtags page

  • chromium: ✅ passed

can add a pending tag

  • chromium: ✅ passed

cannot add an invalid tag name

  • chromium: ✅ passed

cannot add more than 5 tags

  • chromium: ✅ passed

cannot confirm a tag without paying

  • chromium: ✅ passed
account-sendtag-checkout.onboarded.spec.ts (0/3 passed)

can confirm a tag

  • chromium: 🔄 flaky

can refer a tag

  • chromium: ❌ failed
    Error: �[31mTimed out 5000ms waiting for �[39m�[2mexpect(�[22m�[31mlocator�[39m�[2m).�[22mtoHaveValue�[2m(�[22m�[32mexpected�[39m�[2m)�[22m
    

can refer multiple tags in separate transactions

  • chromium: ❌ failed
    Error: �[31mTimed out 5000ms waiting for �[39m�[2mexpect(�[22m�[31mlocator�[39m�[2m).�[22mtoHaveValue�[2m(�[22m�[32mexpected�[39m�[2m)�[22m
    
account-settings-backup.onboarded.spec.ts (2/2 passed)

can backup account

  • chromium: ✅ passed

can remove a signer

  • chromium: ✅ passed
account.logged-in.spec.ts (2/2 passed)

can visit account page

  • chromium: ✅ passed

can update profile

  • chromium: ✅ passed
activity.onboarded.spec.ts (0/1 passed)

can visit activity page and see correct activity feed

  • chromium: ❌ failed
    Error: �[31mTimed out 5000ms waiting for �[39m�[2mexpect(�[22m�[31mlocator�[39m�[2m).�[22mtoContainText�[2m(�[22m�[32mexpected�[39m�[2m)�[22m
    
contacts.onboarded.spec.ts (0/0 passed)
earn.onboarded.spec.ts (0/0 passed)
home.onboarded.spec.ts (1/1 passed)

can visit token detail page

  • chromium: ✅ passed
leaderboard.logged-in.spec.ts (0/0 passed)

can visit leaderboard page

  • chromium: ⏭️ skipped
onboarding.logged-in.spec.ts (1/1 passed)

can visit onboarding page

  • chromium: ✅ passed
profile-external-address.anon.spec.ts (0/0 passed)
profile-external-address.onboarded.spec.ts (0/0 passed)
profile.anon.spec.ts (1/2 passed)

anon user can visit public profile

  • chromium: ❌ failed
    Error: �[31mTimed out 5000ms waiting for �[39m�[2mexpect(�[22m�[31mlocator�[39m�[2m).�[22mtoBeVisible�[2m()�[22m
    

anon user cannot visit private profile

  • chromium: ✅ passed
profile.logged-in.spec.ts (0/1 passed)

logged in user needs onboarding before visiting profile

  • chromium: ❌ failed
    Error: expect.toBeVisible: Error: strict mode violation: getByText('Yvonne Marquardt') resolved to 2 elements:
    
profile.onboarded.spec.ts (4/4 passed)

can visit other user profile and send by tag

  • chromium: ✅ passed

can visit my own profile

  • chromium: ✅ passed

can visit private profile

  • chromium: ✅ passed

can view activities between another profile

  • chromium: ✅ passed
send-token-upgrade.onboarded.spec.ts (0/1 passed)

can upgrade their Send Token V0 to Send Token V1

  • chromium: ❌ failed
    Error: �[2mexpect(�[22m�[31mreceived�[39m�[2m).�[22mtoEqual�[2m(�[22m�[32mexpected�[39m�[2m) // deep equality�[22m
    
send.onboarded.spec.ts (0/13 passed)

can send USDC starting from profile page

  • chromium: ❌ failed
    Error: Send button still visible
    

can send USDC using tag starting from home page

  • chromium: ❌ failed
    Error: �[31mTimed out 10000ms waiting for �[39m�[2mexpect(�[22m�[31mlocator�[39m�[2m).�[22mtoBeVisible�[2m()�[22m
    

can send USDC using sendid starting from home page

  • chromium: ❌ failed
    Error: �[31mTimed out 10000ms waiting for �[39m�[2mexpect(�[22m�[31mlocator�[39m�[2m).�[22mtoBeVisible�[2m()�[22m
    

can send USDC using address starting from home page

  • chromium: ❌ failed
    Error: expect.toBeVisible: Error: strict mode violation: getByText('0x11B...aF35') resolved to 2 elements:
    

can send SEND starting from profile page

  • chromium: ❌ failed
    Error: �[31mTimed out 5000ms waiting for �[39m�[2mexpect(�[22m�[31mlocator�[39m�[2m).�[22mtoBeVisible�[2m()�[22m
    

can send SEND using tag starting from home page

  • chromium: ❌ failed
    Error: �[31mTimed out 10000ms waiting for �[39m�[2mexpect(�[22m�[31mlocator�[39m�[2m).�[22mtoBeVisible�[2m()�[22m
    

can send SEND using sendid starting from home page

  • chromium: ❌ failed
    Error: �[31mTimed out 10000ms waiting for �[39m�[2mexpect(�[22m�[31mlocator�[39m�[2m).�[22mtoBeVisible�[2m()�[22m
    

can send SEND using address starting from home page

  • chromium: ❌ failed
    Error: expect.toBeVisible: Error: strict mode violation: getByText('0x0B1...E8a2') resolved to 2 elements:
    

can send ETH starting from profile page

  • chromium: ❌ failed
    Error: �[31mTimed out 5000ms waiting for �[39m�[2mexpect(�[22m�[31mlocator�[39m�[2m).�[22mtoBeVisible�[2m()�[22m
    

can send ETH using tag starting from home page

  • chromium: ❌ failed
    Error: �[31mTimed out 10000ms waiting for �[39m�[2mexpect(�[22m�[31mlocator�[39m�[2m).�[22mtoBeVisible�[2m()�[22m
    

can send ETH using sendid starting from home page

  • chromium: ❌ failed
    Error: �[31mTimed out 10000ms waiting for �[39m�[2mexpect(�[22m�[31mlocator�[39m�[2m).�[22mtoBeVisible�[2m()�[22m
    

can send ETH using address starting from home page

  • chromium: ❌ failed
    Error: expect.toBeVisible: Error: strict mode violation: getByText('0x56C...FA95') resolved to 2 elements:
    

cannot send below minimum amount for SEND token

  • chromium: ❌ failed
    Error: �[31mTimed out 10000ms waiting for �[39m�[2mexpect(�[22m�[31mlocator�[39m�[2m).�[22mtoBeVisible�[2m()�[22m
    
sendtag-happy-path.onboarded.spec.ts (0/1 passed)

sendtag complete happy path - create, confirm, and change main tag

  • chromium: ❌ failed
    Error: �[31mTimed out 5000ms waiting for �[39m�[2mexpect(�[22m�[31mlocator�[39m�[2m).�[22mtoBeVisible�[2m()�[22m
    

sendtag main tag succession - auto-assigns new main when current is deleted

  • chromium: ⏭️ skipped
sign-in.anon.spec.ts (3/3 passed)

redirect on sign-in

  • chromium: ✅ passed

redirect to send page on sign-in with recipient params

  • chromium: ✅ passed

old user can login using phone number

  • chromium: ✅ passed
sign-up.anon.spec.ts (2/2 passed)

can sign up

  • chromium: ✅ passed

country code is selected based on geoip

  • chromium: ✅ passed
swap.onboarded.spec.ts (2/5 passed)

can swap USDC for SEND

  • chromium: ❌ failed
    Error: Timeout 3000ms exceeded while waiting on the predicate
    

can swap USDC for ETH

  • chromium: ❌ failed
    Error: Timeout 3000ms exceeded while waiting on the predicate
    

can refresh swap form and preserve filled data

  • chromium: ❌ failed
    Error: Timeout 3000ms exceeded while waiting on the predicate
    

can't access form page without accepting risk dialog

  • chromium: ✅ passed

can't access summary page without filling swap form

  • chromium: ✅ passed

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