@coinlist-co/react 0.12.2-rc.abd9d38 → 0.12.2-rc.e1f6c82

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +10 -0
  2. package/dist/{chunk-45LAPB7U.js → chunk-EKLUJZ7T.js} +10 -10
  3. package/dist/chunk-EKLUJZ7T.js.map +1 -0
  4. package/dist/{chunk-HDJEDOS4.js → chunk-GIE4UWB3.js} +1207 -799
  5. package/dist/chunk-GIE4UWB3.js.map +1 -0
  6. package/dist/chunk-MJ6YXZWH.js +22 -0
  7. package/dist/chunk-MJ6YXZWH.js.map +1 -0
  8. package/dist/{chunk-M7WDZZPX.js → chunk-PIOQA6HW.js} +194 -190
  9. package/dist/chunk-PIOQA6HW.js.map +1 -0
  10. package/dist/client/index.d.ts +2977 -4267
  11. package/dist/client/index.js +8552 -5713
  12. package/dist/client/index.js.map +1 -1
  13. package/dist/server/index.d.ts +7 -33
  14. package/dist/server/index.js +8 -4
  15. package/dist/server/index.js.map +1 -1
  16. package/dist/{tokens-namespace-DrwRi0AQ.d.cts → time-Bbqlt2x7.d.ts} +2081 -2734
  17. package/dist/{token-registry-snapshot-C-Qs3Lgs.d.ts → token-registry-snapshot-DttZXGvY.d.ts} +74 -42
  18. package/dist/universal/index.d.ts +59 -998
  19. package/dist/universal/index.js +38 -36
  20. package/package.json +18 -14
  21. package/dist/chunk-45LAPB7U.js.map +0 -1
  22. package/dist/chunk-HDJEDOS4.js.map +0 -1
  23. package/dist/chunk-M7WDZZPX.js.map +0 -1
  24. package/dist/client/index.cjs +0 -17098
  25. package/dist/client/index.cjs.map +0 -1
  26. package/dist/client/index.d.cts +0 -6660
  27. package/dist/server/index.cjs +0 -4240
  28. package/dist/server/index.cjs.map +0 -1
  29. package/dist/server/index.d.cts +0 -378
  30. package/dist/time-BOCS1TbH.d.cts +0 -50
  31. package/dist/time-C7mhO5_a.d.ts +0 -50
  32. package/dist/token-registry-snapshot-CpzLmsc2.d.cts +0 -179
  33. package/dist/tokens-namespace-DrwRi0AQ.d.ts +0 -3364
  34. package/dist/universal/index.cjs +0 -4135
  35. package/dist/universal/index.cjs.map +0 -1
  36. package/dist/universal/index.d.cts +0 -1314
@@ -1,378 +0,0 @@
1
- import { A as AuthorizationCode, C as CodeVerifier, aq as OAuthSession, v as OAuthAccessToken, ar as ClientCredentialsOAuth, as as Sender, L as Logger, w as OffersNamespace, J as Offer, at as PaginationParams, au as PaginatedResponse, O as OfferId, z as OfferDetail, R as RequirementsNamespace, d as OfferOptionId, s as Requirement, t as RequirementsNamespaceImpl, U as UniversalNamespaceContext, o as WalletsNamespace, E as Erc20Namespace, c as CoinListTokenSaleNamespace, S as SuperstateSwapNamespace, g as OndoNamespace, T as TokensNamespace, u as Config, av as ClientSecret, _ as PinoLoggerOptions } from '../tokens-namespace-DrwRi0AQ.cjs';
2
- import { S as Seconds } from '../time-BOCS1TbH.cjs';
3
- import 'viem';
4
-
5
- interface SessionStore {
6
- getSession(): Promise<OAuthSession | null>;
7
- /**
8
- * Persists or clears the OAuth session.
9
- *
10
- * **Omit this method to create a read-only store.** When absent, the SDK
11
- * skips token refresh entirely — no network call is made and no refresh
12
- * token is consumed. This is the correct approach for contexts that can read
13
- * the session but cannot write it back, such as Next.js Server Components.
14
- *
15
- * ⚠️ Do **not** implement this as a no-op (`async () => {}`). If the method
16
- * is present, the SDK assumes writes succeed: it will fire a token refresh
17
- * network call, consume the refresh token, then invoke `setSession` — which
18
- * would silently discard the new session and leave the browser holding an
19
- * invalidated refresh token. Simply **omit** `setSession` to prevent any
20
- * refresh from being attempted.
21
- *
22
- * {@link ServerAuthNamespace.completeOAuth} and
23
- * {@link ServerAuthNamespace.logout} always require a writable store and
24
- * throw {@link WritableSessionStoreRequiredError} if `setSession` is absent.
25
- */
26
- setSession?(session: OAuthSession | null): Promise<void>;
27
- }
28
- /**
29
- * The empty session store: holds no session, reads nothing, never writes.
30
- *
31
- * For server contexts that act without a user — the client-credentials grant
32
- * (`auth.clientCredentials`) and the public token registry (`tokens`) read
33
- * nothing from the store, so hosts building those paths need no store of
34
- * their own.
35
- *
36
- * `setSession` is deliberately absent, not a no-op — see
37
- * {@link SessionStore.setSession} for why a no-op is a bug.
38
- */
39
- declare function emptySessionStore(): SessionStore;
40
- /** The PKCE pair `CoinListClient#auth.completeOAuth` hands to the backend. */
41
- interface CompleteOAuthParams {
42
- /** The short-lived authorization code parsed out of the redirect URL. */
43
- code: AuthorizationCode;
44
- /** The `code_verifier` the browser generated when starting the flow. */
45
- codeVerifier: CodeVerifier;
46
- }
47
- /**
48
- * OAuth session lifecycle on your backend: exchanging authorization codes,
49
- * keeping the access token fresh, minting app-level tokens, and logging out.
50
- *
51
- * This namespace is server-only: every method needs the `clientSecret` and the
52
- * {@link SessionStore}, neither of which may exist in a browser.
53
- */
54
- interface ServerAuthNamespace {
55
- /**
56
- * Exchanges an authorization code from `CoinListClient#auth.completeOAuth`
57
- * for an OAuth session and persists it via {@link SessionStore.setSession}.
58
- *
59
- * The exchange is never retried automatically: an authorization code is
60
- * single-use, so a retry of an attempt that reached the server would fail
61
- * anyway, and could mask why the first one did.
62
- *
63
- * @throws {@link WritableSessionStoreRequiredError} if the session store
64
- * does not provide `setSession`.
65
- * @throws {@link HttpError} if CoinList refuses the exchange.
66
- */
67
- completeOAuth(params: CompleteOAuthParams): Promise<OAuthSession>;
68
- /**
69
- * Returns a valid access token for the current session, refreshing it if it
70
- * is expired or near expiry. This is what you serve to
71
- * {@link ClientConfig.getAccessToken}: answer `null` with "no session"
72
- * (e.g. a 204) and a throw with a failure (e.g. a 503), never the other way
73
- * round - the browser signs the user out on the first and not the second.
74
- *
75
- * **Writable store**: if the token is expired, the SDK exchanges the refresh
76
- * token for a new session, persists it, and returns the fresh access token.
77
- * Concurrent calls for the same session in this process share one exchange.
78
- *
79
- * A rejected refresh token (`400 invalid_grant`) is only a *suspicion* at
80
- * first, because the backend answers "rotated a moment ago by a concurrent
81
- * request" and "expired or revoked" identically: the SDK writes nothing,
82
- * so it cannot overwrite the session the winning request just stored, and
83
- * returns `null` - or the current access token, if that has not actually
84
- * expired yet. Only a second rejection of the same refresh token, 5 to 60
85
- * seconds later in this process, is the verdict: the session is cleared via
86
- * {@link SessionStore.setSession} and {@link Config.onSessionExpired} is
87
- * called. A browser confirming through your endpoint asks again after one
88
- * second, so it signs out on its own verdict and not on this one.
89
- *
90
- * **Read-only store** (no `setSession`): refresh is skipped entirely. The
91
- * stored token is returned as-is, even if it is expired — a non-null return
92
- * value does **not** guarantee the token is accepted by the API. Before
93
- * making API calls, check `token.expiresAt > new Date()`. Use a writable
94
- * store (e.g. in a Route Handler) when you need the SDK to renew the session
95
- * automatically.
96
- *
97
- * @returns the access token, or `null` if there is no session, or the
98
- * session was rejected (suspected or confirmed).
99
- * @throws the underlying error - an {@link HttpError} for a 5xx or
100
- * `invalid_client`, the `fetch` error for a network failure - when the SDK
101
- * could not find out whether a session exists and the current access token
102
- * has already expired. The session is left untouched. **Never treat this as
103
- * logged out**: it means "try again", and during an outage treating it as
104
- * logged out would sign out every user at once.
105
- */
106
- getAccessToken(): Promise<OAuthAccessToken | null>;
107
- /**
108
- * Obtains an app-level access token via the OAuth 2.0 `client_credentials`
109
- * grant (RFC 6749 §4.4). No user is involved: the token authenticates the
110
- * partner application itself and only grants access to app-level resources
111
- * such as offers and offer requirements.
112
- *
113
- * The token is **not** persisted to the {@link SessionStore} and has no
114
- * refresh token. It expires at `expiresAt`; once expired, call this method
115
- * again to obtain a fresh token — the SDK does not renew it automatically.
116
- *
117
- * Pass the result to `ServerOffersNamespace` or
118
- * `ServerRequirementsNamespace.forOffer` to read without a user session.
119
- */
120
- clientCredentials(): Promise<ClientCredentialsOAuth>;
121
- /**
122
- * Revokes the current token via `POST /oauth/revoke` and clears the session.
123
- * Does nothing when there is no session.
124
- *
125
- * The revoke is best-effort: if it fails for any reason - an
126
- * {@link HttpError}, a network failure, anything else - the failure is
127
- * logged at `'warn'` and the session is cleared regardless, because the
128
- * cleared session is what logs the user out. Set `strict` on the server
129
- * config to rethrow it instead.
130
- *
131
- * @throws {@link WritableSessionStoreRequiredError} if the session store does
132
- * not provide `setSession`.
133
- * @throws whatever the {@link SessionStore} throws, in either mode. A failed
134
- * `setSession(null)` means the session was not cleared.
135
- * @throws the revoke failure, only when `strict` is set. The session is then
136
- * left untouched, so the call can be retried.
137
- */
138
- logout(): Promise<void>;
139
- }
140
-
141
- /**
142
- * What the server-only namespaces need, on top of what
143
- * {@link UniversalNamespaceContext} provides: authentication that a caller can
144
- * satisfy with an app-level token instead of a user session.
145
- */
146
- interface ServerNamespaceContext {
147
- readonly api: Sender;
148
- /** As {@link UniversalNamespaceContext.logger}: the raw port, scoped per namespace. */
149
- readonly logger: Logger | null;
150
- /**
151
- * Requires a user session, unless `clientCreds` is supplied — an app-level
152
- * token authenticates the request on its own. Throws
153
- * {@link NotAuthenticatedError} when neither is present.
154
- */
155
- ensureAuthenticated(clientCreds?: ClientCredentialsOAuth): Promise<void>;
156
- }
157
-
158
- /**
159
- * The server-side offers namespace: the same reads as the shared
160
- * {@link OffersNamespace}, each additionally callable with an app-level token
161
- * from `ServerAuthNamespace.clientCredentials` instead of a user session.
162
- *
163
- * When a user session exists it takes precedence and `clientCreds` acts as a
164
- * fallback. Without either, the reads throw {@link NotAuthenticatedError}.
165
- */
166
- interface ServerOffersNamespace extends OffersNamespace {
167
- /** @param clientCreds app-level token to read without a user session. */
168
- list(clientCreds?: ClientCredentialsOAuth): Promise<Offer[]>;
169
- /** @param clientCreds app-level token to read without a user session. */
170
- listPage(params: PaginationParams, clientCreds?: ClientCredentialsOAuth): Promise<PaginatedResponse<Offer>>;
171
- /** @param clientCreds app-level token to read without a user session. */
172
- get(id: OfferId, clientCreds?: ClientCredentialsOAuth): Promise<OfferDetail>;
173
- }
174
- declare class ServerOffersNamespaceImpl implements ServerOffersNamespace {
175
- private readonly ctx;
176
- private readonly log;
177
- constructor(ctx: ServerNamespaceContext);
178
- list(clientCreds?: ClientCredentialsOAuth): Promise<Offer[]>;
179
- listPage(params: PaginationParams, clientCreds?: ClientCredentialsOAuth): Promise<PaginatedResponse<Offer>>;
180
- get(id: OfferId, clientCreds?: ClientCredentialsOAuth): Promise<OfferDetail>;
181
- }
182
-
183
- /**
184
- * The server-side requirements namespace: the same surface as the shared
185
- * {@link RequirementsNamespace}, except {@link forOffer} — the offer's
186
- * requirement definitions are app-level data, so it is additionally callable
187
- * with a token from `ServerAuthNamespace.clientCredentials`.
188
- *
189
- * Everything else is per-user data and needs a user session. `handle` is
190
- * client-only: there is no browser tab to open on a server.
191
- */
192
- interface ServerRequirementsNamespace extends RequirementsNamespace {
193
- /** @param clientCreds app-level token to read without a user session. */
194
- forOffer(offerId: OfferId, clientCreds?: ClientCredentialsOAuth): Promise<Record<OfferOptionId, Requirement[]>>;
195
- }
196
- declare class ServerRequirementsNamespaceImpl extends RequirementsNamespaceImpl implements ServerRequirementsNamespace {
197
- private readonly serverCtx;
198
- constructor(serverCtx: UniversalNamespaceContext & ServerNamespaceContext);
199
- forOffer(offerId: OfferId, clientCreds?: ClientCredentialsOAuth): Promise<Record<OfferOptionId, Requirement[]>>;
200
- }
201
-
202
- interface ServerConfig extends Config {
203
- readonly clientSecret: ClientSecret;
204
- readonly sessionStore: SessionStore;
205
- /**
206
- * How many seconds before its expiry an access token is refreshed. Defaults
207
- * to 60. Refreshing early moves the work to a single request while the
208
- * current token still works, and a refresh that fails inside this window
209
- * keeps serving the current token rather than failing the request.
210
- *
211
- * Build it with `Seconds.of(n)`, which throws a `ValidationError` unless
212
- * `n` is a non-negative integer.
213
- */
214
- readonly accessTokenExpiryBufferSeconds?: Seconds;
215
- /**
216
- * Whether the SDK throws where it would otherwise recover and log a
217
- * `'warn'` line. Defaults to `false`.
218
- *
219
- * Today it governs one thing: a failed token revoke in `auth.logout()`. By
220
- * default the session is cleared regardless; with `strict` the failure is
221
- * rethrown and the session is left untouched.
222
- */
223
- readonly strict?: boolean;
224
- }
225
- /**
226
- * Server-side CoinList SDK client.
227
- *
228
- * Functionality is grouped into namespaces — `coinlist.auth.getAccessToken()`,
229
- * `coinlist.offers.list()`, `coinlist.requirements.statuses(offerId)`.
230
- *
231
- * Operates in one of two modes depending on whether {@link SessionStore}
232
- * includes a `setSession` implementation:
233
- *
234
- * - **Writable store** (`setSession` provided) — full functionality: token
235
- * refresh, `auth.completeOAuth`, and `auth.logout` all work normally.
236
- *
237
- * - **Read-only store** (no `setSession`) — token refresh is skipped entirely,
238
- * meaning no network call is made and no refresh token is consumed.
239
- * `auth.completeOAuth` and `auth.logout` throw
240
- * {@link WritableSessionStoreRequiredError}. `auth.getAccessToken` may
241
- * return an expired token (see its docs). Use this mode in execution
242
- * contexts that can read the session but cannot write it back, such as
243
- * Next.js Server Components.
244
- *
245
- * Unless a namespace says otherwise, its methods require a user session and
246
- * throw {@link NotAuthenticatedError} when there is none. When the SDK could
247
- * not find out whether there is one - CoinList's token endpoint failing, or
248
- * the network - they throw that underlying error instead: see
249
- * {@link ServerAuthNamespace.getAccessToken}.
250
- */
251
- interface CoinListServer {
252
- /**
253
- * OAuth session lifecycle: exchanging an authorization code, serving a valid
254
- * access token to the browser, minting app-level tokens, and logging out —
255
- * e.g. `coinlist.auth.getAccessToken()`.
256
- */
257
- readonly auth: ServerAuthNamespace;
258
- /**
259
- * The offer catalogue — e.g. `coinlist.offers.list()`. Every read also
260
- * accepts an app-level token from {@link ServerAuthNamespace.clientCredentials}
261
- * so it can run without a user session.
262
- */
263
- readonly offers: ServerOffersNamespace;
264
- /**
265
- * Offer requirements and the operations that satisfy them — e.g.
266
- * `coinlist.requirements.statuses(offerId)`. `forOffer` also accepts an
267
- * app-level token; the rest is per-user data and needs a user session.
268
- */
269
- readonly requirements: ServerRequirementsNamespace;
270
- /**
271
- * The user's external wallets: ownership proofs and offer-option bindings —
272
- * e.g. `coinlist.wallets.list({ offerId, offerOptionId })`.
273
- */
274
- readonly wallets: WalletsNamespace;
275
- /**
276
- * Generic ERC-20 reads (token allowance and balance) — e.g.
277
- * `coinlist.erc20.getBalance({ ... })`.
278
- */
279
- readonly erc20: Erc20Namespace;
280
- /**
281
- * Token-sale operations: listing, reading, and recording participations —
282
- * e.g. `coinlist.tokenSale.list()`. The on-chain `execute`
283
- * flow is client-only and is not exposed here.
284
- */
285
- readonly tokenSale: CoinListTokenSaleNamespace;
286
- /**
287
- * On-chain swap operations: quoting a swap, reading swap-contract state, and
288
- * allow-listing a proven wallet — e.g.
289
- * `coinlist.superstate.getOutputToken({ contractAddress, chain })`.
290
- */
291
- readonly superstate: SuperstateSwapNamespace;
292
- /**
293
- * Ondo swap reads: trading status and quoting. Both are free to poll.
294
- *
295
- * No CoinList fee is applied to a quote; see {@link OndoNamespace}.
296
- *
297
- * This is Ondo's whole surface for now — the wallet-driven half arrives with
298
- * ENG-1680 and will be client-only, since it needs a wallet to sign with.
299
- */
300
- readonly ondo: OndoNamespace;
301
- /**
302
- * Token display metadata (name, symbol, decimals, logos) from CoinList's
303
- * public token registry, keyed by chain + contract address — e.g.
304
- * `coinlist.tokens.get({ chain, address })` for an entry of
305
- * `Offer.tokens`, or `coinlist.tokens.list()` for the whole
306
- * catalogue in one request.
307
- *
308
- * Public and unauthenticated: unlike the other namespaces, its methods never
309
- * require a session, so it also works with a read-only store.
310
- */
311
- readonly tokens: TokensNamespace;
312
- }
313
- declare function createCoinListServer(config: ServerConfig): CoinListServer;
314
-
315
- /**
316
- * A {@link Logger} that writes newline-delimited JSON to stdout through pino.
317
- *
318
- * ```ts
319
- * createCoinListServer({
320
- * ...config,
321
- * logger: pinoServerLogger({ isDev: false, level: 'info' }),
322
- * });
323
- * ```
324
- *
325
- * The Node counterpart of {@link pinoClientLogger}, for a route handler, a BFF
326
- * or SSR. One line per record, which is what every log aggregator ingests
327
- * without configuration.
328
- *
329
- * ## What it deliberately does not do
330
- *
331
- * **No transport, and no `pino-pretty`.** A pino transport runs on a worker
332
- * thread through `thread-stream`, which every bundler has to be told about
333
- * (`serverExternalPackages` in Next) and which edge runtimes cannot run at
334
- * all. Pretty-printing is a pipe the host owns rather than a dependency the
335
- * SDK takes on their behalf:
336
- *
337
- * ```sh
338
- * node server.js | npx pino-pretty
339
- * ```
340
- *
341
- * **No environment-dependent formatting.** `isDev` decides which levels are
342
- * legal and nothing else, so a development record and a production record are
343
- * the same shape - what you debug is what you ship.
344
- *
345
- * If you already run pino, or want transports, redaction or `destination`,
346
- * implement {@link Logger} yourself: it is four methods over an event, and
347
- * `@opentelemetry/instrumentation-pino` patches the pino module rather than an
348
- * instance, so trace correlation reaches this logger either way.
349
- *
350
- * ## Production
351
- *
352
- * **Not advised in production**, the same as everywhere else this seam is
353
- * documented: the SDK's default answer is to leave {@link Config.logger}
354
- * undefined outside development, staging and incident reproduction. A backend
355
- * is the least bad place to disregard that - the records go to your process
356
- * and your sink rather than to a page the end user can read - but it is still
357
- * a disregard, and the retention and access questions become yours.
358
- *
359
- * If you run one, `isDev: false` restricts you to `'error'`, `'warn'` and
360
- * `'info'` - `{ isDev: false, level: 'debug' }` does not compile, see
361
- * {@link PinoLoggerOptions}. Those levels are redacted by construction, which
362
- * is a mechanism the SDK holds itself to; whether that clears your bar is a
363
- * judgement the SDK is not in a position to make for you.
364
- *
365
- * Holds no module-level state: every call builds its own pino instance, and
366
- * the level is fixed at construction, so two loggers never interfere. Fixed is
367
- * this implementation's choice, not the seam's - the SDK re-reads
368
- * {@link Logger.level} before every log call - so if you want a level you can
369
- * change at runtime, implement {@link Logger} over your own pino instance
370
- * rather than calling this.
371
- */
372
- declare function pinoServerLogger(options: PinoLoggerOptions): Logger;
373
-
374
- declare class WritableSessionStoreRequiredError extends Error {
375
- constructor(message?: string);
376
- }
377
-
378
- export { type CoinListServer, type CompleteOAuthParams, type ServerAuthNamespace, type ServerConfig, type ServerNamespaceContext, type ServerOffersNamespace, ServerOffersNamespaceImpl, type ServerRequirementsNamespace, ServerRequirementsNamespaceImpl, type SessionStore, WritableSessionStoreRequiredError, createCoinListServer, emptySessionStore, pinoServerLogger };
@@ -1,50 +0,0 @@
1
- import { aA as Newtype } from './tokens-namespace-DrwRi0AQ.cjs';
2
-
3
- /**
4
- * An instant: milliseconds since the Unix epoch, as `Date.now()` reads it.
5
- * Distinct from {@link Millis}, a duration, so an instant cannot be passed
6
- * where a timeout is expected or the other way round.
7
- */
8
- type EpochMillis = Newtype<number, 'EpochMillis'>;
9
- declare const EpochMillis: {
10
- /**
11
- * @throws {@link ValidationError} unless `value` is an integer a `Date` can
12
- * represent: at most {@link MAX_EPOCH_MILLIS} either side of the epoch.
13
- */
14
- of: (value: number) => EpochMillis;
15
- /** The wall clock. Code that needs the time takes a `TimeEff` instead. */
16
- now: () => EpochMillis;
17
- /** @throws {@link ValidationError} for an invalid `Date`. */
18
- fromDate: (date: Date) => EpochMillis;
19
- /** How long after `from` the instant `to` is; negative if it is before. */
20
- elapsed: (from: EpochMillis, to: EpochMillis) => Millis;
21
- plus: (at: EpochMillis, duration: Millis) => EpochMillis;
22
- };
23
- /**
24
- * A duration in milliseconds. May be negative: the gap between two instants
25
- * read off a wall clock that stepped back in between.
26
- */
27
- type Millis = Newtype<number, 'Millis'>;
28
- declare const Millis: {
29
- of: (value: number) => Millis;
30
- };
31
- /** A duration in whole, non-negative seconds. */
32
- type Seconds = Newtype<number, 'Seconds'>;
33
- declare const Seconds: {
34
- /**
35
- * @throws {@link ValidationError} unless `value` is a non-negative integer.
36
- */
37
- of: (value: number) => Seconds;
38
- toMillis: (value: Seconds) => Millis;
39
- };
40
- /**
41
- * Whether `expiresAt` has passed at `now`, counting it as passed `buffer`
42
- * early. The boundary instant itself counts as expired.
43
- */
44
- declare function isExpired({ expiresAt, now, buffer, }: {
45
- expiresAt: EpochMillis;
46
- now: EpochMillis;
47
- buffer?: Millis;
48
- }): boolean;
49
-
50
- export { EpochMillis as E, Millis as M, Seconds as S, isExpired as i };
@@ -1,50 +0,0 @@
1
- import { aA as Newtype } from './tokens-namespace-DrwRi0AQ.js';
2
-
3
- /**
4
- * An instant: milliseconds since the Unix epoch, as `Date.now()` reads it.
5
- * Distinct from {@link Millis}, a duration, so an instant cannot be passed
6
- * where a timeout is expected or the other way round.
7
- */
8
- type EpochMillis = Newtype<number, 'EpochMillis'>;
9
- declare const EpochMillis: {
10
- /**
11
- * @throws {@link ValidationError} unless `value` is an integer a `Date` can
12
- * represent: at most {@link MAX_EPOCH_MILLIS} either side of the epoch.
13
- */
14
- of: (value: number) => EpochMillis;
15
- /** The wall clock. Code that needs the time takes a `TimeEff` instead. */
16
- now: () => EpochMillis;
17
- /** @throws {@link ValidationError} for an invalid `Date`. */
18
- fromDate: (date: Date) => EpochMillis;
19
- /** How long after `from` the instant `to` is; negative if it is before. */
20
- elapsed: (from: EpochMillis, to: EpochMillis) => Millis;
21
- plus: (at: EpochMillis, duration: Millis) => EpochMillis;
22
- };
23
- /**
24
- * A duration in milliseconds. May be negative: the gap between two instants
25
- * read off a wall clock that stepped back in between.
26
- */
27
- type Millis = Newtype<number, 'Millis'>;
28
- declare const Millis: {
29
- of: (value: number) => Millis;
30
- };
31
- /** A duration in whole, non-negative seconds. */
32
- type Seconds = Newtype<number, 'Seconds'>;
33
- declare const Seconds: {
34
- /**
35
- * @throws {@link ValidationError} unless `value` is a non-negative integer.
36
- */
37
- of: (value: number) => Seconds;
38
- toMillis: (value: Seconds) => Millis;
39
- };
40
- /**
41
- * Whether `expiresAt` has passed at `now`, counting it as passed `buffer`
42
- * early. The boundary instant itself counts as expired.
43
- */
44
- declare function isExpired({ expiresAt, now, buffer, }: {
45
- expiresAt: EpochMillis;
46
- now: EpochMillis;
47
- buffer?: Millis;
48
- }): boolean;
49
-
50
- export { EpochMillis as E, Millis as M, Seconds as S, isExpired as i };
@@ -1,179 +0,0 @@
1
- import { aI as ClientId, bw as RedirectUri, aJ as CodeChallenge, bk as PKCEState, C as CodeVerifier, q as EvmWalletAddress, a as EthereumChain, bN as Tx, B as BlockchainAmount, bG as SwapPreview, a0 as AssetDecimals, aA as Newtype, D as TokenMetadata, aH as Chain, b as EvmContractAddress, bf as OfferToken } from './tokens-namespace-DrwRi0AQ.cjs';
2
- import { Hex, Abi, Hash, TransactionReceipt } from 'viem';
3
-
4
- type PKCEParams = {
5
- clientId: ClientId;
6
- responseType: 'code';
7
- redirectUri: RedirectUri;
8
- codeChallenge: CodeChallenge;
9
- codeChallengeMethod: 'S256';
10
- state: PKCEState;
11
- codeVerifier: CodeVerifier;
12
- };
13
- type PKCEConfig = {
14
- clientId: ClientId;
15
- redirectUri: RedirectUri;
16
- };
17
- /**
18
- * Generates PKCE parameters for an OAuth2 authorization code flow.
19
- * Pure crypto — no React, no DOM beyond Web Crypto API. Safe to use
20
- * in server-side code and Next.js middleware.
21
- */
22
- declare function generatePKCEParams(config: PKCEConfig): Promise<PKCEParams>;
23
-
24
- type WriteContractParams = {
25
- abi: Abi;
26
- address: `0x${string}`;
27
- functionName: string;
28
- args?: readonly unknown[];
29
- value?: bigint;
30
- chain: EthereumChain;
31
- };
32
- type BroadcastTxParams = Tx & {
33
- chain: EthereumChain;
34
- };
35
- /**
36
- * The signing-only wallet capability: address + `signMessage`. This is all the
37
- * external-wallet ownership proof needs (see `useConnectWallet`), so hosts can
38
- * satisfy that flow without implementing on-chain capabilities. The richer
39
- * {@link EvmWallet} extends this for swap flows.
40
- *
41
- * SDK users implement this against their own wallet stack (e.g. viem, wagmi,
42
- * Privy). `signMessage` throws on failure and the SDK classifies it.
43
- */
44
- interface EvmSigner {
45
- readonly address: EvmWalletAddress;
46
- signMessage(message: string): Promise<Hex>;
47
- }
48
- /**
49
- * The full on-chain wallet the SDK needs to run the swap flows: an
50
- * {@link EvmSigner} plus contract writes, raw-tx broadcast, and confirmation.
51
- * SDK users implement this against their own wallet stack (e.g. viem, wagmi,
52
- * Privy).
53
- *
54
- * Methods throw on failure. The SDK catches and classifies the thrown error
55
- * (viem's `UserRejectedRequestError`, `InsufficientFundsError`, timeouts, …)
56
- * into a typed {@link WalletError}, so implementers can simply let their wallet
57
- * library's errors propagate.
58
- */
59
- interface EvmWallet extends EvmSigner {
60
- writeContract(params: WriteContractParams): Promise<Hash>;
61
- broadcastRawTx(params: BroadcastTxParams): Promise<Hash>;
62
- awaitTx(hash: Hash, chain: EthereumChain): Promise<TransactionReceipt>;
63
- }
64
- /**
65
- * The host-provided wallet the ownership flow signs with: the signing-only
66
- * {@link EvmSigner} plus the {@link EthereumChain} the signature is proven on.
67
- * `chain` rides on the wallet (not the offer) because the binding is
68
- * chain-agnostic: it only records which EVM chain signed.
69
- */
70
- type ConnectWallet = EvmSigner & {
71
- readonly chain: EthereumChain;
72
- };
73
-
74
- /**
75
- * A read-only quote for a swap as domain amounts: how much goes in, the
76
- * protocol fee, and how much would come out. Derived from the raw
77
- * {@link SwapPreview} the swap contract returns.
78
- */
79
- type SwapQuote = {
80
- inputTokenAmount: BlockchainAmount;
81
- fee: BlockchainAmount;
82
- outputTokenAmount: BlockchainAmount;
83
- };
84
- declare const SwapQuote: {
85
- /**
86
- * Assembles a {@link SwapQuote} from a raw contract {@link SwapPreview}. The
87
- * input and fee are denominated in the input token; the output in the output
88
- * token.
89
- */
90
- fromPreview: (preview: SwapPreview, inputDecimals: AssetDecimals, outputDecimals: AssetDecimals) => SwapQuote;
91
- };
92
-
93
- type FormattedAmountUi = Newtype<string, 'FormattedAmountUi'>;
94
- declare const FormattedAmountUi: (value: string) => FormattedAmountUi;
95
- type FormattedPercentUi = Newtype<string, 'FormattedPercentUi'>;
96
- declare const FormattedPercentUi: (value: string) => FormattedPercentUi;
97
- type TxExplorerUrl = Newtype<string, 'TxExplorerUrl'>;
98
- declare const TxExplorerUrl: (value: string) => TxExplorerUrl;
99
- /**
100
- * A wallet address shortened for display (e.g. `0x1234…5678`). Keeps a
101
- * `0x${string}` base but drops the runtime `0x` narrowing.
102
- */
103
- type ShortenedWalletAddress = Newtype<`0x${string}`, 'ShortenedWalletAddress'>;
104
- declare const ShortenedWalletAddress: (value: string) => ShortenedWalletAddress;
105
- type FormattedAmountAssetUi = Newtype<string, 'FormattedAmountAssetUi'>;
106
- declare const FormattedAmountAssetUi: (value: string) => FormattedAmountAssetUi;
107
- type AssetIconUrl = Newtype<string, 'AssetIconUrl'>;
108
- declare const AssetIconUrl: (value: string) => AssetIconUrl;
109
-
110
- /**
111
- * An array guaranteed to hold at least one element. Use it where an empty list
112
- * would be a bug (e.g. the set of assets a swap always offers).
113
- */
114
- type NonEmptyArray<T> = [T, ...T[]];
115
-
116
- /**
117
- * A token as a lookup names it. `Chain` rather than `EthereumChain` because
118
- * `OfferToken.chain` is the wider type; a Solana entry simply never matches,
119
- * since the snapshot models EVM chains only.
120
- */
121
- type TokenKey = {
122
- chain: Chain;
123
- address: EvmContractAddress;
124
- };
125
- /**
126
- * One `coinlist.tokens.list()` answer, indexed for the lookups a catalogue
127
- * makes: by the `(chain, address)` pairs `Offer.tokens` carries.
128
- *
129
- * The registry is fetched whole - a few hundred tokens across every chain in
130
- * one request - and then asked one question per offer. Building the index
131
- * once is what keeps that a map lookup per card rather than a scan of the
132
- * snapshot per card. The same rule frontline-web and every other host wrote
133
- * for themselves, kept here so that none of them has to.
134
- */
135
- type TokenRegistrySnapshot = {
136
- /** Every token the snapshot lists, in registry order. */
137
- readonly tokens: readonly TokenMetadata[];
138
- /** `chain:address` (address lowercased) to its metadata. */
139
- readonly byKey: ReadonlyMap<string, TokenMetadata>;
140
- };
141
- declare const TokenRegistrySnapshot: {
142
- /** Indexes a `tokens.list()` result. `[]` is a valid, empty snapshot. */
143
- fromTokens: (tokens: readonly TokenMetadata[]) => TokenRegistrySnapshot;
144
- /**
145
- * The registry's entry for one token, or `null` when it lists none. The
146
- * registry is curated, so `null` is an ordinary answer rather than an
147
- * error, and callers fall back to their own display defaults.
148
- */
149
- get: (snapshot: TokenRegistrySnapshot, token: TokenKey) => TokenMetadata | null;
150
- /**
151
- * The registry's entry for the token an offer is *about*, or `null` when
152
- * it lists none of them.
153
- *
154
- * Resolution follows {@link offerDisplayTokens}: the token a sale
155
- * distributes or a swap hands over, never the funding token the user pays
156
- * with. An offer deployed on several chains carries one such token per
157
- * chain, and the first the registry knows wins - they are the same asset,
158
- * so any listed one answers for the offer.
159
- */
160
- forOffer: (snapshot: TokenRegistrySnapshot, offer: {
161
- tokens: readonly OfferToken[];
162
- }) => TokenMetadata | null;
163
- };
164
- /**
165
- * The tokens an offer is *about*, most specific first: every `swap` entry,
166
- * then every `distribution` entry. `funding` entries name what a swap is paid
167
- * with (USDC, USDT) and never the asset on offer, so they are left out.
168
- *
169
- * `swap` outranks `distribution` because a swap product names the asset it
170
- * hands over precisely, while a sale's distribution entry names the same
171
- * token for a sale product and is accepted as the fallback. The checkout's
172
- * per-chain lookup and the catalogue's any-chain lookup both read this
173
- * ordering, which is why it is stated once, here.
174
- */
175
- declare function offerDisplayTokens(offer: {
176
- tokens: readonly OfferToken[];
177
- }): OfferToken[];
178
-
179
- export { AssetIconUrl as A, type BroadcastTxParams as B, type ConnectWallet as C, type EvmWallet as E, FormattedAmountAssetUi as F, type NonEmptyArray as N, type PKCEConfig as P, SwapQuote as S, TxExplorerUrl as T, type WriteContractParams as W, ShortenedWalletAddress as a, FormattedPercentUi as b, TokenRegistrySnapshot as c, type EvmSigner as d, FormattedAmountUi as e, type PKCEParams as f, generatePKCEParams as g, offerDisplayTokens as o };