@ensofinance/checkout-widget 0.0.13 → 0.0.14
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/checkout-widget.es.js +8421 -8103
- package/dist/checkout-widget.es.js.map +1 -1
- package/dist/checkout-widget.umd.js +31 -31
- package/dist/checkout-widget.umd.js.map +1 -1
- package/dist/index.d.ts +7 -0
- package/orval.config.ts +40 -6
- package/package.json +1 -1
- package/src/components/BridgeFee.tsx +3 -3
- package/src/components/Checkout.tsx +2 -2
- package/src/components/ExchangeConfirmSecurity.tsx +16 -3
- package/src/components/QuoteParameters.tsx +33 -18
- package/src/components/TransactionDetailRow.tsx +6 -5
- package/src/components/cards/AssetCard.tsx +2 -2
- package/src/components/cards/OptionCard.tsx +2 -0
- package/src/components/steps/ExchangeFlow.tsx +254 -96
- package/src/components/steps/FlowSelector.tsx +26 -10
- package/src/components/steps/WalletFlow/WalletAmountStep.tsx +22 -23
- package/src/components/steps/WalletFlow/WalletTokenStep.tsx +5 -3
- package/src/components/ui/index.tsx +0 -3
- package/src/enso-api/api.ts +144 -3
- package/src/enso-api/custom-instance.ts +1 -0
- package/src/enso-api/index.ts +29 -118
- package/src/enso-api/model/approveActionDto.ts +17 -0
- package/src/enso-api/model/approveArgsDto.ts +22 -0
- package/src/enso-api/model/approveArgsDtoAmount.ts +16 -0
- package/src/enso-api/model/balanceActionDto.ts +17 -0
- package/src/enso-api/model/balanceArgsDto.ts +15 -0
- package/src/enso-api/model/borrowActionDto.ts +18 -0
- package/src/enso-api/model/borrowArgsDto.ts +22 -0
- package/src/enso-api/model/borrowArgsDtoAmountOut.ts +16 -0
- package/src/enso-api/model/bridgeActionDto.ts +19 -0
- package/src/enso-api/model/bridgeArgsDto.ts +29 -0
- package/src/enso-api/model/bridgeArgsDtoAmountIn.ts +16 -0
- package/src/enso-api/model/bridgeArgsDtoCallbackItem.ts +64 -0
- package/src/enso-api/model/bundleControllerBundleShortcutTransactionBodyItem.ts +69 -0
- package/src/enso-api/model/callActionDto.ts +18 -0
- package/src/enso-api/model/callArgsDto.ts +29 -0
- package/src/enso-api/model/callArgsDtoArgsItem.ts +17 -0
- package/src/enso-api/model/callArgsDtoArgsItemAnyOf.ts +12 -0
- package/src/enso-api/model/callArgsDtoValue.ts +16 -0
- package/src/enso-api/model/callOutput.ts +15 -0
- package/src/enso-api/model/depositActionDto.ts +18 -0
- package/src/enso-api/model/depositArgsDto.ts +28 -0
- package/src/enso-api/model/depositArgsDtoAmountIn.ts +20 -0
- package/src/enso-api/model/depositArgsDtoAmountInOneOfItem.ts +13 -0
- package/src/enso-api/model/depositArgsDtoTokenIn.ts +15 -0
- package/src/enso-api/model/depositArgsDtoTokenOut.ts +15 -0
- package/src/enso-api/model/depositCLMMActionDto.ts +18 -0
- package/src/enso-api/model/depositCLMMArgsDto.ts +30 -0
- package/src/enso-api/model/depositCLMMArgsDtoAmountInItem.ts +17 -0
- package/src/enso-api/model/depositCLMMArgsDtoAmountInItemAnyOf.ts +12 -0
- package/src/enso-api/model/ensoFeeActionDto.ts +17 -0
- package/src/enso-api/model/ensoFeeArgsDto.ts +20 -0
- package/src/enso-api/model/ensoFeeArgsDtoAmount.ts +16 -0
- package/src/enso-api/model/feeActionDto.ts +17 -0
- package/src/enso-api/model/feeArgsDto.ts +22 -0
- package/src/enso-api/model/feeArgsDtoAmount.ts +16 -0
- package/src/enso-api/model/harvestActionDto.ts +19 -0
- package/src/enso-api/model/harvestArgsDto.ts +17 -0
- package/src/enso-api/model/index.ts +115 -4
- package/src/enso-api/model/mergeActionDto.ts +17 -0
- package/src/enso-api/model/mergeArgsDto.ts +22 -0
- package/src/enso-api/model/mergeArgsDtoAmountInItem.ts +13 -0
- package/src/enso-api/model/minAmountOutActionDto.ts +17 -0
- package/src/enso-api/model/minAmountOutArgsDto.ts +19 -0
- package/src/enso-api/model/minAmountOutArgsDtoAmountOut.ts +16 -0
- package/src/enso-api/model/minAmountOutArgsDtoMinAmountOut.ts +16 -0
- package/src/enso-api/model/multiDepositActionDto.ts +18 -0
- package/src/enso-api/model/multiDepositArgsDto.ts +24 -0
- package/src/enso-api/model/multiDepositArgsDtoAmountInItem.ts +17 -0
- package/src/enso-api/model/multiDepositArgsDtoAmountInItemAnyOf.ts +12 -0
- package/src/enso-api/model/multiOutSingleDepositActionDto.ts +18 -0
- package/src/enso-api/model/multiOutSingleDepositArgsDto.ts +24 -0
- package/src/enso-api/model/multiOutSingleDepositArgsDtoAmountIn.ts +16 -0
- package/src/enso-api/model/multiRedeemActionDto.ts +18 -0
- package/src/enso-api/model/multiRedeemArgs2Dto.ts +24 -0
- package/src/enso-api/model/multiRedeemArgs2DtoAmountIn.ts +16 -0
- package/src/enso-api/model/nontokenizedControllerRouteNontokenizedShorcutTransactionParams.ts +8 -0
- package/src/enso-api/model/nontokenizedControllerRouteNontokenizedShorcutTransactionRoutingStrategy.ts +1 -0
- package/src/enso-api/model/nontokenizedRouteShortcutTransaction.ts +31 -0
- package/src/enso-api/model/paymasterFeeActionDto.ts +17 -0
- package/src/enso-api/model/paymasterFeeArgsDto.ts +18 -0
- package/src/enso-api/model/paymasterFeeArgsDtoAmount.ts +16 -0
- package/src/enso-api/model/permitTransferFromActionDto.ts +18 -0
- package/src/enso-api/model/permitTransferFromArgsDto.ts +29 -0
- package/src/enso-api/model/permitTransferFromArgsDtoAmount.ts +20 -0
- package/src/enso-api/model/permitTransferFromArgsDtoAmountOneOfItem.ts +13 -0
- package/src/enso-api/model/permitTransferFromArgsDtoToken.ts +15 -0
- package/src/enso-api/model/positionModel.ts +14 -0
- package/src/enso-api/model/redeemActionDto.ts +18 -0
- package/src/enso-api/model/redeemArgsDto.ts +25 -0
- package/src/enso-api/model/redeemArgsDtoAmountIn.ts +16 -0
- package/src/enso-api/model/redeemArgsDtoTokenOut.ts +15 -0
- package/src/enso-api/model/redeemCLMMActionDto.ts +18 -0
- package/src/enso-api/model/redeemCLMMArgsDto.ts +24 -0
- package/src/enso-api/model/redeemCLMMArgsDtoLiquidity.ts +16 -0
- package/src/enso-api/model/repayActionDto.ts +18 -0
- package/src/enso-api/model/repayArgsDto.ts +22 -0
- package/src/enso-api/model/repayArgsDtoAmountIn.ts +16 -0
- package/src/enso-api/model/routeActionDto.ts +20 -0
- package/src/enso-api/model/routeArgsDto.ts +38 -0
- package/src/enso-api/model/routeArgsDtoAmountIn.ts +16 -0
- package/src/enso-api/model/singleDepositActionDto.ts +18 -0
- package/src/enso-api/model/singleDepositArgsDto.ts +24 -0
- package/src/enso-api/model/singleDepositArgsDtoAmountIn.ts +16 -0
- package/src/enso-api/model/singleRedeemActionDto.ts +18 -0
- package/src/enso-api/model/singleRedeemArgs2Dto.ts +24 -0
- package/src/enso-api/model/singleRedeemArgs2DtoAmountIn.ts +16 -0
- package/src/enso-api/model/slippageActionDto.ts +17 -0
- package/src/enso-api/model/slippageArgsDto.ts +18 -0
- package/src/enso-api/model/slippageArgsDtoAmountOut.ts +16 -0
- package/src/enso-api/model/splitActionDto.ts +17 -0
- package/src/enso-api/model/splitArgsDto.ts +22 -0
- package/src/enso-api/model/splitArgsDtoAmountIn.ts +16 -0
- package/src/enso-api/model/swapActionDto.ts +18 -0
- package/src/enso-api/model/swapArgsDto.ts +30 -0
- package/src/enso-api/model/swapArgsDtoAmountIn.ts +16 -0
- package/src/enso-api/model/tokenizedMultiDepositActionDto.ts +18 -0
- package/src/enso-api/model/tokenizedMultiDepositArgsDto.ts +24 -0
- package/src/enso-api/model/tokenizedMultiDepositArgsDtoAmountInItem.ts +17 -0
- package/src/enso-api/model/tokenizedMultiDepositArgsDtoAmountInItemAnyOf.ts +14 -0
- package/src/enso-api/model/tokenizedMultiRedeemActionDto.ts +18 -0
- package/src/enso-api/model/tokenizedMultiRedeemArgsDto.ts +24 -0
- package/src/enso-api/model/tokenizedMultiRedeemArgsDtoAmountIn.ts +16 -0
- package/src/enso-api/model/tokenizedSingleDepositActionDto.ts +18 -0
- package/src/enso-api/model/tokenizedSingleDepositArgsDto.ts +24 -0
- package/src/enso-api/model/tokenizedSingleDepositArgsDtoAmountIn.ts +16 -0
- package/src/enso-api/model/tokenizedSingleRedeemActionDto.ts +18 -0
- package/src/enso-api/model/tokenizedSingleRedeemArgsDto.ts +24 -0
- package/src/enso-api/model/tokenizedSingleRedeemArgsDtoAmountIn.ts +16 -0
- package/src/enso-api/model/tokensControllerTokensLiquidityType.ts +19 -0
- package/src/enso-api/model/tokensControllerTokensParams.ts +6 -0
- package/src/enso-api/model/transferActionDto.ts +18 -0
- package/src/enso-api/model/transferArgsDto.ts +22 -0
- package/src/enso-api/model/transferArgsDtoAmount.ts +16 -0
- package/src/enso-api/model/transferFromActionDto.ts +18 -0
- package/src/enso-api/model/transferFromArgsDto.ts +24 -0
- package/src/enso-api/model/transferFromArgsDtoAmount.ts +16 -0
- package/src/index.ts +1 -0
- package/src/store.ts +12 -5
- package/src/types/index.ts +9 -3
- package/src/util/common.tsx +2 -0
- package/src/util/enso-hooks.tsx +72 -11
|
@@ -53,31 +53,29 @@ import { ConfirmExchangeStep } from "../ExchangeConfirmSecurity";
|
|
|
53
53
|
|
|
54
54
|
import SuccessIcon from "@/assets/success.svg";
|
|
55
55
|
import FailIcon from "@/assets/fail.svg";
|
|
56
|
+
import { SupportedExchanges } from "@/types";
|
|
56
57
|
|
|
57
58
|
const ENTRY_POINT_ADDRESS: `0x${string}` =
|
|
58
59
|
"0x0000000071727de22e5e9d8baf0edac6f37da032";
|
|
59
60
|
|
|
60
|
-
export
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
[ExchangeType.binance]: "Binance",
|
|
66
|
-
[ExchangeType.delayed]: "Smart Account",
|
|
61
|
+
export const ExchangeToIntegrationType: Record<SupportedExchanges, string> = {
|
|
62
|
+
[SupportedExchanges.Binance]: "binanceInternationalDirect",
|
|
63
|
+
[SupportedExchanges.Kraken]: "krakenDirect",
|
|
64
|
+
[SupportedExchanges.Coinbase]: "coinbase",
|
|
65
|
+
[SupportedExchanges.Bybit]: "bybitDirect",
|
|
67
66
|
};
|
|
68
67
|
|
|
69
|
-
//
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
// });
|
|
68
|
+
// Map Mesh broker types to icon URLs
|
|
69
|
+
export const EXCHANGE_ICON_BY_TYPE: Record<string, string> = {
|
|
70
|
+
[ExchangeToIntegrationType[SupportedExchanges.Binance]]:
|
|
71
|
+
"https://assets.coingecko.com/markets/images/52/large/binance.jpg",
|
|
72
|
+
[ExchangeToIntegrationType[SupportedExchanges.Kraken]]:
|
|
73
|
+
"https://assets.coingecko.com/markets/images/29/large/kraken.jpg",
|
|
74
|
+
[ExchangeToIntegrationType[SupportedExchanges.Coinbase]]:
|
|
75
|
+
"https://assets.coingecko.com/markets/images/23/large/Coinbase_Coin_Primary.png",
|
|
76
|
+
[ExchangeToIntegrationType[SupportedExchanges.Bybit]]:
|
|
77
|
+
"https://assets.coingecko.com/markets/images/698/large/bybit_spot.png",
|
|
78
|
+
};
|
|
81
79
|
|
|
82
80
|
// Types for Mesh Holdings API response
|
|
83
81
|
interface CryptocurrencyPosition {
|
|
@@ -141,6 +139,7 @@ Withdrawal steps:
|
|
|
141
139
|
|
|
142
140
|
export enum WithdrawalStep {
|
|
143
141
|
CheckSessionKey,
|
|
142
|
+
ChooseExchange,
|
|
144
143
|
ChooseExchangeAsset,
|
|
145
144
|
ChooseBalanceAsset,
|
|
146
145
|
ChooseAmount,
|
|
@@ -149,6 +148,7 @@ export enum WithdrawalStep {
|
|
|
149
148
|
TrackUserOp,
|
|
150
149
|
}
|
|
151
150
|
const withdrawalSteps = [
|
|
151
|
+
WithdrawalStep.ChooseExchange,
|
|
152
152
|
WithdrawalStep.CheckSessionKey,
|
|
153
153
|
WithdrawalStep.ChooseExchangeAsset,
|
|
154
154
|
WithdrawalStep.ChooseAmount,
|
|
@@ -160,7 +160,7 @@ const balanceSteps = [
|
|
|
160
160
|
WithdrawalStep.ChooseAmount,
|
|
161
161
|
WithdrawalStep.SignUserOp,
|
|
162
162
|
];
|
|
163
|
-
|
|
163
|
+
// Integration details are fetched dynamically from Mesh API.
|
|
164
164
|
|
|
165
165
|
// Mesh network IDs for EVM chains (from Mesh networks API)
|
|
166
166
|
const MESH_NETWORK_IDS: { [chainId: number]: string } = {
|
|
@@ -184,20 +184,138 @@ const getNetworkId = (chainId: number): string => {
|
|
|
184
184
|
|
|
185
185
|
const useHandleMeshAccessPayload = () => {
|
|
186
186
|
const { setMeshAccessToken } = useAppStore();
|
|
187
|
-
const deviceKey =
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
187
|
+
const deviceKey = useDeviceId();
|
|
188
|
+
const selectedIntegration = useAppStore((s) => s.selectedIntegration);
|
|
189
|
+
|
|
190
|
+
return useCallback(
|
|
191
|
+
(accessTokenPayload: AccessTokenPayload, sessionId: string) => {
|
|
192
|
+
setMeshAccessToken(accessTokenPayload); // Persist access token and session id for future reloads
|
|
193
|
+
|
|
194
|
+
debugger;
|
|
195
|
+
sessionStorage.setItem(
|
|
196
|
+
`${deviceKey}:${selectedIntegration?.type}`,
|
|
197
|
+
JSON.stringify({
|
|
198
|
+
accessToken:
|
|
199
|
+
accessTokenPayload.accountTokens[0].accessToken,
|
|
200
|
+
sessionId,
|
|
201
|
+
timestamp: Date.now(),
|
|
202
|
+
}),
|
|
203
|
+
);
|
|
204
|
+
},
|
|
205
|
+
[deviceKey, selectedIntegration?.type],
|
|
206
|
+
);
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
type MeshIntegration = {
|
|
210
|
+
id: string;
|
|
211
|
+
type: string; // brokerType
|
|
212
|
+
name: string;
|
|
213
|
+
networks?: {
|
|
214
|
+
id: string;
|
|
215
|
+
nativeSymbol?: string;
|
|
216
|
+
name?: string;
|
|
217
|
+
chainId?: string | number;
|
|
218
|
+
}[];
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
const ChooseExchangeStep = ({
|
|
222
|
+
setStep,
|
|
223
|
+
}: {
|
|
224
|
+
setStep: (step: WithdrawalStep) => void;
|
|
225
|
+
}) => {
|
|
226
|
+
const { chainIdOut } = useAppStore();
|
|
227
|
+
const [integrations, setIntegrations] = useState<MeshIntegration[]>([]);
|
|
228
|
+
const [loading, setLoading] = useState(true);
|
|
229
|
+
const [error, setError] = useState<string | null>(null);
|
|
230
|
+
const setSelectedIntegration = useAppStore(
|
|
231
|
+
(state) => state.setSelectedIntegration,
|
|
232
|
+
);
|
|
233
|
+
const { enableExchange } = useContext(CheckoutContext);
|
|
234
|
+
|
|
235
|
+
useEffect(() => {
|
|
236
|
+
const fetchIntegrations = async () => {
|
|
237
|
+
try {
|
|
238
|
+
const res = await fetch(`${MESH_API_URL}/integrations`);
|
|
239
|
+
const data = await res.json();
|
|
240
|
+
const availableExchanges = enableExchange
|
|
241
|
+
.map((e) => ExchangeToIntegrationType[e])
|
|
242
|
+
.filter(Boolean);
|
|
243
|
+
|
|
244
|
+
// Filter integrations by current chain support
|
|
245
|
+
const filtered = data?.filter(
|
|
246
|
+
(i) =>
|
|
247
|
+
i.networks.some((n) => +n.chainId === chainIdOut) &&
|
|
248
|
+
availableExchanges.includes(i.type),
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
setIntegrations(filtered);
|
|
252
|
+
} catch (e) {
|
|
253
|
+
console.error("Failed to fetch integrations", e);
|
|
254
|
+
setError("Failed to load exchanges");
|
|
255
|
+
} finally {
|
|
256
|
+
setLoading(false);
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
fetchIntegrations();
|
|
260
|
+
}, [chainIdOut]);
|
|
261
|
+
|
|
262
|
+
if (loading)
|
|
263
|
+
return (
|
|
264
|
+
<Center>
|
|
265
|
+
<Spinner m={5} />
|
|
266
|
+
</Center>
|
|
199
267
|
);
|
|
200
|
-
|
|
268
|
+
if (error)
|
|
269
|
+
return (
|
|
270
|
+
<BodyWrapper>
|
|
271
|
+
<Box p={5} color="red.500">
|
|
272
|
+
{error}
|
|
273
|
+
</Box>
|
|
274
|
+
</BodyWrapper>
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
return (
|
|
278
|
+
<BodyWrapper>
|
|
279
|
+
<Box mb={4} width="100%" textAlign="left">
|
|
280
|
+
<HeaderTitle>Choose Exchange</HeaderTitle>
|
|
281
|
+
</Box>
|
|
282
|
+
|
|
283
|
+
{integrations?.length > 0 ? (
|
|
284
|
+
<ListWrapper>
|
|
285
|
+
{integrations.map((integration) => (
|
|
286
|
+
<AssetCard
|
|
287
|
+
key={integration.id}
|
|
288
|
+
// chainId={chainIdOut || 1}
|
|
289
|
+
icon={EXCHANGE_ICON_BY_TYPE[integration.type]}
|
|
290
|
+
title={integration.name}
|
|
291
|
+
balance={""}
|
|
292
|
+
usdBalance=""
|
|
293
|
+
tag=""
|
|
294
|
+
loading={false}
|
|
295
|
+
selected={false}
|
|
296
|
+
onClick={() => {
|
|
297
|
+
setSelectedIntegration({
|
|
298
|
+
id: integration.id,
|
|
299
|
+
type: integration.type,
|
|
300
|
+
name: integration.name,
|
|
301
|
+
});
|
|
302
|
+
setStep(WithdrawalStep.CheckSessionKey);
|
|
303
|
+
}}
|
|
304
|
+
/>
|
|
305
|
+
))}
|
|
306
|
+
</ListWrapper>
|
|
307
|
+
) : (
|
|
308
|
+
<Box
|
|
309
|
+
textAlign="center"
|
|
310
|
+
fontSize={"sm"}
|
|
311
|
+
color="fg.subtle"
|
|
312
|
+
py={3}
|
|
313
|
+
>
|
|
314
|
+
No exchanges available for specified target chain
|
|
315
|
+
</Box>
|
|
316
|
+
)}
|
|
317
|
+
</BodyWrapper>
|
|
318
|
+
);
|
|
201
319
|
};
|
|
202
320
|
|
|
203
321
|
const CheckSessionKeyStep = ({
|
|
@@ -208,26 +326,30 @@ const CheckSessionKeyStep = ({
|
|
|
208
326
|
const { chainIdOut, setMeshAccessToken, setSessionId, setChainIdIn } =
|
|
209
327
|
useAppStore();
|
|
210
328
|
const { address } = useAccount();
|
|
211
|
-
const deviceKey =
|
|
329
|
+
const deviceKey = useDeviceId();
|
|
212
330
|
const [showConfirmation, setShowConfirmation] = useState(false);
|
|
331
|
+
const selectedIntegration = useAppStore((s) => s.selectedIntegration);
|
|
213
332
|
|
|
214
333
|
const invalidChainId = chainIdOut && !MESH_NETWORKS.includes(chainIdOut);
|
|
215
334
|
const handleMeshAccessPayload = useHandleMeshAccessPayload();
|
|
216
|
-
const setActiveExchange = useAppStore((state) => state.setActiveExchange);
|
|
217
|
-
|
|
218
|
-
useEffect(() => {
|
|
219
|
-
setActiveExchange("binance");
|
|
220
|
-
}, []);
|
|
221
335
|
|
|
222
336
|
useEffect(() => {
|
|
223
337
|
setChainIdIn(chainIdOut);
|
|
224
338
|
}, [chainIdOut]);
|
|
225
339
|
|
|
226
340
|
useEffect(() => {
|
|
341
|
+
if (!selectedIntegration) {
|
|
342
|
+
// ensure an exchange is selected
|
|
343
|
+
setStep(WithdrawalStep.ChooseExchange);
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
227
346
|
if (invalidChainId) return;
|
|
228
347
|
// If connection is persisted, skip fetching a new link token
|
|
229
|
-
const saved = sessionStorage.getItem(
|
|
348
|
+
const saved = sessionStorage.getItem(
|
|
349
|
+
`${deviceKey}:${selectedIntegration.type}`,
|
|
350
|
+
);
|
|
230
351
|
// On load: check for persisted connection and hydrate state
|
|
352
|
+
debugger;
|
|
231
353
|
if (saved) {
|
|
232
354
|
try {
|
|
233
355
|
const parsed = JSON.parse(saved);
|
|
@@ -245,20 +367,24 @@ const CheckSessionKeyStep = ({
|
|
|
245
367
|
|
|
246
368
|
// Show confirmation instead of auto-connecting
|
|
247
369
|
setShowConfirmation(true);
|
|
248
|
-
}, [deviceKey, invalidChainId]);
|
|
370
|
+
}, [deviceKey, invalidChainId, selectedIntegration]);
|
|
249
371
|
|
|
250
372
|
const handleConfirmAuth = () => {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
373
|
+
const brokerType = selectedIntegration?.type;
|
|
374
|
+
fetch(
|
|
375
|
+
`${MESH_API_URL}/linktoken?brokerType=${encodeURIComponent(brokerType)}`,
|
|
376
|
+
{
|
|
377
|
+
method: "POST",
|
|
378
|
+
headers: {
|
|
379
|
+
"Content-Type": "application/json",
|
|
380
|
+
},
|
|
381
|
+
body: JSON.stringify({
|
|
382
|
+
userId: deviceKey,
|
|
383
|
+
integrationId: selectedIntegration?.id,
|
|
384
|
+
address,
|
|
385
|
+
}),
|
|
255
386
|
},
|
|
256
|
-
|
|
257
|
-
userId: deviceKey,
|
|
258
|
-
integrationId: BINANCE_INTEGRATION_ID,
|
|
259
|
-
address,
|
|
260
|
-
}),
|
|
261
|
-
})
|
|
387
|
+
)
|
|
262
388
|
.then((response) => response.json())
|
|
263
389
|
.then((response) => {
|
|
264
390
|
setSessionId(response.content.sessionId);
|
|
@@ -269,7 +395,10 @@ const CheckSessionKeyStep = ({
|
|
|
269
395
|
console.log("onIntegrationConnected", payload);
|
|
270
396
|
meshLink.closeLink();
|
|
271
397
|
setStep(WithdrawalStep.ChooseExchangeAsset);
|
|
272
|
-
handleMeshAccessPayload(
|
|
398
|
+
handleMeshAccessPayload(
|
|
399
|
+
payload.accessToken,
|
|
400
|
+
response.content.sessionId,
|
|
401
|
+
); // Persist access token and session id for future reloads
|
|
273
402
|
},
|
|
274
403
|
onExit: (error) => {
|
|
275
404
|
console.log("onExit", error);
|
|
@@ -310,21 +439,32 @@ const CheckSessionKeyStep = ({
|
|
|
310
439
|
}
|
|
311
440
|
|
|
312
441
|
if (showConfirmation) {
|
|
313
|
-
return
|
|
442
|
+
return (
|
|
443
|
+
<ConfirmExchangeStep
|
|
444
|
+
onConfirm={handleConfirmAuth}
|
|
445
|
+
exchangeName={selectedIntegration?.name}
|
|
446
|
+
exchangeIcon={
|
|
447
|
+
selectedIntegration?.type
|
|
448
|
+
? EXCHANGE_ICON_BY_TYPE[selectedIntegration.type]
|
|
449
|
+
: undefined
|
|
450
|
+
}
|
|
451
|
+
/>
|
|
452
|
+
);
|
|
314
453
|
}
|
|
315
454
|
|
|
316
455
|
return <Spinner m={5} />;
|
|
317
456
|
};
|
|
318
457
|
|
|
458
|
+
const DEVICE_ID_KEY = "meshDeviceId";
|
|
319
459
|
// Generate a unique device ID to use as user id for Mesh
|
|
320
|
-
const
|
|
460
|
+
const useDeviceId = () => {
|
|
321
461
|
return useMemo(() => {
|
|
322
|
-
|
|
323
|
-
|
|
462
|
+
let deviceId = localStorage.getItem(DEVICE_ID_KEY);
|
|
463
|
+
console.log(deviceId);
|
|
324
464
|
|
|
325
465
|
if (!deviceId) {
|
|
326
466
|
deviceId = `device_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;
|
|
327
|
-
localStorage.setItem(
|
|
467
|
+
localStorage.setItem(DEVICE_ID_KEY, deviceId);
|
|
328
468
|
}
|
|
329
469
|
|
|
330
470
|
return deviceId;
|
|
@@ -358,12 +498,14 @@ const ChooseAssetStep = ({
|
|
|
358
498
|
setTokenIn,
|
|
359
499
|
chainIdIn,
|
|
360
500
|
} = useAppStore();
|
|
501
|
+
const deviceKey = useDeviceId();
|
|
502
|
+
|
|
503
|
+
const selectedIntegration = useAppStore((s) => s.selectedIntegration);
|
|
361
504
|
|
|
362
|
-
const deviceKey = useDeviceKey();
|
|
363
505
|
useEffect(() => {
|
|
364
506
|
const fetchData = async () => {
|
|
365
507
|
try {
|
|
366
|
-
// Fetch holdings
|
|
508
|
+
// Fetch holdings for the selected exchange
|
|
367
509
|
const holdingsResponse = await fetch(
|
|
368
510
|
`${MESH_API_URL}/holdings`,
|
|
369
511
|
{
|
|
@@ -375,7 +517,7 @@ const ChooseAssetStep = ({
|
|
|
375
517
|
body: JSON.stringify({
|
|
376
518
|
authToken:
|
|
377
519
|
meshAccessToken.accountTokens[0].accessToken,
|
|
378
|
-
brokerType:
|
|
520
|
+
brokerType: selectedIntegration?.type,
|
|
379
521
|
}),
|
|
380
522
|
},
|
|
381
523
|
);
|
|
@@ -393,7 +535,9 @@ const ChooseAssetStep = ({
|
|
|
393
535
|
setStep(WithdrawalStep.CheckSessionKey);
|
|
394
536
|
setMeshAccessToken(null);
|
|
395
537
|
setSessionId(null);
|
|
396
|
-
sessionStorage.removeItem(
|
|
538
|
+
sessionStorage.removeItem(
|
|
539
|
+
`${deviceKey}:${selectedIntegration?.type}`,
|
|
540
|
+
);
|
|
397
541
|
}
|
|
398
542
|
throw new Error(
|
|
399
543
|
holdingsData.message || "Failed to fetch holdings",
|
|
@@ -402,10 +546,9 @@ const ChooseAssetStep = ({
|
|
|
402
546
|
|
|
403
547
|
// Fetch supported tokens for current chain
|
|
404
548
|
const tokensResponse = await fetch(
|
|
405
|
-
`${MESH_API_URL}/tokens?chainId=${chainIdIn}`,
|
|
549
|
+
`${MESH_API_URL}/tokens?chainId=${chainIdIn}&brokerType=${encodeURIComponent(selectedIntegration?.type || "")}`,
|
|
406
550
|
);
|
|
407
551
|
const tokensData = await tokensResponse.json();
|
|
408
|
-
console.log("Tokens data:", tokensData);
|
|
409
552
|
|
|
410
553
|
if (
|
|
411
554
|
tokensData.status === "success" &&
|
|
@@ -456,18 +599,16 @@ const ChooseAssetStep = ({
|
|
|
456
599
|
}
|
|
457
600
|
};
|
|
458
601
|
|
|
459
|
-
if (meshAccessToken && sessionId && chainIdOut) {
|
|
602
|
+
if (meshAccessToken && sessionId && chainIdOut && selectedIntegration) {
|
|
460
603
|
fetchData();
|
|
461
604
|
}
|
|
462
|
-
}, [address, chainIdOut, meshAccessToken, sessionId]);
|
|
605
|
+
}, [address, chainIdOut, meshAccessToken, sessionId, selectedIntegration]);
|
|
463
606
|
|
|
464
607
|
const geckoTokens = useTokenFromListBySymbols(
|
|
465
608
|
matchedTokens.map((token) => token.symbol),
|
|
466
609
|
chainIdIn,
|
|
467
610
|
);
|
|
468
611
|
|
|
469
|
-
console.log("geckoTokens", geckoTokens);
|
|
470
|
-
|
|
471
612
|
if (loading)
|
|
472
613
|
return (
|
|
473
614
|
<Center>
|
|
@@ -545,10 +686,16 @@ const ChooseDelayedBalance = ({
|
|
|
545
686
|
|
|
546
687
|
// Get smart account balances
|
|
547
688
|
const { holdingsList, total, isLoading } = useSmartAccountBalances(1);
|
|
548
|
-
const
|
|
689
|
+
const setSelectedIntegration = useAppStore(
|
|
690
|
+
(state) => state.setSelectedIntegration,
|
|
691
|
+
);
|
|
549
692
|
|
|
550
693
|
useEffect(() => {
|
|
551
|
-
|
|
694
|
+
setSelectedIntegration({
|
|
695
|
+
type: "delayed",
|
|
696
|
+
name: "Smart account",
|
|
697
|
+
id: "",
|
|
698
|
+
});
|
|
552
699
|
}, []);
|
|
553
700
|
|
|
554
701
|
if (isLoading) {
|
|
@@ -637,7 +784,7 @@ const ChooseAmountStep = ({
|
|
|
637
784
|
const [inputMode, setInputMode] = useState<"usd" | "token">("usd");
|
|
638
785
|
const [usdValue, setUsdValue] = useState<string>("");
|
|
639
786
|
const { setAmountIn } = useAppStore();
|
|
640
|
-
const { tokenInData
|
|
787
|
+
const { tokenInData } = useAppDetails();
|
|
641
788
|
const isStable = selectedToken?.symbol.toLowerCase().includes("USD");
|
|
642
789
|
const roundingPrecision = isStable ? 2 : 6;
|
|
643
790
|
|
|
@@ -1016,10 +1163,12 @@ const InitiateWithdrawalStep = ({
|
|
|
1016
1163
|
const { meshAccessToken, amountIn, chainIdOut } = useAppStore();
|
|
1017
1164
|
const { address } = useAccount();
|
|
1018
1165
|
const { tokenInData } = useAppDetails();
|
|
1166
|
+
const sessionId = useAppStore((state) => state.sessionId);
|
|
1019
1167
|
const [isLoading, setIsLoading] = useState(true);
|
|
1168
|
+
const selectedIntegration = useAppStore((s) => s.selectedIntegration);
|
|
1020
1169
|
|
|
1021
1170
|
const handleMeshAccessPayload = useHandleMeshAccessPayload();
|
|
1022
|
-
const deviceKey =
|
|
1171
|
+
const deviceKey = useDeviceId();
|
|
1023
1172
|
|
|
1024
1173
|
useEffect(() => {
|
|
1025
1174
|
if (!selectedToken || !userOp || !meshAccessToken) {
|
|
@@ -1047,7 +1196,7 @@ const InitiateWithdrawalStep = ({
|
|
|
1047
1196
|
const meshData = {
|
|
1048
1197
|
restrictMultipleAccounts: true,
|
|
1049
1198
|
userId: deviceKey,
|
|
1050
|
-
integrationId:
|
|
1199
|
+
integrationId: selectedIntegration?.id,
|
|
1051
1200
|
transferOptions: {
|
|
1052
1201
|
toAddresses,
|
|
1053
1202
|
},
|
|
@@ -1055,31 +1204,35 @@ const InitiateWithdrawalStep = ({
|
|
|
1055
1204
|
|
|
1056
1205
|
console.log("link request body", meshData);
|
|
1057
1206
|
|
|
1058
|
-
const response = await fetch(
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
restrictMultipleAccounts: true,
|
|
1065
|
-
userId: deviceKey,
|
|
1066
|
-
integrationId: BINANCE_INTEGRATION_ID,
|
|
1067
|
-
transferOptions: {
|
|
1068
|
-
toAddresses,
|
|
1207
|
+
const response = await fetch(
|
|
1208
|
+
`${MESH_API_URL}/linktoken?brokerType=${encodeURIComponent(selectedIntegration?.type || "")}`,
|
|
1209
|
+
{
|
|
1210
|
+
method: "POST",
|
|
1211
|
+
headers: {
|
|
1212
|
+
"Content-Type": "application/json",
|
|
1069
1213
|
},
|
|
1070
|
-
|
|
1071
|
-
|
|
1214
|
+
body: JSON.stringify({
|
|
1215
|
+
restrictMultipleAccounts: true,
|
|
1216
|
+
userId: deviceKey,
|
|
1217
|
+
integrationId: selectedIntegration?.id,
|
|
1218
|
+
transferOptions: {
|
|
1219
|
+
toAddresses,
|
|
1220
|
+
},
|
|
1221
|
+
}),
|
|
1222
|
+
},
|
|
1223
|
+
);
|
|
1072
1224
|
|
|
1073
1225
|
const data = await response.json();
|
|
1074
1226
|
console.log("Link token response:", data);
|
|
1075
1227
|
|
|
1228
|
+
// @ts-ignore
|
|
1076
1229
|
const accessTokens: IntegrationAccessToken[] =
|
|
1077
1230
|
meshAccessToken.accountTokens.map((token) => ({
|
|
1078
1231
|
...token,
|
|
1079
1232
|
accountId: token.account.accountId,
|
|
1080
1233
|
accountName: token.account.accountName,
|
|
1081
|
-
brokerName:
|
|
1082
|
-
brokerType:
|
|
1234
|
+
brokerName: selectedIntegration?.name,
|
|
1235
|
+
brokerType: selectedIntegration?.type,
|
|
1083
1236
|
}));
|
|
1084
1237
|
|
|
1085
1238
|
console.log("accessTokens", accessTokens);
|
|
@@ -1088,7 +1241,7 @@ const InitiateWithdrawalStep = ({
|
|
|
1088
1241
|
clientId: address,
|
|
1089
1242
|
accessTokens,
|
|
1090
1243
|
onIntegrationConnected: (payload) => {
|
|
1091
|
-
handleMeshAccessPayload(payload.accessToken); // Persist access token and session id for future reloads
|
|
1244
|
+
handleMeshAccessPayload(payload.accessToken, sessionId); // Persist access token and session id for future reloads
|
|
1092
1245
|
console.log("Integration connected", payload);
|
|
1093
1246
|
},
|
|
1094
1247
|
onTransferFinished: (transferData) => {
|
|
@@ -1441,7 +1594,7 @@ const TrackUserOpStep = ({
|
|
|
1441
1594
|
|
|
1442
1595
|
const ExchangeFlow = ({
|
|
1443
1596
|
setFlow,
|
|
1444
|
-
initialStep = WithdrawalStep.
|
|
1597
|
+
initialStep = WithdrawalStep.ChooseExchange,
|
|
1445
1598
|
}: {
|
|
1446
1599
|
setFlow: (string) => void;
|
|
1447
1600
|
initialStep?: WithdrawalStep;
|
|
@@ -1452,15 +1605,19 @@ const ExchangeFlow = ({
|
|
|
1452
1605
|
null,
|
|
1453
1606
|
);
|
|
1454
1607
|
const [userOp, setUserOp] = useState<any | null>(null);
|
|
1455
|
-
const
|
|
1456
|
-
|
|
1608
|
+
const setSelectedIntegration = useAppStore(
|
|
1609
|
+
(state) => state.setSelectedIntegration,
|
|
1610
|
+
);
|
|
1611
|
+
const selectedIntegration = useAppStore((s) => s.selectedIntegration);
|
|
1457
1612
|
|
|
1458
1613
|
useEffect(() => {
|
|
1459
|
-
return () =>
|
|
1614
|
+
return () => setSelectedIntegration(null);
|
|
1460
1615
|
}, []);
|
|
1461
1616
|
|
|
1462
1617
|
const currentStepComponent = (() => {
|
|
1463
1618
|
switch (currentStep) {
|
|
1619
|
+
case WithdrawalStep.ChooseExchange:
|
|
1620
|
+
return <ChooseExchangeStep setStep={setCurrentStep} />;
|
|
1464
1621
|
case WithdrawalStep.CheckSessionKey:
|
|
1465
1622
|
return <CheckSessionKeyStep setStep={setCurrentStep} />;
|
|
1466
1623
|
case WithdrawalStep.ChooseExchangeAsset:
|
|
@@ -1528,9 +1685,10 @@ const ExchangeFlow = ({
|
|
|
1528
1685
|
maxWidth={"16px"}
|
|
1529
1686
|
onClick={() => {
|
|
1530
1687
|
const index =
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1688
|
+
(selectedIntegration?.type === "delayed"
|
|
1689
|
+
? balanceSteps
|
|
1690
|
+
: withdrawalSteps
|
|
1691
|
+
).findIndex((step) => step === currentStep) - 1;
|
|
1534
1692
|
if (index > 0) {
|
|
1535
1693
|
setCurrentStep(withdrawalSteps[index]);
|
|
1536
1694
|
} else {
|
|
@@ -1554,7 +1712,7 @@ const ExchangeFlow = ({
|
|
|
1554
1712
|
width="100%"
|
|
1555
1713
|
>
|
|
1556
1714
|
<HeaderTitle>
|
|
1557
|
-
Deposit from {
|
|
1715
|
+
Deposit from {selectedIntegration?.name}
|
|
1558
1716
|
</HeaderTitle>
|
|
1559
1717
|
</Box>
|
|
1560
1718
|
|
|
@@ -17,18 +17,20 @@ import { CheckoutContext } from "../Checkout";
|
|
|
17
17
|
import { WalletCard, OptionCard } from "../cards";
|
|
18
18
|
import { WalletStatus } from "../cards/WalletCard";
|
|
19
19
|
import { useWalletIcon, useSmartAccountBalances } from "@/util/enso-hooks";
|
|
20
|
-
import ExchangeFlow, {
|
|
20
|
+
import ExchangeFlow, {
|
|
21
|
+
WithdrawalStep,
|
|
22
|
+
EXCHANGE_ICON_BY_TYPE,
|
|
23
|
+
ExchangeToIntegrationType,
|
|
24
|
+
} from "@/components/steps/ExchangeFlow";
|
|
21
25
|
import WalletFlow from "@/components/steps/WalletFlow/WalletFlow";
|
|
22
26
|
|
|
23
|
-
import BinanceIcon from "../../assets/BinanceBadge.svg";
|
|
24
|
-
|
|
25
27
|
const FLOWS = {
|
|
26
28
|
exchangeFlow: ExchangeFlow,
|
|
27
29
|
walletFlow: WalletFlow,
|
|
28
30
|
};
|
|
29
31
|
|
|
30
32
|
const FlowSelector = () => {
|
|
31
|
-
const { handleClose,
|
|
33
|
+
const { handleClose, enableExchange } = useContext(CheckoutContext);
|
|
32
34
|
const [flow, setFlow] = useState("");
|
|
33
35
|
const [initialStep, setInitialStep] = useState<string | number>("");
|
|
34
36
|
|
|
@@ -102,19 +104,33 @@ const FlowSelector = () => {
|
|
|
102
104
|
firstStep: WithdrawalStep.ChooseBalanceAsset,
|
|
103
105
|
});
|
|
104
106
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
+
console.log(
|
|
108
|
+
enableExchange,
|
|
109
|
+
enableExchange.map(
|
|
110
|
+
(integration) => EXCHANGE_ICON_BY_TYPE[integration],
|
|
111
|
+
),
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
if (Array.isArray(enableExchange) && enableExchange.length > 0)
|
|
107
115
|
options.unshift({
|
|
108
|
-
id: "
|
|
116
|
+
id: "exchange",
|
|
109
117
|
title: "Connect Exchange",
|
|
110
118
|
limit: "No Limit",
|
|
111
119
|
delay: "2 min",
|
|
112
|
-
icons:
|
|
120
|
+
icons: enableExchange
|
|
121
|
+
.map(
|
|
122
|
+
(integration) =>
|
|
123
|
+
EXCHANGE_ICON_BY_TYPE[
|
|
124
|
+
ExchangeToIntegrationType[integration]
|
|
125
|
+
],
|
|
126
|
+
)
|
|
127
|
+
.filter(Boolean),
|
|
113
128
|
flow: "exchangeFlow",
|
|
114
|
-
|
|
129
|
+
// Start at ChooseExchange to allow picking among multiple integrations
|
|
130
|
+
firstStep: WithdrawalStep.ChooseExchange,
|
|
115
131
|
});
|
|
116
132
|
return options;
|
|
117
|
-
}, [address,
|
|
133
|
+
}, [address, enableExchange, smartAccountTotal, isLoadingSmartAccount]);
|
|
118
134
|
|
|
119
135
|
const FlowComponent = flow && FLOWS[flow];
|
|
120
136
|
|