Skip to content

fix: raise default transaction expiry to 120 seconds - #9

Closed
Primata wants to merge 1 commit into
mainfrom
fix/default-txn-expiry-120s
Closed

fix: raise default transaction expiry to 120 seconds#9
Primata wants to merge 1 commit into
mainfrom
fix/default-txn-expiry-120s

Conversation

@Primata

@Primata Primata commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

DEFAULT_TXN_EXP_SEC_FROM_NOW goes from 20 to 120 seconds.

Twenty seconds is narrower than a hardware-wallet signing round trip. The device chooser plus on-device confirmation routinely runs 15 to 60 seconds, and a browser extension adds an approval prompt in front of that. The node accepts the transaction into its mempool, then drops it once expiry passes, so the caller gets a hash for a transaction that never confirms and no error to explain it.

The constant is the only fallback behind MovementConfig.getDefaultTxnExpirySecFromNow(), and transactionBuilder.ts is its single consumer. Explicit options.expireTimestamp and transactionGenerationConfig.defaultTxnExpirySecFromNow both still take precedence, so nothing that already sets a window changes.

No test asserted the old value.

The 20-second default was narrower than a hardware-wallet signing round
trip. A device chooser plus an on-device confirmation routinely takes 15
to 60 seconds, and a browser extension adds an approval prompt on top. The
node accepted the transaction into its mempool and then dropped it once
expiry passed, so callers held a hash for a transaction that never
confirmed.

Callers wanting the old window can pass options.expireTimestamp or set
transactionGenerationConfig.defaultTxnExpirySecFromNow.
@Primata
Primata requested a review from ganymedio August 6, 2026 03:10
@ganymedio

Copy link
Copy Markdown
Collaborator

Closing this in favour of fixing the error instead.

The complaint is that a dropped transaction leaves you with a hash and nothing explaining it. That's a diagnosis problem, and it lives in waitForTransaction. A 404 is treated as retryable, so once the node drops the transaction the loop keeps polling a hash that no longer exists and ends at "timed out in pending state after 20 seconds". It never compares expiration_timestamp_secs against ledger time, so it cannot distinguish a slow transaction from one that is gone. The error points at timeoutSecs, which is the wrong lever.

The targeted fix is to capture the expiry from the pending response and, once polls start failing, throw an error saying the transaction expired and was dropped. That resolves the complaint for every consumer and changes behaviour for none.

Raising the default does change behaviour for everyone. Sequence-number ordering means a submitted transaction that never commits blocks later transactions from the same account until it expires, so 120 seconds turns a 20-second stall into a two-minute one. Flows that need a longer window can pass options.expireTimestamp or set transactionGenerationConfig.defaultTxnExpirySecFromNow, which is what Motion Wallet's hardware paths already do.

@ganymedio ganymedio closed this Aug 6, 2026
@ganymedio
ganymedio deleted the fix/default-txn-expiry-120s branch August 6, 2026 14:14
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