Skip to content

Update ERC-7730: Improve duration format - #1908

Open
melanciani wants to merge 5 commits into
ethereum:masterfrom
melanciani:melanciani/erc7730_duration_display_options
Open

melanciani wants to merge 5 commits into
ethereum:masterfrom
melanciani:melanciani/erc7730_duration_display_options

Conversation

@melanciani

Copy link
Copy Markdown
Contributor

Abstract

This change amends the ERC-7730 duration field format. A duration value (a number
of seconds) is rendered as <days>d<hh>h<mm>m<ss>s, where days is unbounded and
hh/mm/ss are zero-padded to two digits. This replaces the previous HH:MM:ss
rendering, whose unbounded hours field (e.g. 240:00:00 for ten days) is ambiguous and
easily misread on a clear-signing display.

Motivation

Durations in clear-signing are frequently authorization or validity windows (permit and
delegation expiries, operator authorizations). The prior HH:MM:ss format collapsed
multi-day windows into large hour counts (240:00:00), which users can misread — a
meaningful risk when the value governs how long access is granted. A fixed, days-inclusive
format makes the magnitude legible at a glance without adding optional styles or parameters
that would fragment wallet behavior.

Rationale

Alternatives considered:

  • Keep HH:MM:ss — rejected: ambiguous for multi-day durations (240:00:00).
  • ISO-8601 durations (P10D, PT2H17M30S) — the formal standard, but rejected: cryptic
    for end users on a hardware-wallet screen.
  • Opt-in style/base parameters — rejected: adds configuration and lets the same value
    render differently across wallets. A single imposed format is simpler and consistent.

The chosen Dd HHh MMm SSs form is days-inclusive, self-describing, and unambiguous, and keeps
duration parameter-free.

Backwards Compatibility

This is a breaking change to the rendered output of duration (previously HH:MM:ss), so it
affects renderers, not descriptor documents (no schema-structure change; documents that
validated before still validate). It is introduced in the v3.0.0 schema line — the current
mutable -next major draft — and does NOT alter the released v2 schema. Wallets and libraries
implementing ERC-7730 MUST update their duration renderer to the new format when adopting v3.

Test Cases

Field value (seconds) Rendered
0 0d00h00m00s
45 0d00h00m45s
3600 0d01h00m00s
8250 0d02h17m30s
360000 4d04h00m00s
864000 10d00h00m00s

Reference Implementation

function formatDuration(totalSeconds: bigint): string {
  const t = totalSeconds < 0n ? -totalSeconds : totalSeconds;
  const days = t / 86400n;
  const hh = ((t % 86400n) / 3600n).toString().padStart(2, "0");
  const mm = ((t % 3600n) / 60n).toString().padStart(2, "0");
  const ss = (t % 60n).toString().padStart(2, "0");
  return `${days}d${hh}h${mm}m${ss}s`;
}

Security Considerations

duration commonly renders a validity or authorization window (e.g. a decryption-delegation
or operator expiry). A misread duration could lead a user to authorize longer-lived access
than intended. The days-inclusive format directly reduces that misread risk versus large
unbounded hour counts. The change is rendering-only and introduces no new attack surface.

@eip-review-bot

eip-review-bot commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator

File ERCS/erc-7730.md

Requires 1 more review from Authors: @arein, @arikg, @forshtat, @fredrik0x, @kuzdogan, @lcastillo-ledger, @llbartekll, @paoun-ledger

@eip-review-bot eip-review-bot changed the title Improve duration format Update ERC-7730: Improve duration format Jul 24, 2026
@forshtat

Copy link
Copy Markdown
Contributor

Just a quick question - should an upper bound for duration be defined in the ERC? I mean, if totalSeconds: bigint is 2²⁵⁶, is threshold applicable for duration fields?

@melanciani

Copy link
Copy Markdown
Contributor Author

Just a quick question - should an upper bound for duration be defined in the ERC? I mean, if totalSeconds: bigint is 2²⁵⁶, is threshold applicable for duration fields?

truncating duration seems dangerous for clear signing as it could hide genuine large values , no ? Still, we could include some kind of unboundedMessage parameter (with default Forever) for type(uint256).max, wdyt ?

@forshtat

Copy link
Copy Markdown
Contributor

truncating duration seems dangerous for clear signing as it could hide genuine large values , no ? Still, we could include some kind of unboundedMessage parameter (with default Forever) for type(uint256).max, wdyt ?

Well, for me personally having a Forever value for durations (similar to existing Unlimited value for amounts) makes total sense.
Will be happy to hear if it was not added for a reason that I might be missing here.

@melanciani

Copy link
Copy Markdown
Contributor Author

I was not part of the initial specs regarding this so can't say, this PR is suggestion toward improving this ! I've pushed the unboundedMessage parameter change

@kuzdogan

kuzdogan commented Jul 29, 2026

Copy link
Copy Markdown
Member

While we are on it, shouldn't we also add "months" and "years" too? I assume there will be use cases to set couple years of deadlines etc.

Edit: I guess months will be tricky because of variable days of month (30 or 31). Same for years with 366 and 365 day years?

@forshtat

Copy link
Copy Markdown
Contributor

Edit: I guess months will be tricky because of variable days of month (30 or 31). Same for years with 366 and 365 day years?

Yeah, the wallet will need to know if the duration field means "a countdown that starts right now" or not, and to know the current time (most wallets don't) to render it precisely (could even give you the end date then).
Should we allow rendering durations as "Approximately 5 years and 7 months"?

@melanciani

Copy link
Copy Markdown
Contributor Author

@kuzdogan @forshtat following your comments, I agree years/months would make sense but I think we should avoid displays approximation by default. Still, I feel it would make sense to introduce a new optional parameter that would enable a more readable view like "Approximately 5 years and 7 months" yes, I'll try to suggest something soon

@melanciani

Copy link
Copy Markdown
Contributor Author

hey again @kuzdogan @forshtat what do you think of my suggestion ? I'm mostly not sure about the need to specify the exact way we want to display approximation:

Add approximation parameter to the duration format

Optional approximation boolean (default false) on durationParameters. When enabled, an approximate calendar duration is appended after the exact one:

1856d00h00m00s (approx. 5 years and 1 month)
210d00h00m00s (approx. 7 months)

It's appended, never a replacement, so no precision is hidden.

The algorithm is fully specified so all wallets render identically: round to the nearest month (2629800 s = 30.4375 d, so 12 months = 1 Julian year), split into years/months, omit zero components, singular/plural per value. Values below one month get no suffix, and type(uint256).max still renders unboundedMessage alone.

Only years and months — stopping there keeps the output a deterministic function of the value, with no clock, locale or calendar needed. Default false, so existing descriptors are unaffected

@github-actions github-actions Bot added the w-ci label Aug 5, 2026
@melanciani

Copy link
Copy Markdown
Contributor Author

CI is failing on something unrelated: I've opened an issue to fix this: #1933

@melanciani
melanciani force-pushed the melanciani/erc7730_duration_display_options branch from 742b0b6 to c0201a9 Compare August 12, 2026 20:45
@github-actions

Copy link
Copy Markdown

The commit c0201a9 (as a parent of 8f783e5) contains errors.
Please inspect the Run Summary for details.

@melanciani
melanciani force-pushed the melanciani/erc7730_duration_display_options branch from c0201a9 to 407e4f2 Compare August 12, 2026 20:50
@github-actions github-actions Bot removed the w-ci label Aug 12, 2026
@melanciani

Copy link
Copy Markdown
Contributor Author

ci is green again ! cc @forshtat @kuzdogan

Comment thread ERCS/erc-7730.md Outdated
Co-authored-by: Alex Forshtat <forshtat1@gmail.com>
@melanciani
melanciani requested a review from forshtat August 14, 2026 19:04
@melanciani

Copy link
Copy Markdown
Contributor Author

while working again on ethereum/clear-signing-erc7730-registry#2595, I suggest a new improvement: instead of just adding Forever, we generalize to special values (not threshold), to also support 0 values (without enforcing any labels)

For example: we have a setter that gives right for a period of time, and revoke path uses 0 as the time input: in this case, we'd prefer not to display the 01/01/1970 date and instead have a custom label like Immediately

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants