Skip to content

Retry Telegram photo mints on nonce race with a friendly notice#411

Merged
techeng322 merged 1 commit into
mainfrom
techengme/myc-5038-telegram-photo-mint-can-still-fail-with-aa25-invalid-account
Jul 19, 2026
Merged

Retry Telegram photo mints on nonce race with a friendly notice#411
techeng322 merged 1 commit into
mainfrom
techengme/myc-5038-telegram-photo-mint-can-still-fail-with-aa25-invalid-account

Conversation

@techeng322

@techeng322 techeng322 commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Telegram photo mints can occasionally fail with AA25 invalid account nonce when a concurrent UserOperation races the same smart wallet's nonce (the createMomentBatch path is already lock-protected, but other unprotected sendUserOperation call sites can still collide with it).
  • Adds isNonceRetryableError to detect AA25/nonce-related failures, and mintWithNonceRetry to wrap createMomentBatch: on a nonce error it posts a one-time friendly "network's busy" notice to the chat and retries up to 3 attempts total, 5s apart, before giving up.
  • createMomentsFromGroup.ts now goes through mintWithNonceRetry instead of calling createMomentBatch directly.

Test plan

  • pnpm vitest run for isNonceRetryableError, mintWithNonceRetry, createMomentsFromGroup — 16 tests pass
  • tsc --noEmit shows no new type errors from these files

Summary by CodeRabbit

  • New Features

    • Added automatic retries for moment minting when network nonce errors occur.
    • Displays a “network busy…Retrying now” notification before retrying.
    • Preserves immediate error handling for unrelated failures and reports errors after retry attempts are exhausted.
  • Tests

    • Added coverage for nonce error detection, retry behavior, notifications, and failure scenarios.

createMomentBatch is already serialized per smart wallet, but a
concurrent UserOperation from an unprotected call site can still
occasionally trigger AA25 invalid account nonce. Instead of failing
the mint outright, notify the user once and retry up to 3 attempts,
5s apart, before giving up.
@vercel

vercel Bot commented Jul 19, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
in-process-api Ready Ready Preview Jul 19, 2026 12:04am

Request Review

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e1bfa2a8-e53f-45f8-9806-89e5debe80ef

📥 Commits

Reviewing files that changed from the base of the PR and between 6a54894 and 852f468.

📒 Files selected for processing (5)
  • src/lib/coinbase/__tests__/isNonceRetryableError.test.ts
  • src/lib/coinbase/isNonceRetryableError.ts
  • src/lib/telegram/chat/moment/__tests__/mintWithNonceRetry.test.ts
  • src/lib/telegram/chat/moment/createMomentsFromGroup.ts
  • src/lib/telegram/chat/moment/mintWithNonceRetry.ts

📝 Walkthrough

Walkthrough

Adds nonce error classification and a bounded retry wrapper for Coinbase minting. Group moment creation now uses the wrapper, which posts one Telegram notification before delayed retries. New tests cover classification, success, retry, non-retryable, and exhausted-retry paths.

Changes

Nonce retry flow

Layer / File(s) Summary
Nonce error classification
src/lib/coinbase/isNonceRetryableError.ts, src/lib/coinbase/__tests__/isNonceRetryableError.test.ts
Classifies Error instances containing AA25 or “invalid account nonce” messages and tests matching and non-matching inputs.
Bounded mint retry
src/lib/telegram/chat/moment/mintWithNonceRetry.ts, src/lib/telegram/chat/moment/__tests__/mintWithNonceRetry.test.ts
Retries nonce-related batch creation failures with a five-second delay, posts one busy notification, enforces the attempt limit, and propagates terminal errors.
Group creation integration
src/lib/telegram/chat/moment/createMomentsFromGroup.ts
Replaces direct batch creation with mintWithNonceRetry, passing the Telegram thread and preserving batch result handling.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant createMomentsFromGroup
  participant mintWithNonceRetry
  participant createMomentBatch
  participant TelegramThread
  createMomentsFromGroup->>mintWithNonceRetry: Pass thread and batch input
  mintWithNonceRetry->>createMomentBatch: Create moment batch
  createMomentBatch-->>mintWithNonceRetry: Return nonce error
  mintWithNonceRetry->>TelegramThread: Post busy retry notification
  mintWithNonceRetry->>mintWithNonceRetry: Wait five seconds
  mintWithNonceRetry->>createMomentBatch: Retry batch creation
  createMomentBatch-->>mintWithNonceRetry: Return result or final error
  mintWithNonceRetry-->>createMomentsFromGroup: Return result or rethrow error
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: retrying Telegram photo mints on nonce races with a user-facing notice.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch techengme/myc-5038-telegram-photo-mint-can-still-fail-with-aa25-invalid-account

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

src/lib/coinbase/__tests__/isNonceRetryableError.test.ts

Oops! Something went wrong! :(

ESLint: 9.39.4

TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Object'
| property 'configs' -> object with constructor 'Object'
| property 'flat' -> object with constructor 'Object'
| ...
| property 'plugins' -> object with constructor 'Object'
--- property 'react' closes the circle
Referenced from: /.eslintrc.json
at JSON.stringify ()
at /node_modules/.pnpm/@eslint+eslintrc@3.3.5/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2255:45
at Array.map ()
at ConfigValidator.formatErrors (/node_modules/.pnpm/@eslint+eslintrc@3.3.5/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2246:23)
at ConfigValidator.validateConfigSchema (/node_modules/.pnpm/@eslint+eslintrc@3.3.5/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2277:84)
at ConfigArrayFactory._normalizeConfigData (/node_modules/.pnpm/@eslint+eslintrc@3.3.5/node_modules/@eslint/

... [truncated 446 characters] ...

c/dist/eslintrc.cjs:3261:25)
at ConfigArrayFactory._normalizeObjectConfigDataBody (/node_modules/.pnpm/@eslint+eslintrc@3.3.5/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3199:25)
(node:2) ESLintRCWarning: You are using an eslintrc configuration file, which is deprecated and support will be removed in v10.0.0. Please migrate to an eslint.config.js file. See https://eslint.org/docs/latest/use/configure/migration-guide for details. An eslintrc configuration file is used because you have the ESLINT_USE_FLAT_CONFIG environment variable set to false. If you want to use an eslint.config.js file, remove the environment variable. If you want to find the location of the eslintrc configuration file, use the --debug flag.
(Use node --trace-warnings ... to show where the warning was created)

src/lib/coinbase/isNonceRetryableError.ts

Oops! Something went wrong! :(

ESLint: 9.39.4

TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Object'
| property 'configs' -> object with constructor 'Object'
| property 'flat' -> object with constructor 'Object'
| ...
| property 'plugins' -> object with constructor 'Object'
--- property 'react' closes the circle
Referenced from: /.eslintrc.json
at JSON.stringify ()
at /node_modules/.pnpm/@eslint+eslintrc@3.3.5/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2255:45
at Array.map ()
at ConfigValidator.formatErrors (/node_modules/.pnpm/@eslint+eslintrc@3.3.5/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2246:23)
at ConfigValidator.validateConfigSchema (/node_modules/.pnpm/@eslint+eslintrc@3.3.5/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2277:84)
at ConfigArrayFactory._normalizeConfigData (/node_modules/.pnpm/@eslint+eslintrc@3.3.5/node_modules/@eslint/

... [truncated 446 characters] ...

c/dist/eslintrc.cjs:3261:25)
at ConfigArrayFactory._normalizeObjectConfigDataBody (/node_modules/.pnpm/@eslint+eslintrc@3.3.5/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3199:25)
(node:2) ESLintRCWarning: You are using an eslintrc configuration file, which is deprecated and support will be removed in v10.0.0. Please migrate to an eslint.config.js file. See https://eslint.org/docs/latest/use/configure/migration-guide for details. An eslintrc configuration file is used because you have the ESLINT_USE_FLAT_CONFIG environment variable set to false. If you want to use an eslint.config.js file, remove the environment variable. If you want to find the location of the eslintrc configuration file, use the --debug flag.
(Use node --trace-warnings ... to show where the warning was created)

src/lib/telegram/chat/moment/__tests__/mintWithNonceRetry.test.ts

Oops! Something went wrong! :(

ESLint: 9.39.4

TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Object'
| property 'configs' -> object with constructor 'Object'
| property 'flat' -> object with constructor 'Object'
| ...
| property 'plugins' -> object with constructor 'Object'
--- property 'react' closes the circle
Referenced from: /.eslintrc.json
at JSON.stringify ()
at /node_modules/.pnpm/@eslint+eslintrc@3.3.5/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2255:45
at Array.map ()
at ConfigValidator.formatErrors (/node_modules/.pnpm/@eslint+eslintrc@3.3.5/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2246:23)
at ConfigValidator.validateConfigSchema (/node_modules/.pnpm/@eslint+eslintrc@3.3.5/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2277:84)
at ConfigArrayFactory._normalizeConfigData (/node_modules/.pnpm/@eslint+eslintrc@3.3.5/node_modules/@eslint/

... [truncated 446 characters] ...

c/dist/eslintrc.cjs:3261:25)
at ConfigArrayFactory._normalizeObjectConfigDataBody (/node_modules/.pnpm/@eslint+eslintrc@3.3.5/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3199:25)
(node:2) ESLintRCWarning: You are using an eslintrc configuration file, which is deprecated and support will be removed in v10.0.0. Please migrate to an eslint.config.js file. See https://eslint.org/docs/latest/use/configure/migration-guide for details. An eslintrc configuration file is used because you have the ESLINT_USE_FLAT_CONFIG environment variable set to false. If you want to use an eslint.config.js file, remove the environment variable. If you want to find the location of the eslintrc configuration file, use the --debug flag.
(Use node --trace-warnings ... to show where the warning was created)

  • 2 others

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@techeng322
techeng322 merged commit a2f28cf into main Jul 19, 2026
3 checks 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.

1 participant