@coinlist-co/react 0.12.2-rc.7b430dd → 0.12.2-rc.8a0d02a
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.
- package/dist/{chunk-DCW7NQXH.js → chunk-3WW5FLT7.js} +52 -19
- package/dist/chunk-3WW5FLT7.js.map +1 -0
- package/dist/{chunk-MOE5S6CE.js → chunk-C6GF7MDF.js} +915 -458
- package/dist/chunk-C6GF7MDF.js.map +1 -0
- package/dist/{chunk-VH34YC3Q.js → chunk-IZJ4JSSC.js} +78 -4
- package/dist/chunk-IZJ4JSSC.js.map +1 -0
- package/dist/client/index.cjs +12103 -8452
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +1640 -37
- package/dist/client/index.d.ts +1640 -37
- package/dist/client/index.js +7923 -4800
- package/dist/client/index.js.map +1 -1
- package/dist/server/index.cjs +789 -142
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +69 -41
- package/dist/server/index.d.ts +69 -41
- package/dist/server/index.js +323 -65
- package/dist/server/index.js.map +1 -1
- package/dist/{tokens-namespace-CIWBtgt2.d.cts → time-CVZpAkGY.d.cts} +878 -192
- package/dist/{tokens-namespace-CIWBtgt2.d.ts → time-CVZpAkGY.d.ts} +878 -192
- package/dist/{token-registry-snapshot-BNBNuDu1.d.ts → token-registry-snapshot-BkwA8KmD.d.ts} +74 -8
- package/dist/{token-registry-snapshot-CqI6dXM_.d.cts → token-registry-snapshot-bR14QehS.d.cts} +74 -8
- package/dist/universal/index.cjs +982 -448
- package/dist/universal/index.cjs.map +1 -1
- package/dist/universal/index.d.cts +91 -5
- package/dist/universal/index.d.ts +91 -5
- package/dist/universal/index.js +44 -2
- package/package.json +1 -1
- package/dist/chunk-DCW7NQXH.js.map +0 -1
- package/dist/chunk-MOE5S6CE.js.map +0 -1
- package/dist/chunk-VH34YC3Q.js.map +0 -1
package/dist/server/index.js
CHANGED
|
@@ -4,28 +4,38 @@ import {
|
|
|
4
4
|
PINO_LEVEL,
|
|
5
5
|
SDK_LOGGER_NAME,
|
|
6
6
|
loggerOverPino,
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
notifySessionExpired,
|
|
8
|
+
publicClients,
|
|
9
|
+
systemTime
|
|
10
|
+
} from "../chunk-3WW5FLT7.js";
|
|
9
11
|
import {
|
|
10
12
|
API_VERSION,
|
|
13
|
+
Attributes,
|
|
14
|
+
CentrifugeNamespaceImpl,
|
|
11
15
|
ClientCredentialsOAuth,
|
|
12
16
|
CoinListTokenSaleNamespaceImpl,
|
|
17
|
+
EpochMillis,
|
|
13
18
|
Erc20NamespaceImpl,
|
|
14
19
|
HttpError,
|
|
20
|
+
Millis,
|
|
15
21
|
NotAuthenticatedError,
|
|
16
22
|
OAuthSession,
|
|
17
23
|
OndoNamespaceImpl,
|
|
18
24
|
PUBLIC_API_BASE_URL,
|
|
19
25
|
RequirementsNamespaceImpl,
|
|
26
|
+
Seconds,
|
|
20
27
|
SuperstateSwapNamespaceImpl,
|
|
28
|
+
TokenTrigger,
|
|
21
29
|
TokensNamespaceImpl,
|
|
22
30
|
WalletsNamespaceImpl,
|
|
23
31
|
fetchOfferDetails,
|
|
24
32
|
fetchOfferRequirements,
|
|
25
33
|
fetchOffers,
|
|
26
34
|
fetchOffersPage,
|
|
27
|
-
internalLogger
|
|
28
|
-
|
|
35
|
+
internalLogger,
|
|
36
|
+
isExpired,
|
|
37
|
+
isRejectedToken
|
|
38
|
+
} from "../chunk-C6GF7MDF.js";
|
|
29
39
|
|
|
30
40
|
// src/server/core/api/api-client.ts
|
|
31
41
|
var ApiClient = class {
|
|
@@ -42,6 +52,107 @@ var ApiClient = class {
|
|
|
42
52
|
}
|
|
43
53
|
};
|
|
44
54
|
|
|
55
|
+
// src/server/core/session-refresh.ts
|
|
56
|
+
var VERDICT_MIN_GAP = Millis.of(5e3);
|
|
57
|
+
var REJECTION_MEMORY = Millis.of(6e4);
|
|
58
|
+
var RefreshKey = {
|
|
59
|
+
of: ({
|
|
60
|
+
clientId,
|
|
61
|
+
session
|
|
62
|
+
}) => {
|
|
63
|
+
const identity = session.refreshToken === void 0 ? ["access", session.accessToken.value] : ["refresh", session.refreshToken];
|
|
64
|
+
return JSON.stringify([clientId, ...identity]);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
var RefreshCoordinator = class {
|
|
68
|
+
constructor(env = systemTime) {
|
|
69
|
+
this.env = env;
|
|
70
|
+
this.inFlight = /* @__PURE__ */ new Map();
|
|
71
|
+
this.rejections = /* @__PURE__ */ new Map();
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Runs `exchange` for `key` unless one is already in flight, in which case
|
|
75
|
+
* the caller joins it. `joined` tells the caller whether it led: only the
|
|
76
|
+
* leader reports the outcome, so a burst of N produces one verdict, one log
|
|
77
|
+
* line and one `onSessionExpired`.
|
|
78
|
+
*/
|
|
79
|
+
refresh(key, exchange) {
|
|
80
|
+
const existing = this.inFlight.get(key);
|
|
81
|
+
if (existing !== void 0) {
|
|
82
|
+
return { outcome: existing, joined: true };
|
|
83
|
+
}
|
|
84
|
+
const outcome = this.run(key, exchange).finally(() => {
|
|
85
|
+
this.inFlight.delete(key);
|
|
86
|
+
});
|
|
87
|
+
this.inFlight.set(key, outcome);
|
|
88
|
+
return { outcome, joined: false };
|
|
89
|
+
}
|
|
90
|
+
async run(key, exchange) {
|
|
91
|
+
this.forgetStale(this.env.time.now());
|
|
92
|
+
if (this.rejections.get(key)?.type === "expired") {
|
|
93
|
+
return { type: "already-expired" };
|
|
94
|
+
}
|
|
95
|
+
const result = await exchange();
|
|
96
|
+
switch (result.type) {
|
|
97
|
+
case "renewed":
|
|
98
|
+
case "unknown":
|
|
99
|
+
return result;
|
|
100
|
+
case "rejected":
|
|
101
|
+
case "unrenewable": {
|
|
102
|
+
const judged = judge({
|
|
103
|
+
result: result.type,
|
|
104
|
+
prior: this.rejections.get(key),
|
|
105
|
+
now: this.env.time.now()
|
|
106
|
+
});
|
|
107
|
+
this.rejections.set(key, judged.memory);
|
|
108
|
+
return { type: judged.outcome };
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
forgetStale(now) {
|
|
113
|
+
for (const [key, rejection] of this.rejections) {
|
|
114
|
+
if (EpochMillis.elapsed(rejectedAt(rejection), now) > REJECTION_MEMORY) {
|
|
115
|
+
this.rejections.delete(key);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
function judge({
|
|
121
|
+
result,
|
|
122
|
+
prior,
|
|
123
|
+
now
|
|
124
|
+
}) {
|
|
125
|
+
const verdict = {
|
|
126
|
+
outcome: "expired",
|
|
127
|
+
memory: { type: "expired", at: now }
|
|
128
|
+
};
|
|
129
|
+
switch (result) {
|
|
130
|
+
case "unrenewable":
|
|
131
|
+
return verdict;
|
|
132
|
+
case "rejected":
|
|
133
|
+
switch (prior?.type) {
|
|
134
|
+
case void 0:
|
|
135
|
+
return {
|
|
136
|
+
outcome: "suspected",
|
|
137
|
+
memory: { type: "suspected", since: now }
|
|
138
|
+
};
|
|
139
|
+
case "suspected":
|
|
140
|
+
return EpochMillis.elapsed(prior.since, now) >= VERDICT_MIN_GAP ? verdict : { outcome: "suspected", memory: prior };
|
|
141
|
+
case "expired":
|
|
142
|
+
return { outcome: "expired", memory: prior };
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function rejectedAt(rejection) {
|
|
147
|
+
switch (rejection.type) {
|
|
148
|
+
case "suspected":
|
|
149
|
+
return rejection.since;
|
|
150
|
+
case "expired":
|
|
151
|
+
return rejection.at;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
var processRefreshCoordinator = new RefreshCoordinator();
|
|
155
|
+
|
|
45
156
|
// src/server/shared/errors.ts
|
|
46
157
|
var WritableSessionStoreRequiredError = class extends Error {
|
|
47
158
|
constructor(message = "This operation requires a writable SessionStore. Provide a `setSession` implementation in your SessionStore to persist or clear OAuth sessions.") {
|
|
@@ -50,10 +161,7 @@ var WritableSessionStoreRequiredError = class extends Error {
|
|
|
50
161
|
}
|
|
51
162
|
};
|
|
52
163
|
|
|
53
|
-
// src/server/core/server-auth-namespace.ts
|
|
54
|
-
function emptySessionStore() {
|
|
55
|
-
return { getSession: async () => null };
|
|
56
|
-
}
|
|
164
|
+
// src/server/core/server-auth-namespace-impl.ts
|
|
57
165
|
var ServerAuthNamespaceImpl = class {
|
|
58
166
|
constructor(api, config) {
|
|
59
167
|
this.api = api;
|
|
@@ -73,7 +181,8 @@ var ServerAuthNamespaceImpl = class {
|
|
|
73
181
|
client_id: this.config.clientId,
|
|
74
182
|
client_secret: this.config.clientSecret,
|
|
75
183
|
code_verifier: params.codeVerifier
|
|
76
|
-
}
|
|
184
|
+
},
|
|
185
|
+
attributes: Attributes.notRetryable()
|
|
77
186
|
});
|
|
78
187
|
const session = OAuthSession.fromDto(sessionDto);
|
|
79
188
|
await setSession(session);
|
|
@@ -81,39 +190,118 @@ var ServerAuthNamespaceImpl = class {
|
|
|
81
190
|
});
|
|
82
191
|
}
|
|
83
192
|
async getAccessToken() {
|
|
193
|
+
return this.tokenFor(TokenTrigger.beforeRequest);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* {@link getAccessToken} with the reason the SDK is asking, which is what
|
|
197
|
+
* the authenticated HTTP pipeline calls: after a 401 the token's own expiry
|
|
198
|
+
* no longer matters, because the API has answered for it.
|
|
199
|
+
*/
|
|
200
|
+
async tokenFor(trigger) {
|
|
84
201
|
return this.log.wrap(
|
|
85
202
|
"getAccessToken",
|
|
86
203
|
void 0,
|
|
87
|
-
() => this.readAccessToken()
|
|
204
|
+
() => this.readAccessToken(trigger)
|
|
88
205
|
);
|
|
89
206
|
}
|
|
90
|
-
async readAccessToken() {
|
|
207
|
+
async readAccessToken(trigger) {
|
|
91
208
|
const sessionStore = this.config.sessionStore;
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
209
|
+
const classification = classifyAccessToken({
|
|
210
|
+
session: await sessionStore.getSession(),
|
|
211
|
+
store: sessionStoreAccess(sessionStore),
|
|
212
|
+
trigger,
|
|
213
|
+
now: this.config.time.now(),
|
|
214
|
+
buffer: Seconds.toMillis(this.config.accessTokenExpiryBufferSeconds)
|
|
215
|
+
});
|
|
216
|
+
switch (classification.type) {
|
|
217
|
+
case "no-session":
|
|
218
|
+
case "refuse":
|
|
219
|
+
return null;
|
|
220
|
+
case "serve":
|
|
221
|
+
return classification.token;
|
|
222
|
+
case "serve-stale":
|
|
223
|
+
this.log.child({ op: "getAccessToken" }).warn(() => ({
|
|
224
|
+
msg: "serving an expired token: the session store is read-only, so it cannot be refreshed"
|
|
225
|
+
}));
|
|
226
|
+
return classification.token;
|
|
227
|
+
case "refresh":
|
|
228
|
+
return this.refresh(classification);
|
|
106
229
|
}
|
|
107
|
-
return this.refreshSession(session.refreshToken, setSession);
|
|
108
230
|
}
|
|
109
|
-
|
|
231
|
+
/**
|
|
232
|
+
* Refreshes through the process-wide coordinator, then acts on the outcome
|
|
233
|
+
* for this caller's own store. The store is written before anything is
|
|
234
|
+
* logged or the host is notified, so `onSessionExpired` always finds it
|
|
235
|
+
* cleared.
|
|
236
|
+
*/
|
|
237
|
+
async refresh({
|
|
238
|
+
session,
|
|
239
|
+
setSession,
|
|
240
|
+
fallback
|
|
241
|
+
}) {
|
|
110
242
|
const log = this.log.child({ op: "refresh" });
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
243
|
+
const key = RefreshKey.of({ clientId: this.config.clientId, session });
|
|
244
|
+
const { outcome, joined } = this.config.refreshes.refresh(
|
|
245
|
+
key,
|
|
246
|
+
() => this.exchange(session.refreshToken)
|
|
247
|
+
);
|
|
248
|
+
if (joined) {
|
|
249
|
+
log.debug(() => ({ msg: "joined a refresh already in flight" }));
|
|
250
|
+
}
|
|
251
|
+
const result = await outcome;
|
|
252
|
+
switch (result.type) {
|
|
253
|
+
case "renewed":
|
|
254
|
+
await setSession(result.session);
|
|
255
|
+
if (!joined) {
|
|
256
|
+
log.info(() => ({ msg: "session renewed" }));
|
|
257
|
+
}
|
|
258
|
+
return result.session.accessToken;
|
|
259
|
+
case "suspected":
|
|
260
|
+
if (!joined) {
|
|
261
|
+
log.warn(() => ({
|
|
262
|
+
msg: "refresh rejected; not clearing until it is confirmed"
|
|
263
|
+
}));
|
|
264
|
+
}
|
|
265
|
+
return fallback;
|
|
266
|
+
case "expired":
|
|
267
|
+
await setSession(null);
|
|
268
|
+
if (!joined) {
|
|
269
|
+
log.info(() => ({
|
|
270
|
+
msg: "session expired",
|
|
271
|
+
fields: {
|
|
272
|
+
reason: session.refreshToken === void 0 ? "no-refresh-token" : "refresh-rejected"
|
|
273
|
+
}
|
|
274
|
+
}));
|
|
275
|
+
notifySessionExpired(this.config.onSessionExpired, log);
|
|
276
|
+
}
|
|
277
|
+
return null;
|
|
278
|
+
case "already-expired":
|
|
279
|
+
await setSession(null);
|
|
280
|
+
return null;
|
|
281
|
+
case "unknown":
|
|
282
|
+
if (fallback === null) {
|
|
283
|
+
throw result.error;
|
|
284
|
+
}
|
|
285
|
+
if (!joined) {
|
|
286
|
+
log.warning(
|
|
287
|
+
() => ({ msg: "refresh failed; serving the current token" }),
|
|
288
|
+
result.error
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
return fallback;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* One `POST /oauth/token`, total: every failure comes back as a value, so
|
|
296
|
+
* the coordinator can judge it once for everyone who joined.
|
|
297
|
+
*
|
|
298
|
+
* Never retried. The refresh token is single-use, so a retry of an attempt
|
|
299
|
+
* that reached the server would present a token already rotated away, and
|
|
300
|
+
* its `invalid_grant` would be judged as a rejection of the session.
|
|
301
|
+
*/
|
|
302
|
+
async exchange(refreshToken) {
|
|
303
|
+
if (refreshToken === void 0) {
|
|
304
|
+
return { type: "unrenewable" };
|
|
117
305
|
}
|
|
118
306
|
try {
|
|
119
307
|
const sessionDto = await this.api.send({
|
|
@@ -124,19 +312,12 @@ var ServerAuthNamespaceImpl = class {
|
|
|
124
312
|
refresh_token: refreshToken,
|
|
125
313
|
client_id: this.config.clientId,
|
|
126
314
|
client_secret: this.config.clientSecret
|
|
127
|
-
}
|
|
315
|
+
},
|
|
316
|
+
attributes: Attributes.notRetryable()
|
|
128
317
|
});
|
|
129
|
-
|
|
130
|
-
await setSession(newSession);
|
|
131
|
-
log.info(() => ({ msg: "session renewed" }));
|
|
132
|
-
return newSession.accessToken;
|
|
318
|
+
return { type: "renewed", session: OAuthSession.fromDto(sessionDto) };
|
|
133
319
|
} catch (error) {
|
|
134
|
-
|
|
135
|
-
() => ({ msg: "refresh failed; clearing the session" }),
|
|
136
|
-
error
|
|
137
|
-
);
|
|
138
|
-
await setSession(null);
|
|
139
|
-
return null;
|
|
320
|
+
return isInvalidGrant(error) ? { type: "rejected" } : { type: "unknown", error };
|
|
140
321
|
}
|
|
141
322
|
}
|
|
142
323
|
async clientCredentials() {
|
|
@@ -172,28 +353,102 @@ var ServerAuthNamespaceImpl = class {
|
|
|
172
353
|
}
|
|
173
354
|
});
|
|
174
355
|
} catch (err) {
|
|
175
|
-
if (
|
|
356
|
+
if (this.config.strict) {
|
|
176
357
|
throw err;
|
|
177
358
|
}
|
|
178
|
-
this.log.child({ op: "logout" }).
|
|
179
|
-
msg: "
|
|
180
|
-
|
|
359
|
+
this.log.child({ op: "logout" }).warning(
|
|
360
|
+
() => ({ msg: "revoke failed; local session cleared regardless" }),
|
|
361
|
+
err
|
|
362
|
+
);
|
|
181
363
|
}
|
|
182
364
|
await setSession(null);
|
|
183
365
|
}
|
|
184
366
|
/**
|
|
185
|
-
* Returns the store's `setSession`, or throws
|
|
367
|
+
* Returns the store's `setSession`, or throws - the guard every
|
|
186
368
|
* session-writing operation shares.
|
|
187
369
|
*/
|
|
188
370
|
writableSessionStore() {
|
|
189
|
-
const
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
371
|
+
const store = sessionStoreAccess(this.config.sessionStore);
|
|
372
|
+
switch (store.type) {
|
|
373
|
+
case "writable":
|
|
374
|
+
return store.setSession;
|
|
375
|
+
case "read-only":
|
|
376
|
+
throw new WritableSessionStoreRequiredError();
|
|
193
377
|
}
|
|
194
|
-
return setSession;
|
|
195
378
|
}
|
|
196
379
|
};
|
|
380
|
+
function classifyAccessToken({
|
|
381
|
+
session,
|
|
382
|
+
store,
|
|
383
|
+
trigger,
|
|
384
|
+
now,
|
|
385
|
+
buffer
|
|
386
|
+
}) {
|
|
387
|
+
if (session === null) {
|
|
388
|
+
return { type: "no-session" };
|
|
389
|
+
}
|
|
390
|
+
const token = session.accessToken;
|
|
391
|
+
const stale = isExpired({
|
|
392
|
+
expiresAt: EpochMillis.fromDate(token.expiresAt),
|
|
393
|
+
now,
|
|
394
|
+
buffer
|
|
395
|
+
});
|
|
396
|
+
switch (store.type) {
|
|
397
|
+
case "read-only":
|
|
398
|
+
return classifyReadOnly(token, trigger, stale);
|
|
399
|
+
case "writable": {
|
|
400
|
+
if (!needsRefresh(token, trigger, stale)) {
|
|
401
|
+
return { type: "serve", token };
|
|
402
|
+
}
|
|
403
|
+
const fallback = fallbackToken(token, trigger, now);
|
|
404
|
+
return session.refreshToken === void 0 && fallback !== null ? { type: "serve", token: fallback } : {
|
|
405
|
+
type: "refresh",
|
|
406
|
+
session,
|
|
407
|
+
setSession: store.setSession,
|
|
408
|
+
fallback
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
function classifyReadOnly(token, trigger, stale) {
|
|
414
|
+
switch (trigger.type) {
|
|
415
|
+
case "after-401":
|
|
416
|
+
return isRejectedToken(token, trigger.rejected) ? { type: "refuse" } : { type: "serve", token };
|
|
417
|
+
case "before-request":
|
|
418
|
+
return stale ? { type: "serve-stale", token } : { type: "serve", token };
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
function sessionStoreAccess(sessionStore) {
|
|
422
|
+
const setSession = sessionStore.setSession?.bind(sessionStore);
|
|
423
|
+
return setSession === void 0 ? { type: "read-only" } : { type: "writable", setSession };
|
|
424
|
+
}
|
|
425
|
+
function needsRefresh(token, trigger, stale) {
|
|
426
|
+
switch (trigger.type) {
|
|
427
|
+
case "before-request":
|
|
428
|
+
return stale;
|
|
429
|
+
case "after-401":
|
|
430
|
+
return trigger.rejected.type === "no-user-token" || isRejectedToken(token, trigger.rejected) || stale;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
function fallbackToken(token, trigger, now) {
|
|
434
|
+
const unexpired = !isExpired({
|
|
435
|
+
expiresAt: EpochMillis.fromDate(token.expiresAt),
|
|
436
|
+
now
|
|
437
|
+
});
|
|
438
|
+
switch (trigger.type) {
|
|
439
|
+
case "after-401":
|
|
440
|
+
return unexpired && !isRejectedToken(token, trigger.rejected) ? token : null;
|
|
441
|
+
case "before-request":
|
|
442
|
+
return unexpired ? token : null;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
function isInvalidGrant(error) {
|
|
446
|
+
if (!(error instanceof HttpError) || error.response.status !== 400) {
|
|
447
|
+
return false;
|
|
448
|
+
}
|
|
449
|
+
const body = error.response.body;
|
|
450
|
+
return typeof body === "object" && body !== null && "error" in body && body.error === "invalid_grant";
|
|
451
|
+
}
|
|
197
452
|
|
|
198
453
|
// src/server/core/server-offers-namespace.ts
|
|
199
454
|
var ServerOffersNamespaceImpl = class {
|
|
@@ -240,28 +495,26 @@ var ServerRequirementsNamespaceImpl = class extends RequirementsNamespaceImpl {
|
|
|
240
495
|
};
|
|
241
496
|
|
|
242
497
|
// src/server/core/coinlist-server.ts
|
|
243
|
-
var
|
|
498
|
+
var ACCESS_TOKEN_EXPIRY_BUFFER = Seconds.of(60);
|
|
244
499
|
var CoinListServerImpl = class {
|
|
245
500
|
constructor(_config) {
|
|
246
|
-
this._config = _config;
|
|
247
501
|
const logger = _config.logger ?? null;
|
|
248
502
|
this.api = new ApiClient(
|
|
249
503
|
{
|
|
250
504
|
baseUrl: _config.baseUrl ?? PUBLIC_API_BASE_URL,
|
|
251
505
|
xApiVersion: API_VERSION
|
|
252
506
|
},
|
|
253
|
-
|
|
254
|
-
// fresh token. A read-only store cannot persist a new session, so return
|
|
255
|
-
// null immediately — this tells the middleware to skip the retry rather
|
|
256
|
-
// than re-sending with the same expired token and wasting a round-trip.
|
|
257
|
-
(refresh) => refresh && !this._config.sessionStore.setSession ? Promise.resolve(null) : this.auth.getAccessToken(),
|
|
507
|
+
(trigger) => auth.tokenFor(trigger),
|
|
258
508
|
logger
|
|
259
509
|
);
|
|
260
|
-
|
|
510
|
+
const auth = new ServerAuthNamespaceImpl(this.api, {
|
|
261
511
|
..._config,
|
|
262
|
-
accessTokenExpiryBufferSeconds: _config.accessTokenExpiryBufferSeconds ??
|
|
263
|
-
strict: _config.strict ?? false
|
|
512
|
+
accessTokenExpiryBufferSeconds: _config.accessTokenExpiryBufferSeconds ?? ACCESS_TOKEN_EXPIRY_BUFFER,
|
|
513
|
+
strict: _config.strict ?? false,
|
|
514
|
+
refreshes: processRefreshCoordinator,
|
|
515
|
+
...systemTime
|
|
264
516
|
});
|
|
517
|
+
this.auth = auth;
|
|
265
518
|
const ctx = {
|
|
266
519
|
api: this.api,
|
|
267
520
|
rpc: publicClients(this.api, _config.rpc, _config.logger ?? null),
|
|
@@ -276,6 +529,7 @@ var CoinListServerImpl = class {
|
|
|
276
529
|
this.tokenSale = new CoinListTokenSaleNamespaceImpl(ctx);
|
|
277
530
|
this.superstate = new SuperstateSwapNamespaceImpl(ctx);
|
|
278
531
|
this.ondo = new OndoNamespaceImpl(ctx);
|
|
532
|
+
this.centrifuge = new CentrifugeNamespaceImpl(ctx);
|
|
279
533
|
this.tokens = new TokensNamespaceImpl(
|
|
280
534
|
_config.tokensBaseUrl ?? NABU_BASE_URL,
|
|
281
535
|
logger
|
|
@@ -311,8 +565,12 @@ function pinoServerLogger(options) {
|
|
|
311
565
|
options.level
|
|
312
566
|
);
|
|
313
567
|
}
|
|
568
|
+
|
|
569
|
+
// src/server/core/server-auth-namespace.ts
|
|
570
|
+
function emptySessionStore() {
|
|
571
|
+
return { getSession: async () => null };
|
|
572
|
+
}
|
|
314
573
|
export {
|
|
315
|
-
ServerAuthNamespaceImpl,
|
|
316
574
|
ServerOffersNamespaceImpl,
|
|
317
575
|
ServerRequirementsNamespaceImpl,
|
|
318
576
|
WritableSessionStoreRequiredError,
|