lockally_auth library

Secure auth + ergonomics layer for the Lockally Flutter SDK.

Pair with the generated package:lockally/lockally.dart client:

import 'package:lockally/lockally.dart';
import 'package:lockally/lockally_auth.dart';

final client = Lockally(dio: lockallyDio(
  provider: BackendTokenProvider(() async =>
    BackendTokenProvider.parseGrant(await myBackend.fetchToken())),
));

Classes

BackendTokenProvider
The recommended provider for send/OTP/verification/contacts. Calls your backend for a short-lived, narrowly-scoped token; caches it until near expiry. The lk_live_ key stays on your server.
Grant
A short-lived token and when it expires.
InMemoryTokenStore
Non-persistent store — default for tests and for BackendTokenProvider.
LockallyInterceptor
A single dio Interceptor that:
OAuthConfig
OAuth 2.1 authorization-code + PKCE configuration.
OAuthPkceProvider
OAuth PKCE for a signed-in user. Run the browser step with flutter_web_auth_2, then pass the returned code to exchange. Token exchange, refresh, and secure persistence live here.
Page<T>
A page of results from a cursor-paginated endpoint.
Pkce
RFC 7636 Proof Key for Code Exchange (S256).
RetryPolicy
Pure retry/backoff decisions — no timing, no I/O — so it unit-tests cleanly. Retries network errors, 429, and 5xx with exponential backoff + full jitter, honoring Retry-After.
StaticTokenProvider
A fixed key. Do not embed a lk_live_* key in a distributed app — it is extractable from the bundle. Fine for server-side/internal use and lk_test_*.
TokenProvider
Supplies the bearer credential for each request. Async so it can refresh an expiring token or fetch a short-lived one from your backend.
TokenStore
Where OAuth refresh tokens are persisted between launches.

Functions

collect<T>(Future<Page<T>> fetch(String? cursor), {int maxPages = 10000}) Future<List<T>>
Drain every page into a list. Prefer paginate for large result sets.
lockallyDio({required TokenProvider provider, String basePath = 'https://api.lockally.com', RetryPolicy policy = const RetryPolicy()}) → Dio
Build a dio configured with the ergonomics interceptor and a token provider. Pass it to the generated client: Lockally(dio: lockallyDio(provider: ...)).
paginate<T>(Future<Page<T>> fetch(String? cursor), {int maxPages = 10000}) Stream<T>
Iterate every item across all pages of a cursor / next_cursor endpoint as a Stream. A loop guard caps pages so a misbehaving cursor can't spin.

Exceptions / Errors

LockallyException
Typed error mapped from a non-2xx API response. The API returns RFC 7807 application/problem+json; the fields let callers branch on status/code and log requestId for support.