@ensofinance/checkout-widget 0.0.15 → 0.0.17

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 (33) hide show
  1. package/dist/checkout-widget.es.js +8549 -8374
  2. package/dist/checkout-widget.es.js.map +1 -1
  3. package/dist/checkout-widget.umd.js +44 -44
  4. package/dist/checkout-widget.umd.js.map +1 -1
  5. package/orval.config.ts +14 -9
  6. package/package.json +1 -1
  7. package/src/components/CurrencySwapDisplay.tsx +85 -7
  8. package/src/components/QuoteParameters.tsx +58 -6
  9. package/src/components/steps/ExchangeFlow.tsx +0 -2
  10. package/src/components/steps/WalletFlow/WalletAmountStep.tsx +2 -0
  11. package/src/enso-api/api.ts +50 -31
  12. package/src/enso-api/index.ts +491 -722
  13. package/src/enso-api/model/actionAction.ts +2 -0
  14. package/src/enso-api/model/actionToBundleAction.ts +2 -0
  15. package/src/enso-api/model/bridgeLatencyEstimate.ts +33 -0
  16. package/src/enso-api/model/bundleControllerBundleShortcutTransactionRoutingStrategy.ts +1 -1
  17. package/src/enso-api/model/bundleShortcutTransaction.ts +12 -3
  18. package/src/enso-api/model/bundleShortcutTransactionMinAmountsOut.ts +15 -0
  19. package/src/enso-api/model/index.ts +55 -53
  20. package/src/enso-api/model/nonTokenizedControllerTokensParams.ts +5 -1
  21. package/src/enso-api/model/nontokenizedControllerRouteNontokenizedShorcutTransactionParams.ts +1 -1
  22. package/src/enso-api/model/nontokenizedRouteShortcutTransaction.ts +3 -0
  23. package/src/enso-api/model/routeShortcutTransaction.ts +6 -3
  24. package/src/enso-api/model/routeShortcutVariableInputs.ts +1 -1
  25. package/src/enso-api/model/routeShortcutVariableInputsRoutingStrategy.ts +1 -1
  26. package/src/enso-api/model/routerControllerRouteShortcutTransactionRoutingStrategy.ts +1 -1
  27. package/src/enso-api/model/standardActionAction.ts +2 -0
  28. package/src/enso-api/model/userOperation.ts +6 -6
  29. package/src/enso-api/model/walletBalance.ts +20 -8
  30. package/src/enso-api/model/walletControllerCreateApproveTransactionRoutingStrategy.ts +1 -1
  31. package/src/enso-api/model/walletControllerWalletBalancesParams.ts +3 -3
  32. package/src/util/common.tsx +3 -0
  33. package/src/util/enso-hooks.tsx +12 -4
package/orval.config.ts CHANGED
@@ -2,6 +2,7 @@ export default {
2
2
  enso: {
3
3
  output: {
4
4
  baseUrl: "https://api.enso.finance",
5
+ // baseUrl: "http://localhost:3000",
5
6
  mode: "single",
6
7
  prettier: true,
7
8
  target: "src/enso-api/index.ts",
@@ -24,17 +25,21 @@ export default {
24
25
  transformer: (spec: any) => {
25
26
  // Fix all malformed array schemas that have items: { type: 'array' } without proper definition
26
27
  const fixArraySchema = (obj: any) => {
27
- if (!obj || typeof obj !== 'object') return;
28
+ if (!obj || typeof obj !== "object") return;
28
29
 
29
30
  // Fix array items that are themselves arrays without proper items definition
30
- if (obj.type === 'array' && obj.items?.type === 'array' && !obj.items.items) {
31
+ if (
32
+ obj.type === "array" &&
33
+ obj.items?.type === "array" &&
34
+ !obj.items.items
35
+ ) {
31
36
  obj.items = {
32
37
  anyOf: [
33
- { type: 'string' },
34
- { type: 'number' },
35
- { type: 'boolean' },
36
- { type: 'object' },
37
- ]
38
+ { type: "string" },
39
+ { type: "number" },
40
+ { type: "boolean" },
41
+ { type: "object" },
42
+ ],
38
43
  };
39
44
  }
40
45
 
@@ -52,8 +57,8 @@ export default {
52
57
  }
53
58
 
54
59
  return spec;
55
- }
56
- }
60
+ },
61
+ },
57
62
  },
58
63
  },
59
64
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ensofinance/checkout-widget",
3
- "version": "0.0.15",
3
+ "version": "0.0.17",
4
4
  "type": "module",
5
5
  "homepage": "https://www.enso.build/",
6
6
  "repository": {
@@ -112,17 +112,91 @@ const SwapItem = ({
112
112
  );
113
113
  };
114
114
 
115
+ // Component for displaying deposit into protocol (non-tokenized positions)
116
+ const DepositItem = ({
117
+ token,
118
+ chainId,
119
+ size = 32,
120
+ }: {
121
+ token: Token;
122
+ chainId?: SupportedChainId;
123
+ size?: number;
124
+ }) => {
125
+ const protocolName = token?.protocolName || token?.protocol;
126
+ const protocolLogo = token?.protocolLogo;
127
+
128
+ return (
129
+ <Flex align="center" gap={2}>
130
+ <Box position="relative" minW={`${size}px`} minH={`${size}px`}>
131
+ <Box
132
+ borderRadius="50%"
133
+ overflow="hidden"
134
+ width={`${size}px`}
135
+ height={`${size}px`}
136
+ >
137
+ <img
138
+ src={protocolLogo || MOCK_IMAGE_URL}
139
+ title={protocolName}
140
+ alt={protocolName}
141
+ width={`${size}px`}
142
+ height={`${size}px`}
143
+ onError={(e) => {
144
+ e.currentTarget.src = MOCK_IMAGE_URL;
145
+ }}
146
+ />
147
+ </Box>
148
+ {chainId && (
149
+ <Box
150
+ position="absolute"
151
+ bottom="0"
152
+ right="-2px"
153
+ width={`${size / 2}px`}
154
+ height={`${size / 2}px`}
155
+ borderRadius="50%"
156
+ overflow="hidden"
157
+ border="1px solid white"
158
+ zIndex="1"
159
+ >
160
+ <img
161
+ src={`https://icons-ckg.pages.dev/stargate-light/networks/${STARGATE_CHAIN_NAMES[chainId]}.svg`}
162
+ alt={`Chain ${chainId}`}
163
+ width="100%"
164
+ height="100%"
165
+ />
166
+ </Box>
167
+ )}
168
+ </Box>
169
+ <Box>
170
+ <Text fontWeight="medium" fontSize="xs" color="fg.muted">
171
+ Deposit{" "}
172
+ <Text as="span" fontSize="xs" color="fg">
173
+ {token?.symbol}
174
+ </Text>
175
+ </Text>
176
+ <Text fontWeight="medium" fontSize="xs" color="fg.muted">
177
+ into{" "}
178
+ <Text as="span" fontSize="xs" color="fg">
179
+ {protocolName}
180
+ </Text>
181
+ </Text>
182
+ </Box>
183
+ </Flex>
184
+ );
185
+ };
186
+
115
187
  const CurrencySwapDisplay = ({
116
188
  tokenIn,
117
189
  tokenOut,
118
190
  chainIdIn,
119
191
  chainIdOut,
192
+ isNontokenized = false,
120
193
  size = 24,
121
194
  }: {
122
195
  tokenIn: Token;
123
196
  tokenOut: Token;
124
197
  chainIdIn: number;
125
198
  chainIdOut: number;
199
+ isNontokenized?: boolean;
126
200
  size?: number;
127
201
  }) => {
128
202
  return (
@@ -139,13 +213,17 @@ const CurrencySwapDisplay = ({
139
213
  width={"16px"}
140
214
  height={"16px"}
141
215
  />
142
- <SwapItem
143
- token={tokenOut}
144
- chainId={chainIdOut}
145
- title={"You receive"}
146
- subTitle={tokenOut?.symbol}
147
- size={size}
148
- />
216
+ {isNontokenized && tokenOut?.protocol ? (
217
+ <DepositItem token={tokenOut} chainId={chainIdOut} size={size} />
218
+ ) : (
219
+ <SwapItem
220
+ token={tokenOut}
221
+ chainId={chainIdOut}
222
+ title={"You receive"}
223
+ subTitle={tokenOut?.symbol}
224
+ size={size}
225
+ />
226
+ )}
149
227
  </SwapWrapper>
150
228
  );
151
229
  };
@@ -105,6 +105,7 @@ const QuoteParameters = () => {
105
105
  amountIn,
106
106
  chainIdIn,
107
107
  selectedIntegration,
108
+ isNontokenized,
108
109
  } = useAppDetails();
109
110
  const { routeLoading, routeData, routeFetched, routerError } =
110
111
  useRouteData();
@@ -316,7 +317,11 @@ const QuoteParameters = () => {
316
317
  </Table.Cell>
317
318
  </Table.Row>
318
319
  <Table.Row>
319
- <Table.Cell>You receive</Table.Cell>
320
+ <Table.Cell>
321
+ {isNontokenized && effectiveTokenOutData?.protocol
322
+ ? `Deposit into ${effectiveTokenOutData.protocolName || effectiveTokenOutData.protocol}`
323
+ : "You receive"}
324
+ </Table.Cell>
320
325
  <Table.Cell
321
326
  display="flex"
322
327
  textAlign="end"
@@ -341,11 +346,58 @@ const QuoteParameters = () => {
341
346
  )}{" "}
342
347
  {effectiveTokenOutData?.symbol}
343
348
  </Text>
344
- <TokenIcon
345
- token={effectiveTokenOutData}
346
- chainId={chainIdOut}
347
- size={24}
348
- />
349
+ {isNontokenized && effectiveTokenOutData?.protocol ? (
350
+ <Box
351
+ position="relative"
352
+ minW="24px"
353
+ minH="24px"
354
+ >
355
+ <Box
356
+ borderRadius="50%"
357
+ overflow="hidden"
358
+ width="24px"
359
+ height="24px"
360
+ >
361
+ <img
362
+ src={effectiveTokenOutData.protocolLogo || MOCK_IMAGE_URL}
363
+ title={effectiveTokenOutData.protocol}
364
+ alt={effectiveTokenOutData.protocol}
365
+ width="24px"
366
+ height="24px"
367
+ onError={(e) => {
368
+ e.currentTarget.src = MOCK_IMAGE_URL;
369
+ }}
370
+ />
371
+ </Box>
372
+ {chainIdOut && (
373
+ <Box
374
+ position="absolute"
375
+ bottom="0"
376
+ right="-2px"
377
+ width="12px"
378
+ height="12px"
379
+ borderRadius="50%"
380
+ overflow="hidden"
381
+ border="1px solid"
382
+ borderColor="bg"
383
+ zIndex="1"
384
+ >
385
+ <img
386
+ src={`https://icons-ckg.pages.dev/stargate-light/networks/${STARGATE_CHAIN_NAMES[chainIdOut]}.svg`}
387
+ alt={`Chain ${chainIdOut}`}
388
+ width="100%"
389
+ height="100%"
390
+ />
391
+ </Box>
392
+ )}
393
+ </Box>
394
+ ) : (
395
+ <TokenIcon
396
+ token={effectiveTokenOutData}
397
+ chainId={chainIdOut}
398
+ size={24}
399
+ />
400
+ )}
349
401
  </Box>
350
402
  </Skeleton>
351
403
  </Table.Cell>
@@ -191,7 +191,6 @@ const useHandleMeshAccessPayload = () => {
191
191
  (accessTokenPayload: AccessTokenPayload, sessionId: string) => {
192
192
  setMeshAccessToken(accessTokenPayload); // Persist access token and session id for future reloads
193
193
 
194
- debugger;
195
194
  sessionStorage.setItem(
196
195
  `${deviceKey}:${selectedIntegration?.type}`,
197
196
  JSON.stringify({
@@ -349,7 +348,6 @@ const CheckSessionKeyStep = ({
349
348
  `${deviceKey}:${selectedIntegration.type}`,
350
349
  );
351
350
  // On load: check for persisted connection and hydrate state
352
- debugger;
353
351
  if (saved) {
354
352
  try {
355
353
  const parsed = JSON.parse(saved);
@@ -39,6 +39,7 @@ const WalletAmountStep = ({ setStep }: { setStep: (step: string) => void }) => {
39
39
  tokenIn,
40
40
  chainIdOut,
41
41
  chainIdIn,
42
+ isNontokenized,
42
43
  } = useAppDetails();
43
44
 
44
45
  const { data: priceData } = useEnsoPrice(chainIdIn, tokenIn);
@@ -199,6 +200,7 @@ const WalletAmountStep = ({ setStep }: { setStep: (step: string) => void }) => {
199
200
  tokenIn={tokenInData}
200
201
  chainIdIn={chainIdIn}
201
202
  chainIdOut={chainIdOut}
203
+ isNontokenized={isNontokenized}
202
204
  />
203
205
 
204
206
  <Button
@@ -1,12 +1,12 @@
1
1
  import { useAccount, useConfig } from "wagmi";
2
2
  import {
3
- useRouterControllerPostRouteShortcutTransaction,
4
3
  useRouterControllerRouteShortcutTransaction,
5
4
  useTokensControllerTokens,
6
5
  useWalletControllerCreateApproveTransaction,
7
6
  useWalletControllerWalletBalances,
8
7
  useNonTokenizedControllerTokens,
9
8
  useNontokenizedControllerRouteNontokenizedShorcutTransaction,
9
+ useProtocolsControllerFindAll,
10
10
  } from "@/enso-api";
11
11
  import { useMemo } from "react";
12
12
  import { usePricesControllerGetPrice } from "@/enso-api";
@@ -14,11 +14,10 @@ import { Token } from "@/util/common";
14
14
  import { useAppStore } from "@/store";
15
15
  import { Address } from "viem";
16
16
  import { formatNumber, normalizeValue } from "@/util";
17
- import { VITALIK_ADDRESS } from "@/util/constants";
18
17
  import {
19
18
  RouterControllerRouteShortcutTransactionParams,
20
19
  NontokenizedControllerRouteNontokenizedShorcutTransactionParams,
21
- NonTokenizedModel,
20
+ ProtocolModel,
22
21
  } from "./model";
23
22
 
24
23
  export const useWalletBalance = () => {
@@ -242,54 +241,74 @@ export const useApproveData = ({
242
241
  return { approveData: res.data, approveFetched: res.isFetched };
243
242
  };
244
243
 
245
- export const useNontokenizedTokens = () => {
246
- const config = useConfig();
247
-
248
- const supportedChainIds = useMemo(
249
- () => config.chains.map((chain) => chain.id),
250
- [config.chains],
251
- );
252
-
253
- const { data, isLoading } = useNonTokenizedControllerTokens(
244
+ export const useProtocolsMap = () => {
245
+ const { data, isLoading } = useProtocolsControllerFindAll(
254
246
  {},
255
247
  {
256
248
  query: {
257
249
  enabled: true,
250
+ staleTime: 1000 * 60 * 60,
258
251
  },
259
252
  },
260
253
  );
261
254
 
262
- const nontokenizedMap = useMemo(() => {
263
- if (!data?.data) return new Map<string, NonTokenizedModel>();
255
+ const protocolsMap = useMemo(() => {
256
+ if (!data) return new Map<string, ProtocolModel>();
264
257
 
265
- const map = new Map<string, NonTokenizedModel>();
266
- data.data.forEach((token) => {
267
- if (supportedChainIds.includes(token.chainId)) {
268
- const key = `${token.chainId}-${token.address.toLowerCase()}`;
269
- map.set(key, token);
270
- }
258
+ const map = new Map<string, ProtocolModel>();
259
+ data.forEach((protocol) => {
260
+ map.set(protocol.slug.toLowerCase(), protocol);
271
261
  });
272
262
 
273
263
  return map;
274
- }, [data, supportedChainIds]);
264
+ }, [data]);
275
265
 
276
- console.log(nontokenizedMap);
266
+ return { protocolsMap, isLoading };
267
+ };
268
+
269
+ export const useProtocolData = (protocolSlug?: string) => {
270
+ const { protocolsMap, isLoading } = useProtocolsMap();
271
+
272
+ const protocolData = useMemo(() => {
273
+ if (!protocolSlug) return null;
274
+ const protocol = protocolsMap.get(protocolSlug.toLowerCase());
275
+ return {
276
+ logoUri: protocol?.logosUri?.[0] || null,
277
+ name: protocol?.name || protocolSlug,
278
+ };
279
+ }, [protocolSlug, protocolsMap]);
277
280
 
278
- return { nontokenizedMap, isLoading };
281
+ return { protocolData, isLoading };
279
282
  };
280
283
 
281
284
  export const useIsNontokenized = (tokenAddress?: string, chainId?: number) => {
282
- const { nontokenizedMap, isLoading } = useNontokenizedTokens();
283
-
284
- const nontokenizedData = useMemo(() => {
285
- if (!tokenAddress || !chainId) return null;
285
+ const { data, isLoading } = useNonTokenizedControllerTokens(
286
+ {
287
+ positionId: tokenAddress ? [tokenAddress] : undefined,
288
+ chainId,
289
+ },
290
+ {
291
+ query: {
292
+ enabled: !!tokenAddress && !!chainId,
293
+ },
294
+ },
295
+ );
296
+ const { data: addressData } = useNonTokenizedControllerTokens(
297
+ {
298
+ address: tokenAddress ? [tokenAddress] : undefined,
299
+ chainId,
300
+ },
301
+ {
302
+ query: {
303
+ enabled: !!tokenAddress && !!chainId,
304
+ },
305
+ },
306
+ );
286
307
 
287
- const key = `${chainId}-${tokenAddress.toLowerCase()}`;
288
- return nontokenizedMap.get(key) || null;
289
- }, [tokenAddress, chainId, nontokenizedMap]);
308
+ const nontokenizedData = data?.data?.[0] || addressData?.data?.[0] || null;
290
309
 
291
310
  return {
292
- isNontokenized: !!nontokenizedData,
311
+ isNontokenized: Boolean(nontokenizedData),
293
312
  nontokenizedData,
294
313
  isLoading,
295
314
  };