Skip to content

UX: Client-side should validate challenge expiration before creating credential #198

@JasonOA888

Description

@JasonOA888

Problem

When a client receives a Challenge with an expires timestamp that has already passed, the Mppx.createCredential() method still attempts to create a credential and make the payment.

This results in:

  1. Wasted user time - client does work that will be rejected
  2. Unnecessary network round-trips
  3. Potential user confusion (why did my payment fail?)

Current Behavior

The client does not check challenge expiration before creating credentials.

The server validates expiration (src/server/Mppx.ts:359-367):

if (credential.challenge.expires && new Date(credential.challenge.expires) < new Date()) {
  return { challenge: response, status: 402 }
}

But by then the client has already:

  1. Connected wallet
  2. Signed a transaction/message
  3. Submitted the credential

Suggested Fix

Add an expiration check in createCredential() before attempting to create the credential:

async createCredential(response, context) {
  const challenge = transport.getChallenge(response)
  
  // Early rejection of expired challenges
  if (challenge.expires && new Date(challenge.expires) < new Date()) {
    throw new Errors.PaymentExpiredError({ expires: challenge.expires })
  }
  
  // ... rest of implementation
}

Impact

  • Type: UX improvement
  • Risk: Low - just fails faster with clearer error
  • Breaking: No - just changes when the error is thrown

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions