@cfxlabsinc/b2b-services
    Preparing search index...

    Holder of the metcap session, and the only place allowed to mint one.

    A metcap login revokes the tokens previously issued to that credential. Every refreshTokens() is therefore a side effect on every OTHER holder of the credential, not a private cache-fill — which is why callers reach for withTokens instead of acquiring and recovering by hand. Two things follow from that, and both are load-bearing:

    • Refresh is single-flight. Concurrent callers that all miss the cache share one login rather than racing N of them, each revoking the last. The SOFT_EXPIRY_BUFFER_MS below cannot do this on its own: a buffer moves when the herd arrives, it never serialises it.
    • Recovery re-runs the call, it does not just re-mint. The old shape was catch { await refreshTokens(); throw } — which discarded the work, minted a token nobody used, and logged out the peer that had just legitimately logged in. That peer then did the same thing back. withTokens ends the ping-pong by making the caller that paid for the login the one that uses it, so each round of contention strictly makes progress.
    Index
    • Parameters

      • args: { metcapClient: MetcapAccountClient; valkeyClient: ValkeyClient | null }

      Returns MetcapTokenService

    • Run one metcap call with a valid session, re-running it once if metcap says the token was revoked mid-flight.

      The single entry point for anything that needs tokens. Callers do not acquire, do not decide when to refresh, and do not write recovery of their own — all three used to be copy-pasted at each call site, and the Lambda's copy simply omitted the recovery, which is why a revoked token there failed a wire outright (WIRE-EMAIL-HANDLER-B).

      fn must be re-runnable: it is invoked a second time with fresh tokens on InvalidToken. Every metcap call behind this today is a read, and a read that returned nothing but an auth rejection has no effect to undo. Do not put a non-idempotent write inside it without checking that.

      Exactly one extra attempt. Immediately after a refresh we hold the newest token in existence, so the retry all but always wins; losing twice means sustained contention, and a third login would only revoke another peer on the way to the same answer. Anything past that is the caller's retry to own — Temporal's for an activity, SES's for the Lambda.

      Type Parameters

      • T

      Parameters

      Returns Promise<T>