Skip to content

fix(#307): replace hardcoded expiration ledger with live getLatestLed…#311

Merged
zachyo merged 1 commit into
soropad:masterfrom
Danielodingz:fix/307-approve-form-expiration-ledger
Jun 30, 2026
Merged

fix(#307): replace hardcoded expiration ledger with live getLatestLed…#311
zachyo merged 1 commit into
soropad:masterfrom
Danielodingz:fix/307-approve-form-expiration-ledger

Conversation

@Danielodingz

Copy link
Copy Markdown
Contributor

Closes #307

fix(#307): ApproveForm — replace hardcoded expiration ledger with live ledger sequence

Problem

Both the simulate (handleCheck) and submit (onSubmit) paths in
ApproveForm.tsx computed the SEP-41 expiration_ledger using a
hardcoded base of 1_000_000:

// Before (broken)
const ledger = 1000000 + parseInt(formData.expirationDays || "365") * 10800;

This caused two compounding bugs:

  1. Stale base — Testnet and Mainnet ledger sequences are well above
    1,000,000. The computed ledger was already in the past, so Soroban
    rejected the allowance (or created one that expired immediately).
  2. Wrong rate10800 ledgers/day assumes ~8 s/ledger
    (86400 / 10800 = 8). Soroban closes ledgers at ~5 s, so the
    allowance window was off by ~60%.

The vesting flow in AdminPanel already handles this correctly
(getLatestLedger().sequence + days * 17280). ApproveForm was the
outlier.

Fix

frontend/components/forms/ApproveForm.tsx

  • Import fetchCurrentLedger from @/lib/stellar.
  • Add a single shared getExpirationLedger(days) helper that calls
    fetchCurrentLedger(networkConfig) and returns
    currentLedger + parseInt(days) * 17280.
  • Both handleCheck (simulate) and onSubmit (submit) now call the
    same helper — they cannot drift.
// After (correct)
const getExpirationLedger = async (days: string): Promise<number> => {
  const currentLedger = await fetchCurrentLedger(networkConfig);
  return currentLedger + parseInt(days || "365") * 17280;
};

frontend/components/AllowanceList.tsx (follow-on)

  • Add optional currentLedger?: number prop to AllowanceListProps.
  • Add ledgerToExpiryInfo(expirationLedger) helper that converts a
    ledger number to a human-readable expiry date and countdown string
    (e.g. Jun 30, 2026 · 364d 23h remaining / Expired) using
    5 s/ledger arithmetic.
  • Rendered below the existing raw ledger number when currentLedger
    is supplied (fully backwards-compatible — callers that don't pass the
    prop see no change).

Testing

  • Set "365 days" in the Approve form → preflight check and submit both
    compute `sequence + 6,

…testLedger + 17280 ledgers/day

- Import fetchCurrentLedger from @/lib/stellar into ApproveForm
- Add shared getExpirationLedger helper used by both simulate and submit paths
- Replace 1_000_000 + days * 10800 with currentLedger + days * 17280
- Add optional currentLedger prop to AllowanceList
- Add ledgerToExpiryInfo helper to render human date + countdown per allowance
@drips-wave

drips-wave Bot commented Jun 29, 2026

Copy link
Copy Markdown

@Danielodingz Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Danielodingz

Copy link
Copy Markdown
Contributor Author

Hello @zachyo please review PR and merge. Thank You

@Danielodingz

Copy link
Copy Markdown
Contributor Author

Hello @zachyo please review PR and merge. Thank you

@zachyo zachyo merged commit 2720e0c into soropad:master Jun 30, 2026
2 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.

ApproveForm: allowance expiration ledger is hardcoded and (almost always) already expired

2 participants