@avail-project/widgets 0.0.1

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 (143) hide show
  1. package/README.md +34 -0
  2. package/dist/common/components/ErrorBoundary.d.ts +44 -0
  3. package/dist/common/components/ErrorBoundary.d.ts.map +1 -0
  4. package/dist/common/components/ErrorBoundary.js +65 -0
  5. package/dist/common/hooks/useDebouncedCallback.d.ts +13 -0
  6. package/dist/common/hooks/useDebouncedCallback.d.ts.map +1 -0
  7. package/dist/common/hooks/useDebouncedCallback.js +42 -0
  8. package/dist/common/hooks/useDebouncedValue.d.ts +5 -0
  9. package/dist/common/hooks/useDebouncedValue.d.ts.map +1 -0
  10. package/dist/common/hooks/useDebouncedValue.js +15 -0
  11. package/dist/common/hooks/useInterval.d.ts +11 -0
  12. package/dist/common/hooks/useInterval.d.ts.map +1 -0
  13. package/dist/common/hooks/useInterval.js +25 -0
  14. package/dist/common/hooks/useLatest.d.ts +12 -0
  15. package/dist/common/hooks/useLatest.d.ts.map +1 -0
  16. package/dist/common/hooks/useLatest.js +19 -0
  17. package/dist/common/hooks/useNexusError.d.ts +20 -0
  18. package/dist/common/hooks/useNexusError.d.ts.map +1 -0
  19. package/dist/common/hooks/useNexusError.js +120 -0
  20. package/dist/common/hooks/usePolling.d.ts +7 -0
  21. package/dist/common/hooks/usePolling.d.ts.map +1 -0
  22. package/dist/common/hooks/usePolling.js +29 -0
  23. package/dist/common/hooks/useStableCallback.d.ts +6 -0
  24. package/dist/common/hooks/useStableCallback.d.ts.map +1 -0
  25. package/dist/common/hooks/useStableCallback.js +13 -0
  26. package/dist/common/hooks/useStopwatch.d.ts +17 -0
  27. package/dist/common/hooks/useStopwatch.d.ts.map +1 -0
  28. package/dist/common/hooks/useStopwatch.js +44 -0
  29. package/dist/common/hooks/useTransactionExecution.d.ts +62 -0
  30. package/dist/common/hooks/useTransactionExecution.d.ts.map +1 -0
  31. package/dist/common/hooks/useTransactionExecution.js +273 -0
  32. package/dist/common/hooks/useTransactionFlow.d.ts +71 -0
  33. package/dist/common/hooks/useTransactionFlow.d.ts.map +1 -0
  34. package/dist/common/hooks/useTransactionFlow.js +435 -0
  35. package/dist/common/index.d.ts +17 -0
  36. package/dist/common/index.d.ts.map +1 -0
  37. package/dist/common/index.js +16 -0
  38. package/dist/common/tx/steps.d.ts +19 -0
  39. package/dist/common/tx/steps.d.ts.map +1 -0
  40. package/dist/common/tx/steps.js +89 -0
  41. package/dist/common/tx/types.d.ts +11 -0
  42. package/dist/common/tx/types.d.ts.map +1 -0
  43. package/dist/common/tx/types.js +19 -0
  44. package/dist/common/tx/useTransactionSteps.d.ts +21 -0
  45. package/dist/common/tx/useTransactionSteps.d.ts.map +1 -0
  46. package/dist/common/tx/useTransactionSteps.js +40 -0
  47. package/dist/common/types/transaction-flow.d.ts +48 -0
  48. package/dist/common/types/transaction-flow.d.ts.map +1 -0
  49. package/dist/common/types/transaction-flow.js +2 -0
  50. package/dist/common/utils/constant.d.ts +99 -0
  51. package/dist/common/utils/constant.d.ts.map +1 -0
  52. package/dist/common/utils/constant.js +370 -0
  53. package/dist/common/utils/token-pricing.d.ts +33 -0
  54. package/dist/common/utils/token-pricing.d.ts.map +1 -0
  55. package/dist/common/utils/token-pricing.js +255 -0
  56. package/dist/common/utils/transaction-flow.d.ts +35 -0
  57. package/dist/common/utils/transaction-flow.d.ts.map +1 -0
  58. package/dist/common/utils/transaction-flow.js +65 -0
  59. package/dist/index.d.ts +5 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +2 -0
  62. package/dist/lib/utils.d.ts +4 -0
  63. package/dist/lib/utils.d.ts.map +1 -0
  64. package/dist/lib/utils.js +8 -0
  65. package/dist/nexus/NexusProvider.d.ts +50 -0
  66. package/dist/nexus/NexusProvider.d.ts.map +1 -0
  67. package/dist/nexus/NexusProvider.js +572 -0
  68. package/dist/nexus-widget/components/address-identicon.d.ts +5 -0
  69. package/dist/nexus-widget/components/address-identicon.d.ts.map +1 -0
  70. package/dist/nexus-widget/components/address-identicon.js +39 -0
  71. package/dist/nexus-widget/components/amount-input-unified.d.ts +18 -0
  72. package/dist/nexus-widget/components/amount-input-unified.d.ts.map +1 -0
  73. package/dist/nexus-widget/components/amount-input-unified.js +88 -0
  74. package/dist/nexus-widget/components/deposit-idle-form.d.ts +29 -0
  75. package/dist/nexus-widget/components/deposit-idle-form.d.ts.map +1 -0
  76. package/dist/nexus-widget/components/deposit-idle-form.js +506 -0
  77. package/dist/nexus-widget/components/nexus-widget-progress-screen.d.ts +36 -0
  78. package/dist/nexus-widget/components/nexus-widget-progress-screen.d.ts.map +1 -0
  79. package/dist/nexus-widget/components/nexus-widget-progress-screen.js +737 -0
  80. package/dist/nexus-widget/components/pay-using-selector.d.ts +9 -0
  81. package/dist/nexus-widget/components/pay-using-selector.d.ts.map +1 -0
  82. package/dist/nexus-widget/components/pay-using-selector.js +37 -0
  83. package/dist/nexus-widget/components/pay-with-sources.d.ts +11 -0
  84. package/dist/nexus-widget/components/pay-with-sources.d.ts.map +1 -0
  85. package/dist/nexus-widget/components/pay-with-sources.js +266 -0
  86. package/dist/nexus-widget/components/receive-asset-selector.d.ts +28 -0
  87. package/dist/nexus-widget/components/receive-asset-selector.d.ts.map +1 -0
  88. package/dist/nexus-widget/components/receive-asset-selector.js +1178 -0
  89. package/dist/nexus-widget/components/recipient-input.d.ts +10 -0
  90. package/dist/nexus-widget/components/recipient-input.d.ts.map +1 -0
  91. package/dist/nexus-widget/components/recipient-input.js +44 -0
  92. package/dist/nexus-widget/components/send-idle-form.d.ts +29 -0
  93. package/dist/nexus-widget/components/send-idle-form.d.ts.map +1 -0
  94. package/dist/nexus-widget/components/send-idle-form.js +548 -0
  95. package/dist/nexus-widget/components/status-alerts.d.ts +7 -0
  96. package/dist/nexus-widget/components/status-alerts.d.ts.map +1 -0
  97. package/dist/nexus-widget/components/status-alerts.js +17 -0
  98. package/dist/nexus-widget/components/swap-asset-selector.d.ts +74 -0
  99. package/dist/nexus-widget/components/swap-asset-selector.d.ts.map +1 -0
  100. package/dist/nexus-widget/components/swap-asset-selector.js +1910 -0
  101. package/dist/nexus-widget/components/swap-idle-form.d.ts +29 -0
  102. package/dist/nexus-widget/components/swap-idle-form.d.ts.map +1 -0
  103. package/dist/nexus-widget/components/swap-idle-form.js +1289 -0
  104. package/dist/nexus-widget/components/swap-intent-preview.d.ts +95 -0
  105. package/dist/nexus-widget/components/swap-intent-preview.d.ts.map +1 -0
  106. package/dist/nexus-widget/components/swap-intent-preview.js +1050 -0
  107. package/dist/nexus-widget/nexus-widget.d.ts +4 -0
  108. package/dist/nexus-widget/nexus-widget.d.ts.map +1 -0
  109. package/dist/nexus-widget/nexus-widget.js +7819 -0
  110. package/dist/nexus-widget/sdk-types.d.ts +13 -0
  111. package/dist/nexus-widget/sdk-types.d.ts.map +1 -0
  112. package/dist/nexus-widget/sdk-types.js +1 -0
  113. package/dist/nexus-widget/theme.d.ts +156 -0
  114. package/dist/nexus-widget/theme.d.ts.map +1 -0
  115. package/dist/nexus-widget/theme.js +159 -0
  116. package/dist/nexus-widget/types.d.ts +141 -0
  117. package/dist/nexus-widget/types.d.ts.map +1 -0
  118. package/dist/nexus-widget/types.js +1 -0
  119. package/dist/nexus-widget/utils/citrea-tokens.d.ts +82 -0
  120. package/dist/nexus-widget/utils/citrea-tokens.d.ts.map +1 -0
  121. package/dist/nexus-widget/utils/citrea-tokens.js +136 -0
  122. package/dist/nexus-widget/utils/deposit-source-selection.d.ts +55 -0
  123. package/dist/nexus-widget/utils/deposit-source-selection.d.ts.map +1 -0
  124. package/dist/nexus-widget/utils/deposit-source-selection.js +219 -0
  125. package/dist/swaps/components/stacked-token-icons.d.ts +15 -0
  126. package/dist/swaps/components/stacked-token-icons.d.ts.map +1 -0
  127. package/dist/swaps/components/stacked-token-icons.js +38 -0
  128. package/dist/swaps/components/step-flow.d.ts +32 -0
  129. package/dist/swaps/components/step-flow.d.ts.map +1 -0
  130. package/dist/swaps/components/step-flow.js +54 -0
  131. package/dist/swaps/components/token-icon.d.ts +11 -0
  132. package/dist/swaps/components/token-icon.d.ts.map +1 -0
  133. package/dist/swaps/components/token-icon.js +16 -0
  134. package/dist/swaps/components/transaction-progress.d.ts +43 -0
  135. package/dist/swaps/components/transaction-progress.d.ts.map +1 -0
  136. package/dist/swaps/components/transaction-progress.js +94 -0
  137. package/dist/ui/button.d.ts +11 -0
  138. package/dist/ui/button.d.ts.map +1 -0
  139. package/dist/ui/button.js +34 -0
  140. package/dist/ui/dialog.d.ts +17 -0
  141. package/dist/ui/dialog.d.ts.map +1 -0
  142. package/dist/ui/dialog.js +47 -0
  143. package/package.json +60 -0
@@ -0,0 +1,737 @@
1
+ // biome-ignore-all lint: NexusWidget registry component from shadcn registry.
2
+ "use client";
3
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
+ import Decimal from "decimal.js";
5
+ import { Check, ChevronDown, Loader2, X } from "lucide-react";
6
+ import React, { useEffect, useState } from "react";
7
+ import { getShortChainName } from "../../common/utils/constant";
8
+ import {} from "../types";
9
+ import {} from "./swap-asset-selector";
10
+ import {} from "./swap-intent-preview";
11
+ const fontFamily = '"Geist", var(--font-geist-sans), system-ui, sans-serif';
12
+ const primary = "var(--foreground-primary, #161615)";
13
+ const muted = "var(--foreground-muted, #848483)";
14
+ const border = "var(--border-default, #E8E8E7)";
15
+ const brand = "var(--foreground-brand)";
16
+ const danger = "var(--foreground-negative, #E92C2C)";
17
+ const parseDecimal = (value) => {
18
+ if (value === null || value === undefined || value === "")
19
+ return undefined;
20
+ if (Decimal.isDecimal(value))
21
+ return value;
22
+ const cleaned = String(value).replace(/[^0-9.-]/g, "");
23
+ if (!cleaned || cleaned === "-" || cleaned === "." || cleaned === "-.") {
24
+ return undefined;
25
+ }
26
+ try {
27
+ const parsed = new Decimal(cleaned);
28
+ return parsed.isFinite() ? parsed : undefined;
29
+ }
30
+ catch {
31
+ return undefined;
32
+ }
33
+ };
34
+ const formatDecimal = (value, decimals = 2) => (parseDecimal(value) ?? new Decimal(0)).toDecimalPlaces(decimals).toFixed();
35
+ const formatUsd = (value) => `$${formatDecimal(value, 2)}`;
36
+ const unique = (values) => Array.from(new Set(values.filter(Boolean)));
37
+ const formatSymbolSummary = (symbols) => {
38
+ if (symbols.length <= 2)
39
+ return symbols.join(", ");
40
+ return `${symbols.slice(0, 2).join(", ")} and ${symbols.length - 2} others`;
41
+ };
42
+ const getStepType = (step) => String(step?.type ?? step?.typeID ?? "").toUpperCase();
43
+ const PROGRESS_EVENT_NAMES = {
44
+ BRIDGE_PLAN_LIST: "bridge_plan_list",
45
+ BRIDGE_PLAN_PROGRESS: "bridge_plan_progress",
46
+ SWAP_PLAN_LIST: "swap_plan_list",
47
+ SWAP_PLAN_PROGRESS: "swap_plan_progress",
48
+ };
49
+ const STATUS_ORDER = [
50
+ "approveTokens",
51
+ "swapTokens",
52
+ "receiveToken",
53
+ "action",
54
+ ];
55
+ const SWAP_APPROVAL_TYPES = [
56
+ "SOURCE_SWAP",
57
+ "CREATE_PERMIT_EOA_TO_EPHEMERAL",
58
+ "CREATE_PERMIT_FOR_SOURCE_SWAP",
59
+ "EOA_TO_EPHEMERAL_TRANSFER",
60
+ "EOA_EXECUTE_CALL",
61
+ // "BRIDGE_DEPOSIT",
62
+ ];
63
+ const REFUND_ELIGIBLE_SWAP_TYPES = [
64
+ "BRIDGE_INTENT_SUBMISSION",
65
+ "BRIDGE_DEPOSIT",
66
+ ];
67
+ const DESTINATION_SWAP_TYPES = [
68
+ "DESTINATION_SWAP",
69
+ "DESTINATION_SWAP_BATCH_TX",
70
+ "DESTINATION_SWAP_HASH",
71
+ ];
72
+ const BRIDGE_FILL_RECEIVE_TYPES = ["BRIDGE_FILL"];
73
+ const getStatusForStep = (step, mode, hasTransferAction = false) => {
74
+ const type = getStepType(step);
75
+ if (type === "APPROVAL" ||
76
+ type === "TRANSACTION_SENT" ||
77
+ type === "TRANSACTION_CONFIRMED") {
78
+ return mode === "swap" && !hasTransferAction ? null : "action";
79
+ }
80
+ if (type.includes("SWAP_START")) {
81
+ return "swapTokens";
82
+ }
83
+ if (SWAP_APPROVAL_TYPES.some((token) => type.includes(token))) {
84
+ return "approveTokens";
85
+ }
86
+ if (type.includes("SOURCE_SWAP") ||
87
+ type.includes("SOURCE_BATCH") ||
88
+ type.includes("SWAP_SOURCE") ||
89
+ type.includes("BRIDGE_DEPOSIT") ||
90
+ type.includes("BRIDGE_FILL") ||
91
+ type.includes("BRIDGE_INTENT_SUBMISSION") ||
92
+ type.includes("SWAP_COMPLETE") ||
93
+ type.includes("SWAP_SKIPPED")) {
94
+ return "swapTokens";
95
+ }
96
+ if (type.includes("DESTINATION_SWAP") || type.includes("DESTINATION_BATCH")) {
97
+ return "receiveToken";
98
+ }
99
+ return null;
100
+ };
101
+ const stepMatches = (step, tokens) => {
102
+ const type = getStepType(step);
103
+ return tokens.some((token) => type.includes(token));
104
+ };
105
+ const hasCompletedType = (events, steps, tokens) => {
106
+ const completedEvent = events.some((event) => event.completed && stepMatches(event.step, tokens));
107
+ if (completedEvent)
108
+ return true;
109
+ return steps.some((item) => item.completed && stepMatches(item.step, tokens));
110
+ };
111
+ const hasStepType = (events, steps, tokens) => events.some((event) => stepMatches(event.step, tokens) ||
112
+ (event.steps ?? []).some((step) => stepMatches(step, tokens))) || steps.some((item) => stepMatches(item.step, tokens));
113
+ const hasEventType = (events, tokens) => events.some((event) => stepMatches(event.step, tokens) ||
114
+ (event.steps ?? []).some((step) => stepMatches(step, tokens)));
115
+ const hasProgressEventType = (events, tokens) => events.some((event) => (event.name === PROGRESS_EVENT_NAMES.BRIDGE_PLAN_PROGRESS ||
116
+ event.name === PROGRESS_EVENT_NAMES.SWAP_PLAN_PROGRESS) &&
117
+ stepMatches(event.step, tokens));
118
+ const getListedSteps = (events, eventName) => {
119
+ const listEvent = [...events]
120
+ .reverse()
121
+ .find((event) => event.name === eventName && (event.steps?.length ?? 0) > 0);
122
+ return listEvent?.steps ?? [];
123
+ };
124
+ const countListedSteps = (steps, tokens) => steps.filter((step) => stepMatches(step, tokens)).length;
125
+ const getStepSwaps = (step) => {
126
+ const swaps = step?.swaps;
127
+ return Array.isArray(swaps) ? swaps : [];
128
+ };
129
+ const getApprovalUnitsForStep = (step) => {
130
+ if (!stepMatches(step, SWAP_APPROVAL_TYPES))
131
+ return [];
132
+ const swaps = getStepSwaps(step);
133
+ if (swaps.length > 0) {
134
+ return swaps.map((swap) => ({
135
+ symbol: typeof swap?.input?.symbol === "string" ? swap.input.symbol : undefined,
136
+ }));
137
+ }
138
+ const assetSymbol = step?.asset?.symbol;
139
+ const tokenSymbol = step?.token?.symbol;
140
+ return [
141
+ {
142
+ symbol: typeof assetSymbol === "string"
143
+ ? assetSymbol
144
+ : typeof tokenSymbol === "string"
145
+ ? tokenSymbol
146
+ : undefined,
147
+ },
148
+ ];
149
+ };
150
+ const countApprovalUnits = (steps) => steps.reduce((sum, step) => sum + getApprovalUnitsForStep(step).length, 0);
151
+ const countCompletedApprovalUnitsFromEvents = (events) => events.reduce((sum, event) => {
152
+ if (event.name !== PROGRESS_EVENT_NAMES.SWAP_PLAN_PROGRESS ||
153
+ !event.completed) {
154
+ return sum;
155
+ }
156
+ return sum + getApprovalUnitsForStep(event.step).length;
157
+ }, 0);
158
+ const countCompletedApprovalUnitsFromSteps = (steps) => steps.reduce((sum, item) => item.completed ? sum + getApprovalUnitsForStep(item.step).length : sum, 0);
159
+ const getApprovalUnitSymbols = (steps) => steps
160
+ .flatMap((step) => getApprovalUnitsForStep(step))
161
+ .map((unit) => unit.symbol)
162
+ .filter(Boolean);
163
+ const getNumericEventIndex = (...values) => {
164
+ for (const value of values) {
165
+ if (typeof value === "number" && Number.isInteger(value) && value >= 0) {
166
+ return value;
167
+ }
168
+ if (typeof value === "string" && /^\d+$/.test(value)) {
169
+ return Number(value);
170
+ }
171
+ }
172
+ return undefined;
173
+ };
174
+ const getApprovalIndexFromEvent = (event) => {
175
+ const rawEvent = event?.event;
176
+ const rawStep = event?.step;
177
+ return getNumericEventIndex(rawEvent?.approvalIndex, rawEvent?.swapIndex, rawEvent?.currentIndex, rawEvent?.index, rawEvent?.data?.approvalIndex, rawEvent?.data?.swapIndex, rawEvent?.data?.currentIndex, rawEvent?.data?.index, rawStep?.approvalIndex, rawStep?.swapIndex, rawStep?.currentIndex, rawStep?.index, rawStep?.data?.approvalIndex, rawStep?.data?.swapIndex, rawStep?.data?.currentIndex, rawStep?.data?.index);
178
+ };
179
+ const getActiveApprovalProgressEvent = (events) => [...events]
180
+ .reverse()
181
+ .find((event) => event.name === PROGRESS_EVENT_NAMES.SWAP_PLAN_PROGRESS &&
182
+ !event.completed &&
183
+ getApprovalUnitsForStep(event.step).length > 0);
184
+ const getApprovalSymbolFromProgressEvent = (event) => {
185
+ const units = getApprovalUnitsForStep(event?.step);
186
+ if (units.length === 0)
187
+ return undefined;
188
+ if (units.length === 1)
189
+ return units[0]?.symbol;
190
+ const index = getApprovalIndexFromEvent(event);
191
+ if (index === undefined || index >= units.length)
192
+ return undefined;
193
+ return units[index]?.symbol;
194
+ };
195
+ const getApprovalTotalFromSwapStepsList = (events) => countApprovalUnits(getListedSteps(events, PROGRESS_EVENT_NAMES.SWAP_PLAN_LIST));
196
+ const hasStartedStatus = (events, id, mode, hasTransferAction = false) => events.some((event) => getStatusForStep(event.step, mode, hasTransferAction) === id);
197
+ const buildStatusRows = ({ events, failedStep, mode, steps, approvalTotalCount, context, }) => {
198
+ const hasTransferAction = mode === "send" || (mode === "swap" && Boolean(context.recipientAddress));
199
+ const failedStatus = failedStep
200
+ ? getStatusForStep(failedStep, mode, hasTransferAction)
201
+ : null;
202
+ const swapListSteps = getListedSteps(events, PROGRESS_EVENT_NAMES.SWAP_PLAN_LIST);
203
+ const fallbackSteps = steps.map((item) => item.step);
204
+ const destinationSymbol = context.destinationSymbol || "token";
205
+ const destinationChain = context.destinationChain || "destination";
206
+ const opportunityName = context.opportunityName || "app";
207
+ const immutableApprovalTotal = approvalTotalCount ??
208
+ Math.max(countApprovalUnits(swapListSteps), countApprovalUnits(fallbackSteps), countCompletedApprovalUnitsFromEvents(events));
209
+ const refundEligibleFailure = failedStep !== null &&
210
+ failedStep !== undefined &&
211
+ stepMatches(failedStep, REFUND_ELIGIBLE_SWAP_TYPES);
212
+ const approvalCompletedCount = Math.min(immutableApprovalTotal || Number.MAX_SAFE_INTEGER, Math.max(countCompletedApprovalUnitsFromEvents(events), countCompletedApprovalUnitsFromSteps(steps)));
213
+ const approvalSymbols = getApprovalUnitSymbols(swapListSteps.length > 0 ? swapListSteps : fallbackSteps);
214
+ const activeApprovalSymbol = getApprovalSymbolFromProgressEvent(getActiveApprovalProgressEvent(events));
215
+ const hasSwapList = swapListSteps.length > 0 ||
216
+ hasStepType(events, steps, [
217
+ "SWAP_START",
218
+ "DETERMINING_SWAP",
219
+ "SOURCE_SWAP",
220
+ "DESTINATION_SWAP",
221
+ "BRIDGE_DEPOSIT",
222
+ "BRIDGE_FILL",
223
+ "BRIDGE_INTENT_SUBMISSION",
224
+ "SWAP_COMPLETE",
225
+ "SWAP_SKIPPED",
226
+ ]);
227
+ const hasDestinationReceiveStep = countListedSteps(swapListSteps, DESTINATION_SWAP_TYPES) > 0 ||
228
+ countListedSteps(fallbackSteps, DESTINATION_SWAP_TYPES) > 0 ||
229
+ hasProgressEventType(events, DESTINATION_SWAP_TYPES);
230
+ const receiveTokenTypes = hasDestinationReceiveStep
231
+ ? DESTINATION_SWAP_TYPES
232
+ : BRIDGE_FILL_RECEIVE_TYPES;
233
+ const hasReceiveTokenStep = hasDestinationReceiveStep ||
234
+ countListedSteps(swapListSteps, receiveTokenTypes) > 0 ||
235
+ countListedSteps(fallbackSteps, receiveTokenTypes) > 0 ||
236
+ hasProgressEventType(events, receiveTokenTypes);
237
+ const receiveTokenStarted = hasProgressEventType(events, receiveTokenTypes);
238
+ const receiveTokenComplete = hasReceiveTokenStep && hasCompletedType(events, steps, receiveTokenTypes);
239
+ const swapComplete = hasCompletedType(events, steps, [
240
+ "SWAP_COMPLETE",
241
+ "SWAP_SKIPPED",
242
+ ]);
243
+ const swapSkipped = hasCompletedType(events, steps, ["SWAP_SKIPPED"]);
244
+ const shouldShowSwapRows = hasSwapList && !(swapSkipped && (mode === "deposit" || mode === "send"));
245
+ const swapTokensComplete = hasReceiveTokenStep
246
+ ? receiveTokenStarted
247
+ : swapComplete;
248
+ const transactionSent = hasCompletedType(events, steps, ["TRANSACTION_SENT"]);
249
+ const transactionConfirmed = hasCompletedType(events, steps, [
250
+ "TRANSACTION_CONFIRMED",
251
+ ]);
252
+ const rows = [];
253
+ const pushRow = (row) => {
254
+ if (failedStatus) {
255
+ const failedIndex = STATUS_ORDER.indexOf(failedStatus);
256
+ const currentIndex = STATUS_ORDER.indexOf(row.id);
257
+ if (failedIndex >= 0 && currentIndex > failedIndex)
258
+ return;
259
+ }
260
+ rows.push(row);
261
+ };
262
+ if (immutableApprovalTotal > 0) {
263
+ const approvalCurrent = Math.min(immutableApprovalTotal, Math.max(1, approvalCompletedCount + 1));
264
+ const approvalSymbol = activeApprovalSymbol ??
265
+ approvalSymbols[Math.min(approvalCompletedCount, approvalSymbols.length - 1)];
266
+ const approvalDescription = approvalSymbol
267
+ ? `Approve ${approvalSymbol} in wallet`
268
+ : "Approve in wallet";
269
+ let state = "default";
270
+ if (failedStatus === "approveTokens") {
271
+ state = "error";
272
+ }
273
+ else if (approvalCompletedCount >= immutableApprovalTotal) {
274
+ state = "completed";
275
+ }
276
+ else if (hasStartedStatus(events, "approveTokens", mode, hasTransferAction) ||
277
+ events.length === 0) {
278
+ state = "preapproval";
279
+ }
280
+ const approvalSteps = (swapListSteps.length > 0 ? swapListSteps : fallbackSteps).filter((step) => stepMatches(step, SWAP_APPROVAL_TYPES));
281
+ const currentApprovalStep = approvalSteps[approvalCompletedCount];
282
+ const activeSymbol = currentApprovalStep
283
+ ? currentApprovalStep.symbol
284
+ : undefined;
285
+ pushRow({
286
+ id: "approveTokens",
287
+ state,
288
+ description: state === "preapproval" ? approvalDescription : undefined,
289
+ label: state === "completed"
290
+ ? `Approved Swaps (${immutableApprovalTotal} of ${immutableApprovalTotal})`
291
+ : state === "error"
292
+ ? "Collection failed"
293
+ : `Approve Swaps (${approvalCurrent} of ${immutableApprovalTotal})`,
294
+ });
295
+ }
296
+ if (shouldShowSwapRows) {
297
+ const approvalsSatisfied = immutableApprovalTotal === 0 ||
298
+ approvalCompletedCount >= immutableApprovalTotal;
299
+ let state = "default";
300
+ if (failedStatus === "swapTokens") {
301
+ state = "error";
302
+ }
303
+ else if (swapTokensComplete) {
304
+ state = "completed";
305
+ }
306
+ else if (approvalsSatisfied &&
307
+ (hasStartedStatus(events, "swapTokens", mode, hasTransferAction) ||
308
+ hasEventType(events, [
309
+ "DESTINATION_SWAP_BATCH_TX",
310
+ "BRIDGE_DEPOSIT",
311
+ "SOURCE_SWAP_BATCH_TX",
312
+ "SOURCE_SWAP_HASH",
313
+ "SWAP_START",
314
+ ]))) {
315
+ state = "inProgress";
316
+ }
317
+ pushRow({
318
+ id: "swapTokens",
319
+ state,
320
+ label: state === "completed"
321
+ ? "Swaps completed"
322
+ : state === "error"
323
+ ? refundEligibleFailure
324
+ ? "Swap failed. Refund initiated"
325
+ : "Swap failed"
326
+ : state === "inProgress"
327
+ ? "Swaps in progress"
328
+ : "Swap tokens",
329
+ });
330
+ if (hasReceiveTokenStep) {
331
+ pushRow({
332
+ id: "receiveToken",
333
+ state: failedStatus === "receiveToken"
334
+ ? "error"
335
+ : receiveTokenComplete
336
+ ? "completed"
337
+ : receiveTokenStarted
338
+ ? "inProgress"
339
+ : "default",
340
+ label: failedStatus === "receiveToken"
341
+ ? refundEligibleFailure
342
+ ? "Destination swap failed. Refund initiated."
343
+ : "Destination swap failed."
344
+ : receiveTokenComplete
345
+ ? `Received ${destinationSymbol} on ${destinationChain}`
346
+ : receiveTokenStarted
347
+ ? `Receiving ${destinationSymbol} on ${destinationChain}`
348
+ : `Receive ${destinationSymbol} on ${destinationChain}`,
349
+ });
350
+ }
351
+ }
352
+ if (mode === "deposit" || hasTransferAction) {
353
+ const receiveComplete = swapSkipped ||
354
+ !shouldShowSwapRows ||
355
+ (hasReceiveTokenStep ? receiveTokenComplete : swapTokensComplete);
356
+ const isDeposit = mode === "deposit";
357
+ let state = "default";
358
+ if (failedStatus === "action") {
359
+ state = "error";
360
+ }
361
+ else if (transactionConfirmed) {
362
+ state = "completed";
363
+ }
364
+ else if (transactionSent) {
365
+ state = "inProgress";
366
+ }
367
+ else if (receiveComplete) {
368
+ state = "preapproval";
369
+ }
370
+ pushRow({
371
+ id: "action",
372
+ state,
373
+ description: state === "preapproval" ? "Approve in wallet" : undefined,
374
+ label: isDeposit
375
+ ? state === "completed"
376
+ ? `${destinationSymbol} deposited to ${opportunityName}`
377
+ : state === "inProgress"
378
+ ? `Depositing ${destinationSymbol} to ${opportunityName}`
379
+ : state === "error"
380
+ ? "Deposit failed. Funds are in your wallet."
381
+ : state === "preapproval"
382
+ ? `Approve Deposit of ${destinationSymbol} to ${opportunityName}`
383
+ : `Deposit ${destinationSymbol} to ${opportunityName}`
384
+ : state === "completed"
385
+ ? `${destinationSymbol} sent`
386
+ : state === "inProgress"
387
+ ? `Sending ${destinationSymbol}`
388
+ : state === "error"
389
+ ? "Send failed. Funds are in your wallet."
390
+ : state === "preapproval"
391
+ ? `Approve ${destinationSymbol} transfer`
392
+ : `Send ${destinationSymbol}`,
393
+ });
394
+ }
395
+ const orderedRows = rows.sort((a, b) => STATUS_ORDER.indexOf(a.id) - STATUS_ORDER.indexOf(b.id));
396
+ if (orderedRows.some((row) => row.state === "preapproval" || row.state === "inProgress") ||
397
+ orderedRows.some((row) => row.state === "error")) {
398
+ return orderedRows;
399
+ }
400
+ const nextActiveIndex = orderedRows.findIndex((row) => row.state === "default");
401
+ if (nextActiveIndex === -1)
402
+ return orderedRows;
403
+ return orderedRows.map((row, index) => {
404
+ if (index !== nextActiveIndex)
405
+ return row;
406
+ const nextState = row.id === "approveTokens" || row.id === "action"
407
+ ? "preapproval"
408
+ : "inProgress";
409
+ return {
410
+ ...row,
411
+ description: nextState === "preapproval" ? "Approve in wallet" : undefined,
412
+ label: row.id === "swapTokens"
413
+ ? "Swaps in progress"
414
+ : row.id === "receiveToken"
415
+ ? `Receiving ${destinationSymbol} on ${destinationChain}`
416
+ : row.label,
417
+ state: nextState,
418
+ };
419
+ });
420
+ };
421
+ function MiniLogo({ src, label, size, style, }) {
422
+ const [failed, setFailed] = useState(!src);
423
+ useEffect(() => {
424
+ setFailed(!src);
425
+ }, [src]);
426
+ if (!failed && src) {
427
+ return (_jsx("img", { alt: label || "", onError: () => setFailed(true), src: src, style: {
428
+ background: "#FFFFFE",
429
+ borderRadius: "999px",
430
+ height: size,
431
+ objectFit: "cover",
432
+ width: size,
433
+ ...style,
434
+ } }));
435
+ }
436
+ return (_jsx("span", { style: {
437
+ alignItems: "center",
438
+ background: "#E8F0FF",
439
+ borderRadius: "999px",
440
+ color: brand,
441
+ display: "inline-flex",
442
+ fontFamily,
443
+ fontSize: Math.max(10, Math.round(size * 0.42)),
444
+ fontWeight: 700,
445
+ height: size,
446
+ justifyContent: "center",
447
+ width: size,
448
+ ...style,
449
+ }, children: (label || "?").trim().slice(0, 1).toUpperCase() }));
450
+ }
451
+ function TokenLogoPair({ tokenLogo, chainLogo, tokenSymbol, chainName, }) {
452
+ return (_jsxs("span", { style: {
453
+ display: "inline-flex",
454
+ flexShrink: 0,
455
+ height: 27,
456
+ position: "relative",
457
+ width: 27,
458
+ }, children: [_jsx(MiniLogo, { label: tokenSymbol, size: 27, src: tokenLogo }), chainLogo && (_jsx(MiniLogo, { label: chainName, size: 12, src: chainLogo, style: {
459
+ bottom: -1,
460
+ outline: "1px solid #FFFFFE",
461
+ position: "absolute",
462
+ right: -1,
463
+ } }))] }));
464
+ }
465
+ export function NexusWidgetProgressScreen({ fromTokens = [], toToken, fromAmountUsd, toAmount, toAmountUsd, totalFeeUsd, intentData, mode, opportunity, steps, progressEvents = [], failedStep, recipientAddress, }) {
466
+ const intentSources = intentData?.sources ?? [];
467
+ const intentDestination = intentData?.destination;
468
+ const destinationSourceToken = fromTokens.find((token) => {
469
+ const destinationChainId = intentDestination?.chain.id ?? toToken?.chainId;
470
+ const destinationTokenAddress = (intentDestination?.token.contractAddress ??
471
+ toToken?.contractAddress ??
472
+ "").toLowerCase();
473
+ const tokenAmount = parseDecimal(token.userAmount) ?? parseDecimal(token.balance);
474
+ return (destinationChainId !== undefined &&
475
+ destinationTokenAddress !== "" &&
476
+ token.chainId === destinationChainId &&
477
+ token.contractAddress.toLowerCase() === destinationTokenAddress &&
478
+ Boolean(tokenAmount && tokenAmount.gt(0)));
479
+ });
480
+ const sourceSymbols = unique([
481
+ ...(destinationSourceToken ? [destinationSourceToken.symbol] : []),
482
+ ...(intentSources.length > 0
483
+ ? intentSources.map((source) => source.token.symbol)
484
+ : fromTokens.map((token) => token.symbol)),
485
+ ]);
486
+ const intentSourceUsd = intentSources.length > 0
487
+ ? intentSources.reduce((sum, source) => sum.plus(parseDecimal(source.value) ?? 0), new Decimal(0))
488
+ : parseDecimal(fromAmountUsd);
489
+ const requestedDestinationAmount = parseDecimal(toAmount);
490
+ const quotedDestinationAmount = parseDecimal(intentDestination?.amount);
491
+ const destinationBalanceAmount = parseDecimal(toToken?.balance);
492
+ const requestedDestinationUsd = parseDecimal(toAmountUsd);
493
+ const destinationUsdRate = requestedDestinationAmount &&
494
+ requestedDestinationAmount.gt(0) &&
495
+ requestedDestinationUsd &&
496
+ requestedDestinationUsd.gt(0)
497
+ ? requestedDestinationUsd.div(requestedDestinationAmount)
498
+ : quotedDestinationAmount &&
499
+ quotedDestinationAmount.gt(0) &&
500
+ intentDestination?.value
501
+ ? (parseDecimal(intentDestination.value) ?? new Decimal(0)).div(quotedDestinationAmount)
502
+ : undefined;
503
+ const destinationCoverageUsd = (mode === "deposit" || mode === "send") &&
504
+ requestedDestinationAmount &&
505
+ requestedDestinationAmount.gt(0) &&
506
+ quotedDestinationAmount &&
507
+ requestedDestinationAmount.gt(quotedDestinationAmount) &&
508
+ destinationBalanceAmount &&
509
+ destinationBalanceAmount.gt(0) &&
510
+ destinationUsdRate &&
511
+ destinationUsdRate.gt(0)
512
+ ? Decimal.min(requestedDestinationAmount.minus(quotedDestinationAmount), destinationBalanceAmount).mul(destinationUsdRate)
513
+ : undefined;
514
+ const quotedDestinationUsd = parseDecimal(intentDestination?.value);
515
+ const feeUsd = parseDecimal(totalFeeUsd);
516
+ const sourceUsd = mode === "deposit" || mode === "send"
517
+ ? [
518
+ destinationCoverageUsd !== undefined
519
+ ? (intentSourceUsd ?? new Decimal(0)).plus(destinationCoverageUsd)
520
+ : intentSourceUsd,
521
+ requestedDestinationUsd,
522
+ requestedDestinationUsd &&
523
+ requestedDestinationUsd.gt(0) &&
524
+ intentSourceUsd &&
525
+ intentSourceUsd.gt(0) &&
526
+ quotedDestinationUsd &&
527
+ quotedDestinationUsd.gt(0)
528
+ ? requestedDestinationUsd.plus(Decimal.max(intentSourceUsd.minus(quotedDestinationUsd), 0))
529
+ : undefined,
530
+ requestedDestinationUsd &&
531
+ requestedDestinationUsd.gt(0) &&
532
+ feeUsd &&
533
+ feeUsd.gt(0)
534
+ ? requestedDestinationUsd.plus(feeUsd)
535
+ : undefined,
536
+ ]
537
+ .filter((value) => Boolean(value && value.gt(0)))
538
+ .reduce((max, value) => (!max || value.gt(max) ? value : max), undefined)
539
+ : intentSourceUsd;
540
+ const destinationAmount = (mode === "deposit" || mode === "send") && toAmount
541
+ ? toAmount
542
+ : (intentDestination?.amount ?? toAmount ?? "0");
543
+ const destinationSymbol = intentDestination?.token.symbol ||
544
+ toToken?.symbol ||
545
+ opportunity?.tokenSymbol ||
546
+ "";
547
+ const destinationChainName = getShortChainName(intentDestination?.chain.id ?? toToken?.chainId, intentDestination?.chain.name || toToken?.chainName || "");
548
+ const destinationChain = mode === "deposit"
549
+ ? opportunity?.title || opportunity?.protocol || destinationChainName
550
+ : destinationChainName;
551
+ const seededApprovalTotal = countApprovalUnits((steps ?? []).map((item) => item.step));
552
+ const completedApprovalEventTotal = countCompletedApprovalUnitsFromEvents(progressEvents);
553
+ const computedApprovalTotal = Math.max(getApprovalTotalFromSwapStepsList(progressEvents), seededApprovalTotal, completedApprovalEventTotal);
554
+ const [lockedApprovalTotal, setLockedApprovalTotal] = useState(null);
555
+ const approvalTotalCount = lockedApprovalTotal ??
556
+ (computedApprovalTotal > 0 ? computedApprovalTotal : null);
557
+ useEffect(() => {
558
+ if (progressEvents.length === 0) {
559
+ setLockedApprovalTotal(null);
560
+ return;
561
+ }
562
+ if (lockedApprovalTotal !== null || computedApprovalTotal <= 0)
563
+ return;
564
+ setLockedApprovalTotal(computedApprovalTotal);
565
+ }, [computedApprovalTotal, lockedApprovalTotal, progressEvents.length]);
566
+ const statusRows = buildStatusRows({
567
+ events: progressEvents,
568
+ failedStep,
569
+ mode,
570
+ steps: steps ?? [],
571
+ approvalTotalCount,
572
+ context: {
573
+ destinationChain: destinationChainName || destinationChain,
574
+ destinationSymbol,
575
+ opportunityName: opportunity?.title || opportunity?.protocol,
576
+ recipientAddress,
577
+ },
578
+ });
579
+ const [stepsExpanded, setStepsExpanded] = useState(true);
580
+ const activeRow = statusRows.find((row) => row.state === "preapproval" || row.state === "inProgress") ??
581
+ statusRows.find((row) => row.state === "error") ??
582
+ statusRows.find((row) => row.state === "default") ??
583
+ statusRows[statusRows.length - 1];
584
+ const visibleRows = stepsExpanded ? statusRows : activeRow ? [activeRow] : [];
585
+ const canExpand = statusRows.length > 1;
586
+ const getRowHeight = (row) => (row.description ? 47 : 40);
587
+ const collapsedStatusHeight = activeRow ? getRowHeight(activeRow) : 40;
588
+ const expandedStatusHeight = statusRows.reduce((sum, row) => sum + getRowHeight(row), 0);
589
+ return (_jsxs("div", { style: {
590
+ display: "flex",
591
+ flexDirection: "column",
592
+ gap: "7px",
593
+ width: "100%",
594
+ }, children: [_jsxs("div", { style: {
595
+ background: "#FFFFFE",
596
+ border: `1px solid ${border}`,
597
+ borderRadius: "8px",
598
+ boxShadow: "0px 1px 12px 0px #5B5B5B0D",
599
+ boxSizing: "border-box",
600
+ padding: "12px 13px 9px",
601
+ width: "100%",
602
+ }, children: [_jsx("div", { style: {
603
+ color: muted,
604
+ fontFamily,
605
+ fontSize: "10px",
606
+ lineHeight: "14px",
607
+ textAlign: "center",
608
+ }, children: formatSymbolSummary(sourceSymbols) }), _jsx("div", { style: {
609
+ color: primary,
610
+ fontFamily,
611
+ fontSize: "16px",
612
+ fontWeight: 600,
613
+ lineHeight: "22px",
614
+ marginTop: "2px",
615
+ textAlign: "center",
616
+ }, children: formatUsd(sourceUsd) }), _jsx("img", { alt: "", "aria-hidden": "true", src: "https://files.availproject.org/nexus-elements/nexus-one/progress-grid.gif", style: {
617
+ display: "block",
618
+ height: "148px",
619
+ margin: "13px auto 9px",
620
+ objectFit: "cover",
621
+ objectPosition: "center",
622
+ width: "100%",
623
+ } }), _jsxs("div", { style: {
624
+ alignItems: "center",
625
+ display: "flex",
626
+ flexDirection: "column",
627
+ gap: "4px",
628
+ }, children: [_jsxs("div", { style: {
629
+ alignItems: "center",
630
+ color: primary,
631
+ display: "flex",
632
+ fontFamily,
633
+ fontSize: "15px",
634
+ fontWeight: 600,
635
+ gap: "5px",
636
+ lineHeight: "22px",
637
+ }, children: [_jsx(TokenLogoPair, { chainLogo: intentDestination?.chain.logo || toToken?.chainLogo, chainName: destinationChain, tokenLogo: intentDestination?.token?.logo || toToken?.logo, tokenSymbol: destinationSymbol }), _jsx("span", { children: formatDecimal(destinationAmount, 8) }), _jsx("span", { style: { fontSize: "10px", lineHeight: "14px" }, children: destinationSymbol })] }), destinationChain && (_jsxs("div", { style: {
638
+ color: muted,
639
+ fontFamily,
640
+ fontSize: "9px",
641
+ lineHeight: "13px",
642
+ }, children: ["on ", destinationChain] }))] })] }), _jsx("div", { "aria-live": "polite", style: {
643
+ background: "#FFFFFE",
644
+ border: `1px solid ${border}`,
645
+ borderRadius: "8px",
646
+ boxShadow: "0px 1px 12px 0px #5B5B5B0D",
647
+ boxSizing: "border-box",
648
+ overflow: "hidden",
649
+ transition: "box-shadow 220ms ease, border-color 220ms ease",
650
+ width: "100%",
651
+ }, children: _jsx("div", { style: {
652
+ display: "grid",
653
+ gridTemplateRows: "1fr",
654
+ maxHeight: stepsExpanded
655
+ ? `${Math.max(43, expandedStatusHeight)}px`
656
+ : `${collapsedStatusHeight}px`,
657
+ overflow: "hidden",
658
+ transition: "max-height 220ms ease",
659
+ }, children: _jsx("div", { style: {
660
+ display: "flex",
661
+ flexDirection: "column",
662
+ minHeight: 0,
663
+ }, children: visibleRows.map((row, index) => {
664
+ const isCompleted = row.state === "completed";
665
+ const isError = row.state === "error";
666
+ const isDefault = row.state === "default";
667
+ const isLoading = row.state === "preapproval" || row.state === "inProgress";
668
+ const hasDescription = Boolean(row.description);
669
+ const rowColor = isDefault ? muted : isError ? danger : primary;
670
+ return (_jsxs("button", { onClick: () => {
671
+ if (canExpand)
672
+ setStepsExpanded((current) => !current);
673
+ }, style: {
674
+ alignItems: hasDescription ? "flex-start" : "center",
675
+ appearance: "none",
676
+ background: "transparent",
677
+ border: "0",
678
+ borderTop: index > 0 && stepsExpanded ? `1px solid ${border}` : "0",
679
+ boxSizing: "border-box",
680
+ color: rowColor,
681
+ cursor: canExpand ? "pointer" : "default",
682
+ display: "flex",
683
+ fontFamily,
684
+ fontSize: "11px",
685
+ fontWeight: 400,
686
+ gap: "7px",
687
+ minHeight: `${getRowHeight(row)}px`,
688
+ padding: "8px 11px",
689
+ textAlign: "left",
690
+ transition: "color 220ms ease, min-height 220ms ease, opacity 220ms ease",
691
+ width: "100%",
692
+ }, type: "button", children: [isCompleted || isError ? (_jsx("span", { style: {
693
+ alignItems: "center",
694
+ background: isError ? danger : brand,
695
+ borderRadius: "999px",
696
+ color: "#FFFFFE",
697
+ display: "inline-flex",
698
+ height: "15px",
699
+ justifyContent: "center",
700
+ width: "15px",
701
+ }, children: isError ? (_jsx(X, { style: { height: 10, width: 10 } })) : (_jsx(Check, { style: { height: 11, width: 11 } })) })) : isDefault ? (_jsx("span", { style: {
702
+ background: "#FFFFFE",
703
+ border: `2px solid ${border}`,
704
+ borderRadius: "999px",
705
+ boxSizing: "border-box",
706
+ display: "inline-flex",
707
+ height: "15px",
708
+ width: "15px",
709
+ } })) : (_jsx(Loader2, { className: "animate-spin", style: { color: brand, height: 15, width: 15 } })), _jsxs("span", { style: {
710
+ display: "flex",
711
+ flexDirection: "column",
712
+ gap: "3px",
713
+ lineHeight: "18px",
714
+ minWidth: 0,
715
+ }, children: [_jsx("span", { style: {
716
+ color: rowColor,
717
+ fontWeight: isLoading ? 600 : 400,
718
+ }, children: row.label }), row.description && (_jsx("span", { style: {
719
+ color: isLoading ? brand : muted,
720
+ fontSize: "10px",
721
+ fontStyle: "italic",
722
+ fontWeight: 400,
723
+ lineHeight: "13px",
724
+ }, children: row.description }))] }), canExpand && index === 0 && (_jsx(ChevronDown, { style: {
725
+ color: muted,
726
+ flexShrink: 0,
727
+ height: 16,
728
+ marginLeft: "auto",
729
+ marginTop: hasDescription ? 2 : 0,
730
+ transform: stepsExpanded
731
+ ? "rotate(180deg)"
732
+ : "rotate(0deg)",
733
+ transition: "transform 220ms ease",
734
+ width: 16,
735
+ } }))] }, row.id));
736
+ }) }) }) })] }));
737
+ }