@coinlist-co/react 0.12.2-rc.7b430dd → 0.12.2-rc.a59b344
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-4IZ2F732.js} +52 -19
- package/dist/chunk-4IZ2F732.js.map +1 -0
- package/dist/{chunk-MOE5S6CE.js → chunk-NBO5E2RO.js} +152 -6
- package/dist/chunk-NBO5E2RO.js.map +1 -0
- package/dist/{chunk-VH34YC3Q.js → chunk-UJYSXXJF.js} +168 -3
- package/dist/chunk-UJYSXXJF.js.map +1 -0
- package/dist/client/index.cjs +469 -145
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +114 -35
- package/dist/client/index.d.ts +114 -35
- package/dist/client/index.js +297 -114
- package/dist/client/index.js.map +1 -1
- package/dist/server/index.cjs +507 -116
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +65 -41
- package/dist/server/index.d.ts +65 -41
- package/dist/server/index.js +321 -65
- package/dist/server/index.js.map +1 -1
- package/dist/time-CFocgYyl.d.cts +50 -0
- package/dist/time-DvgN98Q9.d.ts +50 -0
- package/dist/{token-registry-snapshot-BNBNuDu1.d.ts → token-registry-snapshot-BsAfBL_b.d.ts} +9 -7
- package/dist/{token-registry-snapshot-CqI6dXM_.d.cts → token-registry-snapshot-Cc_eA5zM.d.cts} +9 -7
- package/dist/{tokens-namespace-CIWBtgt2.d.cts → tokens-namespace-D_XSpiS-.d.cts} +154 -19
- package/dist/{tokens-namespace-CIWBtgt2.d.ts → tokens-namespace-D_XSpiS-.d.ts} +154 -19
- package/dist/universal/index.cjs +333 -40
- package/dist/universal/index.cjs.map +1 -1
- package/dist/universal/index.d.cts +358 -5
- package/dist/universal/index.d.ts +358 -5
- package/dist/universal/index.js +28 -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/client/index.cjs
CHANGED
|
@@ -71,6 +71,7 @@ __export(client_exports, {
|
|
|
71
71
|
OndoBuyOrderConfirmed: () => OndoBuyOrderConfirmed,
|
|
72
72
|
OndoBuyReviewView: () => OndoBuyReviewView,
|
|
73
73
|
OndoCheckoutError: () => OndoCheckoutError,
|
|
74
|
+
OndoCheckoutErrorReason: () => OndoCheckoutErrorReason,
|
|
74
75
|
OndoSellAmountView: () => OndoSellAmountView,
|
|
75
76
|
OndoSellCheckoutContainer: () => OndoSellCheckoutContainer,
|
|
76
77
|
OndoSellCheckoutView: () => OndoSellCheckoutView,
|
|
@@ -110,6 +111,7 @@ __export(client_exports, {
|
|
|
110
111
|
formatCountdown: () => formatCountdown,
|
|
111
112
|
formatMonthYear: () => formatMonthYear,
|
|
112
113
|
formatSaleCardCountdown: () => formatSaleCardCountdown,
|
|
114
|
+
isNotTradable: () => isNotTradable,
|
|
113
115
|
offerAssetIconUrl: () => offerAssetIconUrl,
|
|
114
116
|
offerIconUrl: () => offerIconUrl,
|
|
115
117
|
offerTokenIdentifier: () => offerTokenIdentifier,
|
|
@@ -248,6 +250,30 @@ var VERIFY_IDENTITY_PATH = "/verify-identity";
|
|
|
248
250
|
var VERIFY_IDENTITY_ACCREDITATION_PATH = "/verify-identity/accreditation_full";
|
|
249
251
|
var WALLET_PATH = "/wallet";
|
|
250
252
|
|
|
253
|
+
// src/universal/api/internal-access-token-source.ts
|
|
254
|
+
var SentWith = {
|
|
255
|
+
userToken: (token) => ({
|
|
256
|
+
type: "user-token",
|
|
257
|
+
token
|
|
258
|
+
}),
|
|
259
|
+
noUserToken: { type: "no-user-token" }
|
|
260
|
+
};
|
|
261
|
+
var TokenTrigger = {
|
|
262
|
+
beforeRequest: { type: "before-request" },
|
|
263
|
+
after401: (rejected) => ({
|
|
264
|
+
type: "after-401",
|
|
265
|
+
rejected
|
|
266
|
+
})
|
|
267
|
+
};
|
|
268
|
+
function isRejectedToken(token, rejected) {
|
|
269
|
+
switch (rejected.type) {
|
|
270
|
+
case "user-token":
|
|
271
|
+
return rejected.token.value === token.value;
|
|
272
|
+
case "no-user-token":
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
251
277
|
// src/universal/api/http-attributes.ts
|
|
252
278
|
var empty = {};
|
|
253
279
|
var concat = (left, right) => ({
|
|
@@ -275,6 +301,10 @@ var retryAttempt = (attempt) => ({
|
|
|
275
301
|
var renewAttempted = (value) => ({
|
|
276
302
|
renewAttempted: value
|
|
277
303
|
});
|
|
304
|
+
var notRetryable = () => ({ retryable: false });
|
|
305
|
+
var sentWith = (token) => ({
|
|
306
|
+
sentWith: token
|
|
307
|
+
});
|
|
278
308
|
var requestId = (id) => ({ requestId: id });
|
|
279
309
|
var getRequestId = (attrs) => attrs?.requestId ?? null;
|
|
280
310
|
var isProtected = (attrs) => attrs?.protected === true;
|
|
@@ -282,6 +312,8 @@ var needUserAgent = (attrs) => attrs?.userAgent === true;
|
|
|
282
312
|
var isIdempotent = (attrs) => attrs?.idempotencyKey === true;
|
|
283
313
|
var getRetryAttempt = (attrs) => attrs?.retryAttempt ?? 0;
|
|
284
314
|
var wasRenewAttempted = (attrs) => attrs?.renewAttempted === true;
|
|
315
|
+
var isRetryable = (attrs) => attrs?.retryable !== false;
|
|
316
|
+
var getSentWith = (attrs) => attrs?.sentWith === void 0 ? SentWith.noUserToken : SentWith.userToken(attrs.sentWith);
|
|
285
317
|
var getClientCredentials = (attrs) => attrs?.clientCredentials;
|
|
286
318
|
var Attributes = {
|
|
287
319
|
empty,
|
|
@@ -297,6 +329,10 @@ var Attributes = {
|
|
|
297
329
|
getRetryAttempt,
|
|
298
330
|
renewAttempted,
|
|
299
331
|
wasRenewAttempted,
|
|
332
|
+
notRetryable,
|
|
333
|
+
isRetryable,
|
|
334
|
+
sentWith,
|
|
335
|
+
getSentWith,
|
|
300
336
|
clientCredentials,
|
|
301
337
|
getClientCredentials,
|
|
302
338
|
requestId,
|
|
@@ -684,11 +720,18 @@ var HttpClient = class {
|
|
|
684
720
|
);
|
|
685
721
|
let response = await this.executeRequest(preparedRequest);
|
|
686
722
|
for (const middleware of this.middleware.afterRequest ?? []) {
|
|
723
|
+
let retried = false;
|
|
687
724
|
response = await middleware({
|
|
688
725
|
request: preparedRequest,
|
|
689
726
|
response,
|
|
690
|
-
retry: (nextRequest = preparedRequest) =>
|
|
727
|
+
retry: (nextRequest = preparedRequest) => {
|
|
728
|
+
retried = true;
|
|
729
|
+
return this.runRequestWithAfterMiddleware(nextRequest);
|
|
730
|
+
}
|
|
691
731
|
});
|
|
732
|
+
if (retried) {
|
|
733
|
+
return response;
|
|
734
|
+
}
|
|
692
735
|
}
|
|
693
736
|
return response;
|
|
694
737
|
}
|
|
@@ -821,23 +864,33 @@ function attachSessionMiddleware(fetchAccessToken) {
|
|
|
821
864
|
if (!Attributes.isProtected(request.attributes)) {
|
|
822
865
|
return request;
|
|
823
866
|
}
|
|
824
|
-
|
|
825
|
-
if (
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
867
|
+
const userToken = await fetchAccessToken(TokenTrigger.beforeRequest);
|
|
868
|
+
if (userToken !== null) {
|
|
869
|
+
return withBearer(
|
|
870
|
+
{
|
|
871
|
+
...request,
|
|
872
|
+
attributes: Attributes.concat(
|
|
873
|
+
request.attributes ?? Attributes.empty,
|
|
874
|
+
Attributes.sentWith(userToken)
|
|
875
|
+
)
|
|
876
|
+
},
|
|
877
|
+
userToken.value
|
|
878
|
+
);
|
|
830
879
|
}
|
|
831
|
-
|
|
832
|
-
|
|
880
|
+
const clientCreds = Attributes.getClientCredentials(request.attributes);
|
|
881
|
+
if (clientCreds) {
|
|
882
|
+
return withBearer(request, clientCreds.value);
|
|
883
|
+
}
|
|
884
|
+
return request;
|
|
885
|
+
};
|
|
886
|
+
}
|
|
887
|
+
function withBearer(request, token) {
|
|
888
|
+
return {
|
|
889
|
+
...request,
|
|
890
|
+
headers: {
|
|
891
|
+
...request.headers ?? {},
|
|
892
|
+
Authorization: `Bearer ${token}`
|
|
833
893
|
}
|
|
834
|
-
return {
|
|
835
|
-
...request,
|
|
836
|
-
headers: {
|
|
837
|
-
...request.headers ?? {},
|
|
838
|
-
Authorization: `Bearer ${accessToken.value}`
|
|
839
|
-
}
|
|
840
|
-
};
|
|
841
894
|
};
|
|
842
895
|
}
|
|
843
896
|
|
|
@@ -873,7 +926,7 @@ function getRetryDelayMs(attempt) {
|
|
|
873
926
|
function createRequestRetryMiddleware(options = {}) {
|
|
874
927
|
const delayFn = options.delayFn ?? defaultDelay;
|
|
875
928
|
return async ({ request, response, retry }) => {
|
|
876
|
-
if (!isRetryableStatus(response.status)) {
|
|
929
|
+
if (!isRetryableStatus(response.status) || !Attributes.isRetryable(request.attributes)) {
|
|
877
930
|
return response;
|
|
878
931
|
}
|
|
879
932
|
const currentAttempt = Attributes.getRetryAttempt(request.attributes);
|
|
@@ -906,7 +959,9 @@ function renewSessionMiddleware(fetchAccessToken) {
|
|
|
906
959
|
if (Attributes.wasRenewAttempted(request.attributes)) {
|
|
907
960
|
return response;
|
|
908
961
|
}
|
|
909
|
-
const newToken = await fetchAccessToken(
|
|
962
|
+
const newToken = await fetchAccessToken(
|
|
963
|
+
TokenTrigger.after401(Attributes.getSentWith(request.attributes))
|
|
964
|
+
);
|
|
910
965
|
if (newToken) {
|
|
911
966
|
const nextRequest = Request.concatAttributes(
|
|
912
967
|
request,
|
|
@@ -963,6 +1018,196 @@ var ApiClient = class {
|
|
|
963
1018
|
}
|
|
964
1019
|
};
|
|
965
1020
|
|
|
1021
|
+
// src/universal/core/auth/session-expired.ts
|
|
1022
|
+
function notifySessionExpired(onSessionExpired, log) {
|
|
1023
|
+
if (onSessionExpired === void 0) {
|
|
1024
|
+
return;
|
|
1025
|
+
}
|
|
1026
|
+
Promise.resolve().then(onSessionExpired).catch(
|
|
1027
|
+
(error) => log.failure(() => ({ msg: "onSessionExpired threw" }), error)
|
|
1028
|
+
);
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
// src/universal/types/time.ts
|
|
1032
|
+
var MAX_EPOCH_MILLIS = 864e13;
|
|
1033
|
+
var EpochMillis = {
|
|
1034
|
+
/**
|
|
1035
|
+
* @throws {@link ValidationError} unless `value` is an integer a `Date` can
|
|
1036
|
+
* represent: at most {@link MAX_EPOCH_MILLIS} either side of the epoch.
|
|
1037
|
+
*/
|
|
1038
|
+
of: (value) => {
|
|
1039
|
+
if (!Number.isInteger(value) || Math.abs(value) > MAX_EPOCH_MILLIS) {
|
|
1040
|
+
throw new ValidationError(
|
|
1041
|
+
`EpochMillis must be an integer within \xB1${MAX_EPOCH_MILLIS}, got ${value}`
|
|
1042
|
+
);
|
|
1043
|
+
}
|
|
1044
|
+
return value;
|
|
1045
|
+
},
|
|
1046
|
+
/** The wall clock. Code that needs the time takes a `TimeEff` instead. */
|
|
1047
|
+
now: () => EpochMillis.of(Date.now()),
|
|
1048
|
+
/** @throws {@link ValidationError} for an invalid `Date`. */
|
|
1049
|
+
fromDate: (date) => EpochMillis.of(date.getTime()),
|
|
1050
|
+
/** How long after `from` the instant `to` is; negative if it is before. */
|
|
1051
|
+
elapsed: (from, to) => Millis.of(to - from),
|
|
1052
|
+
plus: (at, duration) => EpochMillis.of(at + duration)
|
|
1053
|
+
};
|
|
1054
|
+
var Millis = {
|
|
1055
|
+
of: (value) => value
|
|
1056
|
+
};
|
|
1057
|
+
|
|
1058
|
+
// src/client/core/auth/client-access-token.ts
|
|
1059
|
+
var CONFIRM_DELAY = Millis.of(1e3);
|
|
1060
|
+
var Generation = {
|
|
1061
|
+
initial: 0,
|
|
1062
|
+
next: (generation) => generation + 1
|
|
1063
|
+
};
|
|
1064
|
+
var ClientAccessToken = class {
|
|
1065
|
+
constructor(env) {
|
|
1066
|
+
this.env = env;
|
|
1067
|
+
this.state = { type: "unknown" };
|
|
1068
|
+
this.hostCall = null;
|
|
1069
|
+
/**
|
|
1070
|
+
* Bumped by {@link clear}. A host call that started before a logout must not
|
|
1071
|
+
* log the user back in when it lands, so every write checks it first. A 401
|
|
1072
|
+
* that arrives after the logout never starts one: `'logged-out'` refuses it.
|
|
1073
|
+
*/
|
|
1074
|
+
this.generation = Generation.initial;
|
|
1075
|
+
this.log = internalLogger(env.logger, "AUTH").child({
|
|
1076
|
+
op: "getAccessToken"
|
|
1077
|
+
});
|
|
1078
|
+
}
|
|
1079
|
+
authState() {
|
|
1080
|
+
return this.state.type;
|
|
1081
|
+
}
|
|
1082
|
+
/**
|
|
1083
|
+
* Asks the host for the current token, whatever is cached.
|
|
1084
|
+
*
|
|
1085
|
+
* Never answers from a host call already in flight: one started before a
|
|
1086
|
+
* login (the mount's `init()`, racing the OAuth callback's) would hand back
|
|
1087
|
+
* the answer from before the session cookie existed. It waits for that call
|
|
1088
|
+
* to settle instead, so that call's verdict still lands, then asks afresh.
|
|
1089
|
+
* A logout while it waits still wins.
|
|
1090
|
+
*
|
|
1091
|
+
* @throws whatever the host's `getAccessToken` throws.
|
|
1092
|
+
*/
|
|
1093
|
+
async load() {
|
|
1094
|
+
const generation = this.generation;
|
|
1095
|
+
if (this.hostCall !== null) {
|
|
1096
|
+
await this.hostCall.catch(() => null);
|
|
1097
|
+
}
|
|
1098
|
+
await this.ask(SentWith.noUserToken, generation);
|
|
1099
|
+
return this.authState();
|
|
1100
|
+
}
|
|
1101
|
+
/**
|
|
1102
|
+
* The HTTP pipeline's token source: see {@link TokenTrigger}.
|
|
1103
|
+
*
|
|
1104
|
+
* @throws whatever the host's `getAccessToken` throws.
|
|
1105
|
+
*/
|
|
1106
|
+
async get(trigger) {
|
|
1107
|
+
const decision = decideToken(this.state, trigger);
|
|
1108
|
+
switch (decision.type) {
|
|
1109
|
+
case "serve":
|
|
1110
|
+
return decision.token;
|
|
1111
|
+
case "ask":
|
|
1112
|
+
return this.ask(decision.rejected, this.generation);
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
/** Forgets the token: `auth.logout()`. Never an expiry, so never notifies. */
|
|
1116
|
+
clear() {
|
|
1117
|
+
this.generation = Generation.next(this.generation);
|
|
1118
|
+
this.hostCall = null;
|
|
1119
|
+
this.state = { type: "logged-out" };
|
|
1120
|
+
}
|
|
1121
|
+
/**
|
|
1122
|
+
* A request that carried no user token was not refused for a token, so the
|
|
1123
|
+
* host's first answer stands. One that was is confirmed before it is
|
|
1124
|
+
* believed.
|
|
1125
|
+
*/
|
|
1126
|
+
async ask(rejected, generation) {
|
|
1127
|
+
if (generation !== this.generation) {
|
|
1128
|
+
return currentToken(this.state);
|
|
1129
|
+
}
|
|
1130
|
+
const first = await this.callHost();
|
|
1131
|
+
switch (rejected.type) {
|
|
1132
|
+
case "no-user-token":
|
|
1133
|
+
return this.commit(first, generation);
|
|
1134
|
+
case "user-token":
|
|
1135
|
+
return isFresh(first, rejected) ? this.commit(first, generation) : this.confirm(rejected, generation);
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
async confirm(rejected, generation) {
|
|
1139
|
+
this.log.warn(() => ({
|
|
1140
|
+
msg: "host returned no fresh token; asking again before signing out"
|
|
1141
|
+
}));
|
|
1142
|
+
await this.env.delay(CONFIRM_DELAY);
|
|
1143
|
+
const second = await this.callHost();
|
|
1144
|
+
return isFresh(second, rejected) ? this.commit(second, generation) : this.expire(generation);
|
|
1145
|
+
}
|
|
1146
|
+
/** The host's `getAccessToken`, joining a call already in flight. */
|
|
1147
|
+
callHost() {
|
|
1148
|
+
if (this.hostCall !== null) {
|
|
1149
|
+
this.log.debug(() => ({ msg: "joined a host call already in flight" }));
|
|
1150
|
+
return this.hostCall;
|
|
1151
|
+
}
|
|
1152
|
+
const call = (async () => this.env.getAccessToken())().finally(() => {
|
|
1153
|
+
if (this.hostCall === call) {
|
|
1154
|
+
this.hostCall = null;
|
|
1155
|
+
}
|
|
1156
|
+
});
|
|
1157
|
+
this.hostCall = call;
|
|
1158
|
+
return call;
|
|
1159
|
+
}
|
|
1160
|
+
commit(token, generation) {
|
|
1161
|
+
if (generation !== this.generation) {
|
|
1162
|
+
return currentToken(this.state);
|
|
1163
|
+
}
|
|
1164
|
+
this.state = token === null ? { type: "logged-out" } : { type: "logged-in", token };
|
|
1165
|
+
return token;
|
|
1166
|
+
}
|
|
1167
|
+
expire(generation) {
|
|
1168
|
+
if (generation !== this.generation) {
|
|
1169
|
+
return null;
|
|
1170
|
+
}
|
|
1171
|
+
const wasLoggedIn = this.state.type === "logged-in";
|
|
1172
|
+
this.state = { type: "logged-out" };
|
|
1173
|
+
if (wasLoggedIn) {
|
|
1174
|
+
this.log.info(() => ({ msg: "session expired" }));
|
|
1175
|
+
notifySessionExpired(this.env.onSessionExpired, this.log);
|
|
1176
|
+
}
|
|
1177
|
+
return null;
|
|
1178
|
+
}
|
|
1179
|
+
};
|
|
1180
|
+
function decideToken(state, trigger) {
|
|
1181
|
+
switch (trigger.type) {
|
|
1182
|
+
case "before-request":
|
|
1183
|
+
return state.type === "unknown" ? { type: "ask", rejected: SentWith.noUserToken } : { type: "serve", token: currentToken(state) };
|
|
1184
|
+
case "after-401":
|
|
1185
|
+
switch (state.type) {
|
|
1186
|
+
// A logout or an expiry verdict: only `load()` may log back in, so a
|
|
1187
|
+
// 401 to a request sent before it must not ask the host again.
|
|
1188
|
+
case "logged-out":
|
|
1189
|
+
return { type: "serve", token: null };
|
|
1190
|
+
// Another request may already have renewed since this one was sent.
|
|
1191
|
+
case "logged-in":
|
|
1192
|
+
return isRejectedToken(state.token, trigger.rejected) ? { type: "ask", rejected: trigger.rejected } : { type: "serve", token: state.token };
|
|
1193
|
+
case "unknown":
|
|
1194
|
+
return { type: "ask", rejected: trigger.rejected };
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
function currentToken(state) {
|
|
1199
|
+
switch (state.type) {
|
|
1200
|
+
case "logged-in":
|
|
1201
|
+
return state.token;
|
|
1202
|
+
case "unknown":
|
|
1203
|
+
case "logged-out":
|
|
1204
|
+
return null;
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
function isFresh(token, rejected) {
|
|
1208
|
+
return token !== null && !isRejectedToken(token, rejected);
|
|
1209
|
+
}
|
|
1210
|
+
|
|
966
1211
|
// src/universal/types/oauth.ts
|
|
967
1212
|
var AuthorizationCode = (value) => value;
|
|
968
1213
|
var CodeVerifier = (value) => value;
|
|
@@ -1361,40 +1606,6 @@ var Asset = {
|
|
|
1361
1606
|
})
|
|
1362
1607
|
};
|
|
1363
1608
|
|
|
1364
|
-
// src/universal/core/shared/utils/wire.ts
|
|
1365
|
-
function unknownTypeError(dto, model) {
|
|
1366
|
-
const type = dto.type;
|
|
1367
|
-
throw new ValidationError(
|
|
1368
|
-
`${model}.type: unknown type ${JSON.stringify(type)}`
|
|
1369
|
-
);
|
|
1370
|
-
}
|
|
1371
|
-
function requiredString(value, field) {
|
|
1372
|
-
const text = notBlankStringOrNull(value);
|
|
1373
|
-
if (text === null) {
|
|
1374
|
-
throw new ValidationError(
|
|
1375
|
-
`${field}: expected a non-blank string, got ${typeof value === "string" ? "a blank string" : String(value)}`
|
|
1376
|
-
);
|
|
1377
|
-
}
|
|
1378
|
-
return text;
|
|
1379
|
-
}
|
|
1380
|
-
function requiredDate(value, field) {
|
|
1381
|
-
const date = typeof value === "string" ? new Date(value) : null;
|
|
1382
|
-
if (date === null || Number.isNaN(date.getTime())) {
|
|
1383
|
-
throw new ValidationError(
|
|
1384
|
-
`${field}: expected a date, got ${JSON.stringify(value)}`
|
|
1385
|
-
);
|
|
1386
|
-
}
|
|
1387
|
-
return date;
|
|
1388
|
-
}
|
|
1389
|
-
function requiredArray(value, field) {
|
|
1390
|
-
if (!Array.isArray(value)) {
|
|
1391
|
-
throw new ValidationError(
|
|
1392
|
-
`${field}: expected an array, got ${typeof value}`
|
|
1393
|
-
);
|
|
1394
|
-
}
|
|
1395
|
-
return value;
|
|
1396
|
-
}
|
|
1397
|
-
|
|
1398
1609
|
// src/universal/types/blockchain/core.ts
|
|
1399
1610
|
var ETHEREUM_CHAINS = {
|
|
1400
1611
|
ethereum_mainnet: true,
|
|
@@ -1485,13 +1696,51 @@ var AssetSymbol = (value) => value;
|
|
|
1485
1696
|
var StablecoinSymbol = (value) => value;
|
|
1486
1697
|
var Bps = (value) => value;
|
|
1487
1698
|
|
|
1699
|
+
// src/universal/core/shared/utils/wire.ts
|
|
1700
|
+
function unknownTypeError(dto, model) {
|
|
1701
|
+
const type = dto.type;
|
|
1702
|
+
throw new ValidationError(
|
|
1703
|
+
`${model}.type: unknown type ${JSON.stringify(type)}`
|
|
1704
|
+
);
|
|
1705
|
+
}
|
|
1706
|
+
function requiredString(value, field) {
|
|
1707
|
+
const text = notBlankStringOrNull(value);
|
|
1708
|
+
if (text === null) {
|
|
1709
|
+
throw new ValidationError(
|
|
1710
|
+
`${field}: expected a non-blank string, got ${typeof value === "string" ? "a blank string" : String(value)}`
|
|
1711
|
+
);
|
|
1712
|
+
}
|
|
1713
|
+
return text;
|
|
1714
|
+
}
|
|
1715
|
+
function requiredDate(value, field) {
|
|
1716
|
+
const date = typeof value === "string" ? new Date(value) : null;
|
|
1717
|
+
if (date === null || Number.isNaN(date.getTime())) {
|
|
1718
|
+
throw new ValidationError(
|
|
1719
|
+
`${field}: expected a date, got ${JSON.stringify(value)}`
|
|
1720
|
+
);
|
|
1721
|
+
}
|
|
1722
|
+
return date;
|
|
1723
|
+
}
|
|
1724
|
+
function decimalOrNull(value) {
|
|
1725
|
+
return value === null ? null : DecimalString(value);
|
|
1726
|
+
}
|
|
1727
|
+
function requiredArray(value, field) {
|
|
1728
|
+
if (!Array.isArray(value)) {
|
|
1729
|
+
throw new ValidationError(
|
|
1730
|
+
`${field}: expected an array, got ${typeof value}`
|
|
1731
|
+
);
|
|
1732
|
+
}
|
|
1733
|
+
return value;
|
|
1734
|
+
}
|
|
1735
|
+
|
|
1488
1736
|
// src/universal/types/offer.ts
|
|
1489
1737
|
var OfferId = (value) => value;
|
|
1490
1738
|
var OfferSlug = (value) => value;
|
|
1491
1739
|
var OFFER_TYPES = {
|
|
1492
1740
|
"coinlist::token_sale": true,
|
|
1493
1741
|
"superstate::swap": true,
|
|
1494
|
-
"ondo::swap": true
|
|
1742
|
+
"ondo::swap": true,
|
|
1743
|
+
"centrifuge::vault": true
|
|
1495
1744
|
};
|
|
1496
1745
|
var isOfferType = (value) => Object.keys(OFFER_TYPES).includes(value);
|
|
1497
1746
|
var OfferEditorial = {
|
|
@@ -1533,6 +1782,7 @@ var Offer = {
|
|
|
1533
1782
|
// on the wire: copying them would hand every consumer a `startsAt` that
|
|
1534
1783
|
// is 1970 for one variant and a date for the others.
|
|
1535
1784
|
case "ondo::swap":
|
|
1785
|
+
case "centrifuge::vault":
|
|
1536
1786
|
return {
|
|
1537
1787
|
...base2,
|
|
1538
1788
|
type: dto.type,
|
|
@@ -1585,6 +1835,19 @@ var OfferSwapContract = {
|
|
|
1585
1835
|
address: EvmContractAddress(dto.address)
|
|
1586
1836
|
})
|
|
1587
1837
|
};
|
|
1838
|
+
var OfferVaultContract = {
|
|
1839
|
+
fromDto: (dto) => ({
|
|
1840
|
+
chain: Chain(dto.chain),
|
|
1841
|
+
address: EvmContractAddress(dto.address)
|
|
1842
|
+
}),
|
|
1843
|
+
/**
|
|
1844
|
+
* Drops every proxy on a chain this SDK does not name, as
|
|
1845
|
+
* `OfferToken.listFromDto` does: frontline publishes the full offer-token
|
|
1846
|
+
* chain list, which runs ahead of {@link Chain}, and one unmodelled chain
|
|
1847
|
+
* should not throw away the proxies the SDK can use.
|
|
1848
|
+
*/
|
|
1849
|
+
listFromDto: (dtos) => dtos.filter((dto) => isChain(dto.chain)).map(OfferVaultContract.fromDto)
|
|
1850
|
+
};
|
|
1588
1851
|
var OfferDetail = {
|
|
1589
1852
|
fromDto: (dto) => {
|
|
1590
1853
|
const fundingAssets = requiredArray(
|
|
@@ -1647,6 +1910,18 @@ var OfferDetail = {
|
|
|
1647
1910
|
"OfferDetail.swap_contracts"
|
|
1648
1911
|
).map(OfferSwapContract.fromDto)
|
|
1649
1912
|
};
|
|
1913
|
+
// No editorial, as for Ondo. `[]` is fine and a missing key is not, for
|
|
1914
|
+
// the same reason as `swap_contracts`: this is the spender a user
|
|
1915
|
+
// approves.
|
|
1916
|
+
case "centrifuge::vault":
|
|
1917
|
+
return {
|
|
1918
|
+
...base2,
|
|
1919
|
+
type: dto.type,
|
|
1920
|
+
logoUrl: notBlankStringOrNull(dto.logo_url),
|
|
1921
|
+
vaultContracts: OfferVaultContract.listFromDto(
|
|
1922
|
+
requiredArray(dto.vault_contracts, "OfferDetail.vault_contracts")
|
|
1923
|
+
)
|
|
1924
|
+
};
|
|
1650
1925
|
default:
|
|
1651
1926
|
return unknownTypeError(dto, "OfferDetail");
|
|
1652
1927
|
}
|
|
@@ -1919,6 +2194,12 @@ function assertPriceFits(raw) {
|
|
|
1919
2194
|
}
|
|
1920
2195
|
}
|
|
1921
2196
|
|
|
2197
|
+
// src/universal/core/checkout/ondo/not-tradable.ts
|
|
2198
|
+
var ONDO_NOT_TRADABLE_CODE = "not_tradable";
|
|
2199
|
+
function isOndoNotTradableError(error) {
|
|
2200
|
+
return apiErrorCode(error) === ONDO_NOT_TRADABLE_CODE;
|
|
2201
|
+
}
|
|
2202
|
+
|
|
1922
2203
|
// src/universal/core/shared/blockchain/formatters.ts
|
|
1923
2204
|
var import_viem3 = require("viem");
|
|
1924
2205
|
|
|
@@ -1939,7 +2220,11 @@ function formatAmount(amount, locale, options) {
|
|
|
1939
2220
|
const decimal = formatRawAmount(amount);
|
|
1940
2221
|
let [integerPart, fractionPart = ""] = decimal.split(".");
|
|
1941
2222
|
const maxFractionDigits = options?.maxFractionDigits;
|
|
1942
|
-
const minFractionDigits =
|
|
2223
|
+
const minFractionDigits = Math.min(
|
|
2224
|
+
options?.minFractionDigits ?? (maxFractionDigits !== void 0 ? maxFractionDigits : 2),
|
|
2225
|
+
maxFractionDigits ?? amount.decimals,
|
|
2226
|
+
amount.decimals
|
|
2227
|
+
);
|
|
1943
2228
|
if (maxFractionDigits !== void 0 && fractionPart.length > maxFractionDigits) {
|
|
1944
2229
|
({ integerPart, fractionPart } = roundFractionHalfUp(
|
|
1945
2230
|
integerPart,
|
|
@@ -1947,7 +2232,8 @@ function formatAmount(amount, locale, options) {
|
|
|
1947
2232
|
maxFractionDigits
|
|
1948
2233
|
));
|
|
1949
2234
|
}
|
|
1950
|
-
const
|
|
2235
|
+
const trimmed = fractionPart.replace(/0+$/, "");
|
|
2236
|
+
const fraction = trimmed.padEnd(minFractionDigits, "0");
|
|
1951
2237
|
const integerFormatted = BigInt(integerPart).toLocaleString(locale);
|
|
1952
2238
|
if (minFractionDigits === 0 && fraction === "") {
|
|
1953
2239
|
return FormattedAmountUi(integerFormatted);
|
|
@@ -2008,6 +2294,14 @@ function assetAmount(amount, symbol) {
|
|
|
2008
2294
|
return FormattedAmountAssetUi(`${amount} ${symbol}`);
|
|
2009
2295
|
}
|
|
2010
2296
|
var NA_AMOUNT_ASSET_UI = FormattedAmountAssetUi("-");
|
|
2297
|
+
var SHARE_MAX_FRACTION_DIGITS = AssetDecimals(6);
|
|
2298
|
+
var SHARE_MIN_FRACTION_DIGITS = AssetDecimals(2);
|
|
2299
|
+
function formatShareAmount(amount, locale) {
|
|
2300
|
+
return formatAmount(amount, locale, {
|
|
2301
|
+
maxFractionDigits: SHARE_MAX_FRACTION_DIGITS,
|
|
2302
|
+
minFractionDigits: SHARE_MIN_FRACTION_DIGITS
|
|
2303
|
+
});
|
|
2304
|
+
}
|
|
2011
2305
|
var USD_FRACTION_DIGITS = AssetDecimals(2);
|
|
2012
2306
|
function formattedUsdPrice(amount, locale) {
|
|
2013
2307
|
if (!amount) return NA_AMOUNT_ASSET_UI;
|
|
@@ -2146,7 +2440,6 @@ var OndoTradingStatus = {
|
|
|
2146
2440
|
};
|
|
2147
2441
|
}
|
|
2148
2442
|
};
|
|
2149
|
-
var decimalOrNull = (value) => value === null ? null : DecimalString(value);
|
|
2150
2443
|
var OndoQuote = {
|
|
2151
2444
|
fromDto: (dto) => {
|
|
2152
2445
|
const assetDecimals = AssetDecimals(dto.asset_decimals);
|
|
@@ -3877,7 +4170,9 @@ var TokenRegistrySnapshot = {
|
|
|
3877
4170
|
}
|
|
3878
4171
|
};
|
|
3879
4172
|
function offerDisplayTokens(offer) {
|
|
3880
|
-
const swaps = offer.tokens.filter(
|
|
4173
|
+
const swaps = offer.tokens.filter(
|
|
4174
|
+
(token) => token.role === "swap" || token.role === "vault"
|
|
4175
|
+
);
|
|
3881
4176
|
const distributions = offer.tokens.filter(
|
|
3882
4177
|
(token) => token.role === "distribution"
|
|
3883
4178
|
);
|
|
@@ -4951,37 +5246,46 @@ function transportFor(api, override, chain, logger) {
|
|
|
4951
5246
|
return typeof override === "string" ? (0, import_viem8.http)(override) : override;
|
|
4952
5247
|
}
|
|
4953
5248
|
|
|
5249
|
+
// src/universal/core/shared/effects.ts
|
|
5250
|
+
var systemTime = { time: { now: EpochMillis.now } };
|
|
5251
|
+
var systemDelay = {
|
|
5252
|
+
delay: (duration) => new Promise((resolve) => setTimeout(resolve, duration))
|
|
5253
|
+
};
|
|
5254
|
+
|
|
4954
5255
|
// src/client/core/coinlist-client.ts
|
|
4955
5256
|
var CoinListClientImpl = class {
|
|
4956
|
-
constructor(
|
|
4957
|
-
this.
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
5257
|
+
constructor(config) {
|
|
5258
|
+
this.config = config;
|
|
5259
|
+
const logger = config.logger ?? null;
|
|
5260
|
+
const accessToken = new ClientAccessToken({
|
|
5261
|
+
getAccessToken: () => config.getAccessToken(),
|
|
5262
|
+
onSessionExpired: config.onSessionExpired,
|
|
5263
|
+
logger,
|
|
5264
|
+
...systemDelay
|
|
5265
|
+
});
|
|
5266
|
+
this.accessToken = accessToken;
|
|
4961
5267
|
this.api = new ApiClient(
|
|
4962
5268
|
{
|
|
4963
|
-
baseUrl:
|
|
5269
|
+
baseUrl: config.baseUrl || PUBLIC_API_BASE_URL,
|
|
4964
5270
|
xApiVersion: API_VERSION
|
|
4965
5271
|
},
|
|
4966
|
-
|
|
5272
|
+
(trigger) => accessToken.get(trigger),
|
|
4967
5273
|
logger
|
|
4968
5274
|
);
|
|
4969
5275
|
const ctx = {
|
|
4970
5276
|
api: this.api,
|
|
4971
|
-
rpc: publicClients(this.api,
|
|
5277
|
+
rpc: publicClients(this.api, config.rpc, config.logger ?? null),
|
|
4972
5278
|
logger,
|
|
4973
5279
|
ensureUserAuthenticated: async () => this.ensureAuthenticated()
|
|
4974
5280
|
};
|
|
4975
|
-
this.auth = new ClientAuthNamespaceImpl(
|
|
4976
|
-
getState: () =>
|
|
4977
|
-
clearAccessToken: () =>
|
|
4978
|
-
this._accessToken = null;
|
|
4979
|
-
}
|
|
5281
|
+
this.auth = new ClientAuthNamespaceImpl(config, {
|
|
5282
|
+
getState: () => accessToken.authState(),
|
|
5283
|
+
clearAccessToken: () => accessToken.clear()
|
|
4980
5284
|
});
|
|
4981
5285
|
this.offers = new OffersNamespaceImpl(ctx);
|
|
4982
5286
|
this.requirements = new ClientRequirementsNamespaceImpl(
|
|
4983
5287
|
ctx,
|
|
4984
|
-
|
|
5288
|
+
config.coinlistBaseUrl
|
|
4985
5289
|
);
|
|
4986
5290
|
this.wallets = new WalletsNamespaceImpl(ctx);
|
|
4987
5291
|
this.erc20 = new Erc20NamespaceImpl(ctx);
|
|
@@ -4993,34 +5297,16 @@ var CoinListClientImpl = class {
|
|
|
4993
5297
|
);
|
|
4994
5298
|
this.ondo = new ClientOndoNamespaceImpl(ctx, this.erc20);
|
|
4995
5299
|
this.tokens = new TokensNamespaceImpl(
|
|
4996
|
-
|
|
5300
|
+
config.tokensBaseUrl ?? NABU_BASE_URL,
|
|
4997
5301
|
logger
|
|
4998
5302
|
);
|
|
4999
5303
|
this.support = new ClientSupportNamespaceImpl(logger);
|
|
5000
5304
|
}
|
|
5001
5305
|
async init() {
|
|
5002
|
-
|
|
5003
|
-
return this.getAuthState();
|
|
5004
|
-
}
|
|
5005
|
-
async fetchAccessToken(refresh) {
|
|
5006
|
-
if (!refresh && this._accessToken !== void 0) return this._accessToken;
|
|
5007
|
-
try {
|
|
5008
|
-
const accessToken = await this._config.getAccessToken();
|
|
5009
|
-
this._accessToken = accessToken;
|
|
5010
|
-
return accessToken;
|
|
5011
|
-
} catch (_) {
|
|
5012
|
-
this._accessToken = null;
|
|
5013
|
-
return null;
|
|
5014
|
-
}
|
|
5015
|
-
}
|
|
5016
|
-
getAuthState() {
|
|
5017
|
-
if (this._accessToken === void 0) {
|
|
5018
|
-
return "unknown";
|
|
5019
|
-
}
|
|
5020
|
-
return this._accessToken !== null ? "logged-in" : "logged-out";
|
|
5306
|
+
return this.accessToken.load();
|
|
5021
5307
|
}
|
|
5022
5308
|
ensureAuthenticated() {
|
|
5023
|
-
if (this.
|
|
5309
|
+
if (this.accessToken.authState() !== "logged-in") {
|
|
5024
5310
|
throw new NotAuthenticatedError();
|
|
5025
5311
|
}
|
|
5026
5312
|
}
|
|
@@ -6299,10 +6585,7 @@ function CheckoutConfirmationDialog({
|
|
|
6299
6585
|
}
|
|
6300
6586
|
)
|
|
6301
6587
|
] }),
|
|
6302
|
-
header
|
|
6303
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Divider, {}),
|
|
6304
|
-
header
|
|
6305
|
-
] }),
|
|
6588
|
+
header,
|
|
6306
6589
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Divider, {}),
|
|
6307
6590
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CheckoutDetailList, { rows }),
|
|
6308
6591
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "clcosdk:flex clcosdk:flex-col clcosdk:gap-3", children: actions })
|
|
@@ -6319,6 +6602,7 @@ function AssetSummaryRow({
|
|
|
6319
6602
|
iconSize = 48,
|
|
6320
6603
|
value,
|
|
6321
6604
|
caption,
|
|
6605
|
+
wrapIdentity = false,
|
|
6322
6606
|
className
|
|
6323
6607
|
}) {
|
|
6324
6608
|
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CoinListStyleScope, { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
@@ -6337,7 +6621,8 @@ function AssetSummaryRow({
|
|
|
6337
6621
|
{
|
|
6338
6622
|
className: cn(
|
|
6339
6623
|
typeClasses.h4,
|
|
6340
|
-
"clcosdk:
|
|
6624
|
+
"clcosdk:text-text-primary",
|
|
6625
|
+
wrapIdentity ? "clcosdk:break-words" : "clcosdk:truncate"
|
|
6341
6626
|
),
|
|
6342
6627
|
children: asset.name
|
|
6343
6628
|
}
|
|
@@ -6347,7 +6632,8 @@ function AssetSummaryRow({
|
|
|
6347
6632
|
{
|
|
6348
6633
|
className: cn(
|
|
6349
6634
|
typeClasses.subhead,
|
|
6350
|
-
"clcosdk:
|
|
6635
|
+
"clcosdk:text-text-secondary",
|
|
6636
|
+
wrapIdentity ? "clcosdk:break-words" : "clcosdk:truncate"
|
|
6351
6637
|
),
|
|
6352
6638
|
children: asset.symbol
|
|
6353
6639
|
}
|
|
@@ -6392,7 +6678,7 @@ function AssetSummaryRow({
|
|
|
6392
6678
|
// src/client/components/checkout/ondo/buy/confirmation/OndoBuyOrderConfirmed.tsx
|
|
6393
6679
|
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
6394
6680
|
var TITLE2 = "Order confirmed";
|
|
6395
|
-
var
|
|
6681
|
+
var SHARES_RECEIVED_LABEL = "Shares received";
|
|
6396
6682
|
var TOTAL_COST_LABEL = "Total cost";
|
|
6397
6683
|
var PRICE_PER_SHARE_LABEL = "Price per share";
|
|
6398
6684
|
var DELIVERED_TO_LABEL = "Delivered to";
|
|
@@ -6414,14 +6700,7 @@ function OndoBuyOrderConfirmed({
|
|
|
6414
6700
|
icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SuccessGlyph, {}),
|
|
6415
6701
|
title: TITLE2,
|
|
6416
6702
|
subtitle: subtitle(state.outputAsset.symbol),
|
|
6417
|
-
header: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
6418
|
-
AssetSummaryRow,
|
|
6419
|
-
{
|
|
6420
|
-
asset: state.outputAsset,
|
|
6421
|
-
value: state.outputAmount,
|
|
6422
|
-
caption: SHARES_RECEIVED_CAPTION
|
|
6423
|
-
}
|
|
6424
|
-
),
|
|
6703
|
+
header: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(AssetSummaryRow, { asset: state.outputAsset, wrapIdentity: true }),
|
|
6425
6704
|
rows: detailRows(state),
|
|
6426
6705
|
actions: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
6427
6706
|
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ClButton, { variant: "gradient", fullWidth: true, onClick: onClose, children: DONE_LABEL }),
|
|
@@ -6434,6 +6713,7 @@ function OndoBuyOrderConfirmed({
|
|
|
6434
6713
|
}
|
|
6435
6714
|
function detailRows(state) {
|
|
6436
6715
|
return [
|
|
6716
|
+
{ label: SHARES_RECEIVED_LABEL, value: state.outputAmount },
|
|
6437
6717
|
{ label: TOTAL_COST_LABEL, value: state.totalCost },
|
|
6438
6718
|
{ label: PRICE_PER_SHARE_LABEL, value: state.pricePerShare },
|
|
6439
6719
|
{ label: DELIVERED_TO_LABEL, value: state.recipientAddress }
|
|
@@ -6874,6 +7154,8 @@ function InfoIcon() {
|
|
|
6874
7154
|
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
6875
7155
|
var UNSUPPORTED_CHAIN_TITLE = "Not available on this network";
|
|
6876
7156
|
var UNSUPPORTED_CHAIN_DESCRIPTION = "Ondo orders cannot be placed on the selected network.";
|
|
7157
|
+
var NOT_TRADABLE_TITLE = "Trading is closed right now";
|
|
7158
|
+
var NOT_TRADABLE_DESCRIPTION = "This asset cannot be traded at the moment. Come back when the market opens.";
|
|
6877
7159
|
function OndoCheckoutError({
|
|
6878
7160
|
reason,
|
|
6879
7161
|
className
|
|
@@ -6915,6 +7197,8 @@ function title(reason) {
|
|
|
6915
7197
|
switch (reason) {
|
|
6916
7198
|
case "unsupported-chain":
|
|
6917
7199
|
return UNSUPPORTED_CHAIN_TITLE;
|
|
7200
|
+
case "not-tradable":
|
|
7201
|
+
return NOT_TRADABLE_TITLE;
|
|
6918
7202
|
default: {
|
|
6919
7203
|
const exhaustive = reason;
|
|
6920
7204
|
return exhaustive;
|
|
@@ -6925,6 +7209,8 @@ function description(reason) {
|
|
|
6925
7209
|
switch (reason) {
|
|
6926
7210
|
case "unsupported-chain":
|
|
6927
7211
|
return UNSUPPORTED_CHAIN_DESCRIPTION;
|
|
7212
|
+
case "not-tradable":
|
|
7213
|
+
return NOT_TRADABLE_DESCRIPTION;
|
|
6928
7214
|
default: {
|
|
6929
7215
|
const exhaustive = reason;
|
|
6930
7216
|
return exhaustive;
|
|
@@ -8053,7 +8339,9 @@ var import_react15 = require("react");
|
|
|
8053
8339
|
|
|
8054
8340
|
// src/client/hooks/checkout/ondo/shared/data/ondo-load-error.ts
|
|
8055
8341
|
function ondoLoadErrorReason(error) {
|
|
8056
|
-
|
|
8342
|
+
if (error instanceof NotAuthenticatedError) return "not-authenticated";
|
|
8343
|
+
if (isOndoNotTradableError(error)) return "not-tradable";
|
|
8344
|
+
return "generic-error";
|
|
8057
8345
|
}
|
|
8058
8346
|
|
|
8059
8347
|
// src/client/hooks/checkout/ondo/buy/data/useOndoBuyTransaction.ts
|
|
@@ -8238,7 +8526,7 @@ function useOndoBuyReviewViewModel({
|
|
|
8238
8526
|
tokenMetadata: outputTokenMetadata
|
|
8239
8527
|
}),
|
|
8240
8528
|
outputAmount: assetAmount(
|
|
8241
|
-
|
|
8529
|
+
formatShareAmount(built.receiveOutputAmount, locale),
|
|
8242
8530
|
ondoSymbol
|
|
8243
8531
|
),
|
|
8244
8532
|
recipientAddress: shortenAddress(active.wallet.address),
|
|
@@ -8358,6 +8646,8 @@ function refreshErrorMessage(reason) {
|
|
|
8358
8646
|
switch (reason) {
|
|
8359
8647
|
case "not-authenticated":
|
|
8360
8648
|
return "Sign in to refresh this quote.";
|
|
8649
|
+
case "not-tradable":
|
|
8650
|
+
return "Trading is paused for this asset. Try again when the market opens.";
|
|
8361
8651
|
case "generic-error":
|
|
8362
8652
|
return "Could not refresh the quote.";
|
|
8363
8653
|
default: {
|
|
@@ -8485,6 +8775,9 @@ function quoteSizeFromKey(key) {
|
|
|
8485
8775
|
|
|
8486
8776
|
// src/client/hooks/checkout/ondo/shared/data/useOndoTradingStatus.ts
|
|
8487
8777
|
var import_react19 = require("react");
|
|
8778
|
+
function isNotTradable(state) {
|
|
8779
|
+
return state.type === "CONTENT" && state.status.type === "not-tradable";
|
|
8780
|
+
}
|
|
8488
8781
|
var LOADING2 = { type: "LOADING" };
|
|
8489
8782
|
function useOndoTradingStatus(options) {
|
|
8490
8783
|
const {
|
|
@@ -8554,6 +8847,30 @@ function useOndoTradingStatus(options) {
|
|
|
8554
8847
|
return { state };
|
|
8555
8848
|
}
|
|
8556
8849
|
|
|
8850
|
+
// src/client/hooks/checkout/ondo/shared/ondo-checkout-error.types.ts
|
|
8851
|
+
var OndoCheckoutErrorReason = {
|
|
8852
|
+
/**
|
|
8853
|
+
* Which reason, if any, replaces the whole checkout. `null` means the steps
|
|
8854
|
+
* render.
|
|
8855
|
+
*
|
|
8856
|
+
* `unsupported-chain` wins because it is settled at mount: no market state
|
|
8857
|
+
* can make a chain with no contract tradable. `not-tradable` needs both a
|
|
8858
|
+
* market *known* to be closed and a user still at the start of the flow,
|
|
8859
|
+
* with no order confirmation on screen. Past the first step a pause belongs
|
|
8860
|
+
* to the step it interrupts, and a just-placed order's dialog must not be
|
|
8861
|
+
* hidden by a market that closed after it filled.
|
|
8862
|
+
*/
|
|
8863
|
+
of: ({
|
|
8864
|
+
swappableHere,
|
|
8865
|
+
notTradable,
|
|
8866
|
+
atEntry
|
|
8867
|
+
}) => {
|
|
8868
|
+
if (!swappableHere) return "unsupported-chain";
|
|
8869
|
+
if (notTradable && atEntry) return "not-tradable";
|
|
8870
|
+
return null;
|
|
8871
|
+
}
|
|
8872
|
+
};
|
|
8873
|
+
|
|
8557
8874
|
// src/client/hooks/checkout/ondo/shared/sidebar/useOndoSidebarViewModel.ts
|
|
8558
8875
|
var MARKET_OPEN = "Market open";
|
|
8559
8876
|
var MARKET_CLOSED2 = "Market closed";
|
|
@@ -8872,18 +9189,19 @@ function useOndoBuyCheckoutViewModel({
|
|
|
8872
9189
|
const [orderConfirmed, setOrderConfirmed] = (0, import_react22.useState)(null);
|
|
8873
9190
|
const swappableHere = swapSpender(offer.swapContracts, chain) !== null;
|
|
8874
9191
|
const live = enabled && swappableHere;
|
|
8875
|
-
const { state:
|
|
9192
|
+
const { state: tradingStatusState } = useOndoTradingStatus({
|
|
8876
9193
|
symbol: ondoSymbol,
|
|
8877
9194
|
side: "buy",
|
|
8878
|
-
size: priceSize(step),
|
|
8879
9195
|
pollIntervalMs: ONDO_POLL_INTERVAL_MS,
|
|
8880
9196
|
enabled: live
|
|
8881
9197
|
});
|
|
8882
|
-
const
|
|
9198
|
+
const notTradable = isNotTradable(tradingStatusState);
|
|
9199
|
+
const { state: priceState } = useOndoPrice({
|
|
8883
9200
|
symbol: ondoSymbol,
|
|
8884
9201
|
side: "buy",
|
|
9202
|
+
size: priceSize(step),
|
|
8885
9203
|
pollIntervalMs: ONDO_POLL_INTERVAL_MS,
|
|
8886
|
-
enabled: live
|
|
9204
|
+
enabled: live && !notTradable
|
|
8887
9205
|
});
|
|
8888
9206
|
const { state: outputTokenMetadataState } = useCheckoutOfferTokenMetadata({
|
|
8889
9207
|
offer,
|
|
@@ -8961,7 +9279,12 @@ function useOndoBuyCheckoutViewModel({
|
|
|
8961
9279
|
priceState,
|
|
8962
9280
|
tradingStatusState
|
|
8963
9281
|
});
|
|
8964
|
-
const
|
|
9282
|
+
const errorReason = OndoCheckoutErrorReason.of({
|
|
9283
|
+
swappableHere,
|
|
9284
|
+
notTradable,
|
|
9285
|
+
atEntry: step.type === "wallet" && orderConfirmed === null
|
|
9286
|
+
});
|
|
9287
|
+
const state = errorReason !== null ? { type: "error", reason: errorReason } : {
|
|
8965
9288
|
type: "content",
|
|
8966
9289
|
wallet: walletState,
|
|
8967
9290
|
amount: amountState,
|
|
@@ -9057,7 +9380,7 @@ function toOrderConfirmedUi({
|
|
|
9057
9380
|
tokenMetadata: outputTokenMetadata
|
|
9058
9381
|
}),
|
|
9059
9382
|
outputAmount: assetAmount(
|
|
9060
|
-
|
|
9383
|
+
formatShareAmount(order.transaction.receiveOutputAmount, locale),
|
|
9061
9384
|
ondoSymbol
|
|
9062
9385
|
),
|
|
9063
9386
|
totalCost: assetAmount(
|
|
@@ -9309,7 +9632,7 @@ function MaxButton2({
|
|
|
9309
9632
|
var import_lucide_react7 = require("lucide-react");
|
|
9310
9633
|
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
9311
9634
|
var TITLE7 = "Order confirmed";
|
|
9312
|
-
var
|
|
9635
|
+
var SHARES_SOLD_LABEL = "Shares sold";
|
|
9313
9636
|
var RECEIVED_LABEL = "Received";
|
|
9314
9637
|
var PRICE_PER_SHARE_LABEL3 = "Price per share";
|
|
9315
9638
|
var DELIVERED_TO_LABEL2 = "Delivered to";
|
|
@@ -9332,18 +9655,9 @@ function OndoSellOrderConfirmed({
|
|
|
9332
9655
|
title: TITLE7,
|
|
9333
9656
|
subtitle: subtitle2(state.soldAsset.symbol, state.proceedsSymbol),
|
|
9334
9657
|
header: (
|
|
9335
|
-
// The
|
|
9336
|
-
//
|
|
9337
|
-
|
|
9338
|
-
// for.
|
|
9339
|
-
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
9340
|
-
AssetSummaryRow,
|
|
9341
|
-
{
|
|
9342
|
-
asset: state.soldAsset,
|
|
9343
|
-
value: state.soldAmount,
|
|
9344
|
-
caption: SHARES_SOLD_CAPTION
|
|
9345
|
-
}
|
|
9346
|
-
)
|
|
9658
|
+
// The header names what was sold. The quantity is a detail row, so a
|
|
9659
|
+
// long fund name and a long share count each get the full width.
|
|
9660
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(AssetSummaryRow, { asset: state.soldAsset, wrapIdentity: true })
|
|
9347
9661
|
),
|
|
9348
9662
|
rows: detailRows3(state),
|
|
9349
9663
|
actions: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
|
|
@@ -9357,6 +9671,7 @@ function OndoSellOrderConfirmed({
|
|
|
9357
9671
|
}
|
|
9358
9672
|
function detailRows3(state) {
|
|
9359
9673
|
return [
|
|
9674
|
+
{ label: SHARES_SOLD_LABEL, value: state.soldAmount },
|
|
9360
9675
|
{ label: RECEIVED_LABEL, value: state.proceeds },
|
|
9361
9676
|
{ label: PRICE_PER_SHARE_LABEL3, value: state.pricePerShare },
|
|
9362
9677
|
{ label: DELIVERED_TO_LABEL2, value: state.recipientAddress }
|
|
@@ -10426,6 +10741,8 @@ function refreshErrorMessage2(reason) {
|
|
|
10426
10741
|
switch (reason) {
|
|
10427
10742
|
case "not-authenticated":
|
|
10428
10743
|
return "Sign in to refresh this quote.";
|
|
10744
|
+
case "not-tradable":
|
|
10745
|
+
return "Trading is paused for this asset. Try again when the market opens.";
|
|
10429
10746
|
case "generic-error":
|
|
10430
10747
|
return "Could not refresh the quote.";
|
|
10431
10748
|
default: {
|
|
@@ -10479,18 +10796,19 @@ function useOndoSellCheckoutViewModel({
|
|
|
10479
10796
|
const [orderConfirmed, setOrderConfirmed] = (0, import_react27.useState)(null);
|
|
10480
10797
|
const swappableHere = swapSpender(offer.swapContracts, chain) !== null;
|
|
10481
10798
|
const live = enabled && swappableHere;
|
|
10482
|
-
const { state:
|
|
10799
|
+
const { state: tradingStatusState } = useOndoTradingStatus({
|
|
10483
10800
|
symbol: ondoSymbol,
|
|
10484
10801
|
side: "sell",
|
|
10485
|
-
size: priceSize2(step),
|
|
10486
10802
|
pollIntervalMs: ONDO_POLL_INTERVAL_MS,
|
|
10487
10803
|
enabled: live
|
|
10488
10804
|
});
|
|
10489
|
-
const
|
|
10805
|
+
const notTradable = isNotTradable(tradingStatusState);
|
|
10806
|
+
const { state: priceState } = useOndoPrice({
|
|
10490
10807
|
symbol: ondoSymbol,
|
|
10491
10808
|
side: "sell",
|
|
10809
|
+
size: priceSize2(step),
|
|
10492
10810
|
pollIntervalMs: ONDO_POLL_INTERVAL_MS,
|
|
10493
|
-
enabled: live
|
|
10811
|
+
enabled: live && !notTradable
|
|
10494
10812
|
});
|
|
10495
10813
|
const { state: inputTokenMetadataState } = useCheckoutOfferTokenMetadata({
|
|
10496
10814
|
offer,
|
|
@@ -10568,7 +10886,14 @@ function useOndoSellCheckoutViewModel({
|
|
|
10568
10886
|
priceState,
|
|
10569
10887
|
tradingStatusState
|
|
10570
10888
|
});
|
|
10571
|
-
const
|
|
10889
|
+
const errorReason = OndoCheckoutErrorReason.of({
|
|
10890
|
+
swappableHere,
|
|
10891
|
+
notTradable,
|
|
10892
|
+
// The step the flow opened on, which for a preselected wallet is the
|
|
10893
|
+
// amount rather than a wallet step it never had.
|
|
10894
|
+
atEntry: step.type === initialStep.type && orderConfirmed === null
|
|
10895
|
+
});
|
|
10896
|
+
const state = errorReason !== null ? { type: "error", reason: errorReason } : {
|
|
10572
10897
|
type: "content",
|
|
10573
10898
|
wallet: hasWalletStep ? walletState : null,
|
|
10574
10899
|
amount: amountState,
|
|
@@ -10678,7 +11003,7 @@ function toOrderConfirmedUi2({
|
|
|
10678
11003
|
tokenMetadata: inputTokenMetadata
|
|
10679
11004
|
}),
|
|
10680
11005
|
soldAmount: assetAmount(
|
|
10681
|
-
|
|
11006
|
+
formatShareAmount(order.transaction.spendInputAmount, locale),
|
|
10682
11007
|
ondoSymbol
|
|
10683
11008
|
),
|
|
10684
11009
|
// The expected proceeds rather than the floor: this dialog reports a sale
|
|
@@ -10917,7 +11242,7 @@ var import_lucide_react9 = require("lucide-react");
|
|
|
10917
11242
|
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
10918
11243
|
var TITLE10 = "Order confirmed";
|
|
10919
11244
|
var TOTAL_COST_LABEL2 = "Total cost";
|
|
10920
|
-
var
|
|
11245
|
+
var SHARES_RECEIVED_LABEL2 = "Shares received";
|
|
10921
11246
|
var SHARES_RECEIVED_ESTIMATED_LABEL = "Shares received (estimated)";
|
|
10922
11247
|
var PRICE_PER_SHARE_LABEL5 = "Price per share";
|
|
10923
11248
|
var PRICE_PER_SHARE_ESTIMATED_LABEL = "Price per share (estimated)";
|
|
@@ -10940,13 +11265,7 @@ function SuperstateOrderConfirmed({
|
|
|
10940
11265
|
icon: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(SuccessGlyph3, {}),
|
|
10941
11266
|
title: TITLE10,
|
|
10942
11267
|
subtitle: subtitle3(state.asset.symbol),
|
|
10943
|
-
header: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
10944
|
-
AssetSummaryRow,
|
|
10945
|
-
{
|
|
10946
|
-
asset: state.asset,
|
|
10947
|
-
caption: `Issued by ${state.issuer}`
|
|
10948
|
-
}
|
|
10949
|
-
),
|
|
11268
|
+
header: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(AssetSummaryRow, { asset: state.asset, wrapIdentity: true }),
|
|
10950
11269
|
rows: detailRows4(state),
|
|
10951
11270
|
actions: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
|
|
10952
11271
|
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(ClButton, { variant: "gradient", fullWidth: true, onClick: onClose, children: DONE_LABEL3 }),
|
|
@@ -10962,7 +11281,7 @@ function detailRows4(state) {
|
|
|
10962
11281
|
return [
|
|
10963
11282
|
{ label: TOTAL_COST_LABEL2, value: state.totalCost },
|
|
10964
11283
|
{
|
|
10965
|
-
label: confirmed ?
|
|
11284
|
+
label: confirmed ? SHARES_RECEIVED_LABEL2 : SHARES_RECEIVED_ESTIMATED_LABEL,
|
|
10966
11285
|
value: state.outputAmount
|
|
10967
11286
|
},
|
|
10968
11287
|
{
|
|
@@ -13034,7 +13353,6 @@ function toOrderConfirmedUi3({
|
|
|
13034
13353
|
networkName: getNetworkName(chain),
|
|
13035
13354
|
iconUrl: assetIconUrl
|
|
13036
13355
|
}),
|
|
13037
|
-
issuer: SUPERSTATE_ISSUER_NAME,
|
|
13038
13356
|
outputAmount: assetAmount(
|
|
13039
13357
|
formatAmount(order.outputAmount, locale),
|
|
13040
13358
|
order.outputAsset.symbol
|
|
@@ -13112,7 +13430,8 @@ function CheckoutContainer({
|
|
|
13112
13430
|
className
|
|
13113
13431
|
}
|
|
13114
13432
|
),
|
|
13115
|
-
tokenSale: (tokenSaleOffer) => config["coinlist::token_sale"].render(tokenSaleOffer)
|
|
13433
|
+
tokenSale: (tokenSaleOffer) => config["coinlist::token_sale"].render(tokenSaleOffer),
|
|
13434
|
+
centrifugeVault: (vaultOffer) => config["centrifuge::vault"].render(vaultOffer)
|
|
13116
13435
|
});
|
|
13117
13436
|
}
|
|
13118
13437
|
function OndoCheckoutContainer({
|
|
@@ -13160,6 +13479,8 @@ function renderOffer(offer, branches) {
|
|
|
13160
13479
|
return branches.superstate(offer);
|
|
13161
13480
|
case "coinlist::token_sale":
|
|
13162
13481
|
return branches.tokenSale(offer);
|
|
13482
|
+
case "centrifuge::vault":
|
|
13483
|
+
return branches.centrifugeVault(offer);
|
|
13163
13484
|
default: {
|
|
13164
13485
|
const exhaustive = offer;
|
|
13165
13486
|
return exhaustive;
|
|
@@ -13761,6 +14082,7 @@ function saleWindow(offer) {
|
|
|
13761
14082
|
case "superstate::swap":
|
|
13762
14083
|
return { tagline: offer.tagline, startsAt: offer.startsAt };
|
|
13763
14084
|
case "ondo::swap":
|
|
14085
|
+
case "centrifuge::vault":
|
|
13764
14086
|
return { tagline: null, startsAt: null };
|
|
13765
14087
|
default: {
|
|
13766
14088
|
const exhaustive = offer;
|
|
@@ -16708,6 +17030,7 @@ function formatMonthYear(date, locale) {
|
|
|
16708
17030
|
OndoBuyOrderConfirmed,
|
|
16709
17031
|
OndoBuyReviewView,
|
|
16710
17032
|
OndoCheckoutError,
|
|
17033
|
+
OndoCheckoutErrorReason,
|
|
16711
17034
|
OndoSellAmountView,
|
|
16712
17035
|
OndoSellCheckoutContainer,
|
|
16713
17036
|
OndoSellCheckoutView,
|
|
@@ -16747,6 +17070,7 @@ function formatMonthYear(date, locale) {
|
|
|
16747
17070
|
formatCountdown,
|
|
16748
17071
|
formatMonthYear,
|
|
16749
17072
|
formatSaleCardCountdown,
|
|
17073
|
+
isNotTradable,
|
|
16750
17074
|
offerAssetIconUrl,
|
|
16751
17075
|
offerIconUrl,
|
|
16752
17076
|
offerTokenIdentifier,
|