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