@b3dotfun/sdk 0.0.29-alpha.4 → 0.0.29-alpha.6
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/cjs/anyspend/react/components/AnyspendDepositHype.js +6 -2
- package/dist/cjs/anyspend/react/components/common/OrderDetails.js +3 -0
- package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.d.ts +2 -1
- package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.js +5 -3
- package/dist/cjs/global-account/react/components/LinkAccount/LinkAccount.js +28 -15
- package/dist/cjs/global-account/react/components/ManageAccount/ManageAccount.js +1 -1
- package/dist/esm/anyspend/react/components/AnyspendDepositHype.js +6 -2
- package/dist/esm/anyspend/react/components/common/OrderDetails.js +4 -1
- package/dist/esm/anyspend/react/hooks/useAnyspendFlow.d.ts +2 -1
- package/dist/esm/anyspend/react/hooks/useAnyspendFlow.js +5 -3
- package/dist/esm/global-account/react/components/LinkAccount/LinkAccount.js +28 -15
- package/dist/esm/global-account/react/components/ManageAccount/ManageAccount.js +1 -1
- package/dist/types/anyspend/react/hooks/useAnyspendFlow.d.ts +2 -1
- package/package.json +1 -1
- package/src/anyspend/react/components/AnyspendDepositHype.tsx +9 -3
- package/src/anyspend/react/components/common/OrderDetails.tsx +4 -0
- package/src/anyspend/react/hooks/useAnyspendFlow.ts +8 -2
- package/src/global-account/react/components/LinkAccount/LinkAccount.tsx +26 -10
- package/src/global-account/react/components/ManageAccount/ManageAccount.tsx +5 -1
|
@@ -27,6 +27,7 @@ const RecipientSelection_1 = require("./common/RecipientSelection");
|
|
|
27
27
|
const escrow_1 = require("../../../anyspend/abis/escrow");
|
|
28
28
|
const lucide_react_1 = require("lucide-react");
|
|
29
29
|
const PanelOnramp_1 = require("./common/PanelOnramp");
|
|
30
|
+
const SLIPPAGE_PERCENT = 3;
|
|
30
31
|
function generateEncodedDataForDepositHype(amount, beneficiary) {
|
|
31
32
|
(0, invariant_1.default)(BigInt(amount) > 0, "Amount must be greater than zero");
|
|
32
33
|
const encodedData = (0, viem_1.encodeFunctionData)({
|
|
@@ -50,6 +51,7 @@ function AnySpendDepositHypeInner({ loadOrder, mode = "modal", recipientAddress,
|
|
|
50
51
|
onTransactionSuccess: onSuccess,
|
|
51
52
|
sourceTokenAddress,
|
|
52
53
|
sourceTokenChainId,
|
|
54
|
+
slippage: SLIPPAGE_PERCENT,
|
|
53
55
|
});
|
|
54
56
|
// Button state logic
|
|
55
57
|
const btnInfo = (0, react_3.useMemo)(() => {
|
|
@@ -133,7 +135,10 @@ function AnySpendDepositHypeInner({ loadOrder, mode = "modal", recipientAddress,
|
|
|
133
135
|
(0, invariant_1.default)(selectedRecipientAddress, "Recipient address is not found");
|
|
134
136
|
(0, invariant_1.default)(depositContractAddress, "Deposit contract address is not found");
|
|
135
137
|
const srcAmountBigInt = BigInt(activeInputAmountInWei);
|
|
136
|
-
|
|
138
|
+
// TODO: temp subtract 3% for slippage
|
|
139
|
+
const originalDepositAmountWei = anyspendQuote.data?.currencyOut?.amount || "0";
|
|
140
|
+
const depositAmountWei = ((BigInt(originalDepositAmountWei) * BigInt(100 - SLIPPAGE_PERCENT)) /
|
|
141
|
+
BigInt(100)).toString();
|
|
137
142
|
const encodedData = generateEncodedDataForDepositHype(depositAmountWei, selectedRecipientAddress);
|
|
138
143
|
createOrder({
|
|
139
144
|
recipientAddress: selectedRecipientAddress,
|
|
@@ -240,7 +245,6 @@ function AnySpendDepositHypeInner({ loadOrder, mode = "modal", recipientAddress,
|
|
|
240
245
|
setSelectedFiatPaymentMethod(method);
|
|
241
246
|
setActivePanel(useAnyspendFlow_1.PanelView.MAIN);
|
|
242
247
|
}, srcAmountOnRamp: srcAmount }));
|
|
243
|
-
console.log("activePanel", activePanel, orderId, oat);
|
|
244
248
|
// If showing token selection, render with panel transitions
|
|
245
249
|
return ((0, jsx_runtime_1.jsx)(react_1.StyleRoot, { children: (0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)("anyspend-container font-inter mx-auto w-full max-w-[460px]", mode === "page" &&
|
|
246
250
|
"bg-as-surface-primary border-as-border-secondary overflow-hidden rounded-2xl border shadow-xl"), children: (0, jsx_runtime_1.jsx)(react_1.TransitionPanel, { activeIndex: orderId
|
|
@@ -49,6 +49,9 @@ function getOrderSuccessText({ order, tournament, formattedActualDstAmount, dstT
|
|
|
49
49
|
actionText = `funded ${tournament?.name}`;
|
|
50
50
|
return `Successfully ${actionText}`;
|
|
51
51
|
case "custom":
|
|
52
|
+
if (order.metadata.action === anyspend_1.DEPOSIT_HYPE_ACTION) {
|
|
53
|
+
return `Successfully deposited ${(0, number_1.formatTokenAmount)(BigInt(order.payload?.amount || "0"), 18)} HYPE to ${recipient}`;
|
|
54
|
+
}
|
|
52
55
|
actionText = order.metadata.action || `executed contract`;
|
|
53
56
|
return `Successfully ${actionText}`;
|
|
54
57
|
default:
|
|
@@ -18,8 +18,9 @@ interface UseAnyspendFlowProps {
|
|
|
18
18
|
onTransactionSuccess?: () => void;
|
|
19
19
|
sourceTokenAddress?: string;
|
|
20
20
|
sourceTokenChainId?: number;
|
|
21
|
+
slippage?: number;
|
|
21
22
|
}
|
|
22
|
-
export declare function useAnyspendFlow({ paymentType, recipientAddress, loadOrder, isDepositMode, onOrderSuccess, onTransactionSuccess, sourceTokenAddress, sourceTokenChainId, }: UseAnyspendFlowProps): {
|
|
23
|
+
export declare function useAnyspendFlow({ paymentType, recipientAddress, loadOrder, isDepositMode, onOrderSuccess, onTransactionSuccess, sourceTokenAddress, sourceTokenChainId, slippage, }: UseAnyspendFlowProps): {
|
|
23
24
|
activePanel: PanelView;
|
|
24
25
|
setActivePanel: import("react").Dispatch<import("react").SetStateAction<PanelView>>;
|
|
25
26
|
orderId: string | undefined;
|
|
@@ -22,7 +22,7 @@ var PanelView;
|
|
|
22
22
|
PanelView[PanelView["ORDER_DETAILS"] = 4] = "ORDER_DETAILS";
|
|
23
23
|
PanelView[PanelView["LOADING"] = 5] = "LOADING";
|
|
24
24
|
})(PanelView || (exports.PanelView = PanelView = {}));
|
|
25
|
-
function useAnyspendFlow({ paymentType = "crypto", recipientAddress, loadOrder, isDepositMode = false, onOrderSuccess, onTransactionSuccess, sourceTokenAddress, sourceTokenChainId, }) {
|
|
25
|
+
function useAnyspendFlow({ paymentType = "crypto", recipientAddress, loadOrder, isDepositMode = false, onOrderSuccess, onTransactionSuccess, sourceTokenAddress, sourceTokenChainId, slippage = 0, }) {
|
|
26
26
|
const searchParams = (0, react_2.useSearchParamsSSR)();
|
|
27
27
|
const router = (0, react_2.useRouter)();
|
|
28
28
|
// Panel and order state
|
|
@@ -103,13 +103,15 @@ function useAnyspendFlow({ paymentType = "crypto", recipientAddress, loadOrder,
|
|
|
103
103
|
if (anyspendQuote?.data?.currencyOut?.amount && anyspendQuote.data.currencyOut.currency?.decimals) {
|
|
104
104
|
const amount = anyspendQuote.data.currencyOut.amount;
|
|
105
105
|
const decimals = anyspendQuote.data.currencyOut.currency.decimals;
|
|
106
|
-
|
|
106
|
+
// Apply slippage (0-100) - reduce amount by slippage percentageFixed slippage value
|
|
107
|
+
const amountWithSlippage = (BigInt(amount) * BigInt(100 - slippage)) / BigInt(100);
|
|
108
|
+
const formattedAmount = (0, number_1.formatTokenAmount)(amountWithSlippage, decimals, 6, false);
|
|
107
109
|
setDstAmount(formattedAmount);
|
|
108
110
|
}
|
|
109
111
|
else {
|
|
110
112
|
setDstAmount("");
|
|
111
113
|
}
|
|
112
|
-
}, [anyspendQuote]);
|
|
114
|
+
}, [anyspendQuote, slippage]);
|
|
113
115
|
// Update useEffect for URL parameter to not override loadOrder
|
|
114
116
|
(0, react_3.useEffect)(() => {
|
|
115
117
|
if (loadOrder)
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.LinkAccount = LinkAccount;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const constants_1 = require("../../../../shared/constants");
|
|
5
6
|
const thirdweb_1 = require("../../../../shared/utils/thirdweb");
|
|
6
7
|
const lucide_react_1 = require("lucide-react");
|
|
7
8
|
const react_1 = require("react");
|
|
@@ -97,6 +98,10 @@ function LinkAccount({ onSuccess: onSuccessCallback, onError, onClose, chain, pa
|
|
|
97
98
|
client: thirdweb_1.client,
|
|
98
99
|
strategy: "email",
|
|
99
100
|
email,
|
|
101
|
+
ecosystem: {
|
|
102
|
+
id: constants_1.ecosystemWalletId,
|
|
103
|
+
partnerId: partnerId,
|
|
104
|
+
},
|
|
100
105
|
});
|
|
101
106
|
}
|
|
102
107
|
else if (selectedMethod === "phone") {
|
|
@@ -104,6 +109,10 @@ function LinkAccount({ onSuccess: onSuccessCallback, onError, onClose, chain, pa
|
|
|
104
109
|
client: thirdweb_1.client,
|
|
105
110
|
strategy: "phone",
|
|
106
111
|
phoneNumber: phone,
|
|
112
|
+
ecosystem: {
|
|
113
|
+
id: constants_1.ecosystemWalletId,
|
|
114
|
+
partnerId: partnerId,
|
|
115
|
+
},
|
|
107
116
|
});
|
|
108
117
|
}
|
|
109
118
|
setOtpSent(true);
|
|
@@ -117,10 +126,12 @@ function LinkAccount({ onSuccess: onSuccessCallback, onError, onClose, chain, pa
|
|
|
117
126
|
};
|
|
118
127
|
const handleLinkAccount = async () => {
|
|
119
128
|
if (!otp) {
|
|
129
|
+
console.error("No OTP entered");
|
|
120
130
|
setError("Please enter the verification code");
|
|
121
131
|
return;
|
|
122
132
|
}
|
|
123
133
|
try {
|
|
134
|
+
setOtpSent(false);
|
|
124
135
|
setLinkingState(true, selectedMethod);
|
|
125
136
|
setError(null);
|
|
126
137
|
if (selectedMethod === "email") {
|
|
@@ -139,17 +150,12 @@ function LinkAccount({ onSuccess: onSuccessCallback, onError, onClose, chain, pa
|
|
|
139
150
|
verificationCode: otp,
|
|
140
151
|
}, mutationOptions);
|
|
141
152
|
}
|
|
142
|
-
onSuccess?.();
|
|
143
|
-
onClose?.();
|
|
144
153
|
}
|
|
145
154
|
catch (error) {
|
|
146
155
|
console.error("Error linking account:", error);
|
|
147
156
|
setError(error instanceof Error ? error.message : "Failed to link account");
|
|
148
157
|
onError?.(error);
|
|
149
158
|
}
|
|
150
|
-
finally {
|
|
151
|
-
setLinkingState(false);
|
|
152
|
-
}
|
|
153
159
|
};
|
|
154
160
|
const handleSocialLink = async (strategy) => {
|
|
155
161
|
try {
|
|
@@ -200,17 +206,24 @@ function LinkAccount({ onSuccess: onSuccessCallback, onError, onClose, chain, pa
|
|
|
200
206
|
setError(null);
|
|
201
207
|
setLinkingState(false);
|
|
202
208
|
}, [isLinking, setSelectedMethod, setEmail, setPhone, setOtp, setOtpSent, setError, setLinkingState]);
|
|
209
|
+
const handleFinishedLinking = (0, react_1.useCallback)((success) => {
|
|
210
|
+
if (success) {
|
|
211
|
+
onSuccess?.();
|
|
212
|
+
onClose?.();
|
|
213
|
+
}
|
|
214
|
+
setLinkingState(false);
|
|
215
|
+
navigateBack();
|
|
216
|
+
setB3ModalContentType({
|
|
217
|
+
type: "manageAccount",
|
|
218
|
+
activeTab: "settings",
|
|
219
|
+
setActiveTab: () => { },
|
|
220
|
+
chain,
|
|
221
|
+
partnerId,
|
|
222
|
+
});
|
|
223
|
+
}, [chain, navigateBack, partnerId, setB3ModalContentType, setLinkingState, onSuccess, onClose]);
|
|
203
224
|
(0, react_1.useEffect)(() => {
|
|
204
225
|
if (isLinking) {
|
|
205
|
-
|
|
206
|
-
navigateBack();
|
|
207
|
-
setB3ModalContentType({
|
|
208
|
-
type: "manageAccount",
|
|
209
|
-
activeTab: "settings",
|
|
210
|
-
setActiveTab: () => { },
|
|
211
|
-
chain,
|
|
212
|
-
partnerId,
|
|
213
|
-
});
|
|
226
|
+
handleFinishedLinking(true);
|
|
214
227
|
}
|
|
215
228
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
216
229
|
}, [profiles.length]);
|
|
@@ -224,5 +237,5 @@ function LinkAccount({ onSuccess: onSuccessCallback, onError, onClose, chain, pa
|
|
|
224
237
|
else {
|
|
225
238
|
handleSocialLink(method.id);
|
|
226
239
|
}
|
|
227
|
-
}, disabled: linkingMethod === method.id, children: isLinking && linkingMethod === method.id ? (0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "animate-spin" }) : method.label }, method.id))), availableAuthMethods.length === 0 && ((0, jsx_runtime_1.jsx)("div", { className: "text-b3-foreground-muted py-8 text-center", children: "All available authentication methods have been connected" }))] })) : ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [selectedMethod === "email" && ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-2", children: [(0, jsx_runtime_1.jsx)("label", { className: "text-b3-grey font-neue-montreal-medium text-sm", children: "Email Address" }), (0, jsx_runtime_1.jsx)("input", { type: "email", placeholder: "Enter your email", className: "bg-b3-line text-b3-grey font-neue-montreal-medium focus:ring-b3-primary-blue/20 w-full rounded-xl p-4 focus:outline-none focus:ring-2", value: email, onChange: e => setEmail(e.target.value), disabled: otpSent || (isLinking && linkingMethod === "email") })] })), selectedMethod === "phone" && ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-2", children: [(0, jsx_runtime_1.jsx)("label", { className: "text-b3-grey font-neue-montreal-medium text-sm", children: "Phone Number" }), (0, jsx_runtime_1.jsx)("input", { type: "tel", placeholder: "Enter your phone number", className: "bg-b3-line text-b3-grey font-neue-montreal-medium focus:ring-b3-primary-blue/20 w-full rounded-xl p-4 focus:outline-none focus:ring-2", value: phone, onChange: e => setPhone(e.target.value), disabled: otpSent || (isLinking && linkingMethod === "phone") }), (0, jsx_runtime_1.jsx)("p", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: "Include country code (e.g., +1 for US)" })] })), error && (0, jsx_runtime_1.jsx)("div", { className: "text-b3-negative font-neue-montreal-medium py-2 text-sm", children: error }), otpSent ? ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "space-y-2", children: [(0, jsx_runtime_1.jsx)("label", { className: "text-b3-grey font-neue-montreal-medium text-sm", children: "Verification Code" }), (0, jsx_runtime_1.jsx)("input", { type: "text", placeholder: "Enter verification code", className: "bg-b3-line text-b3-grey font-neue-montreal-medium focus:ring-b3-primary-blue/20 w-full rounded-xl p-4 focus:outline-none focus:ring-2", value: otp, onChange: e => setOtp(e.target.value)
|
|
240
|
+
}, disabled: linkingMethod === method.id, children: isLinking && linkingMethod === method.id ? (0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "animate-spin" }) : method.label }, method.id))), availableAuthMethods.length === 0 && ((0, jsx_runtime_1.jsx)("div", { className: "text-b3-foreground-muted py-8 text-center", children: "All available authentication methods have been connected" }))] })) : ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [selectedMethod === "email" && ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-2", children: [(0, jsx_runtime_1.jsx)("label", { className: "text-b3-grey font-neue-montreal-medium text-sm", children: "Email Address" }), (0, jsx_runtime_1.jsx)("input", { type: "email", placeholder: "Enter your email", className: "bg-b3-line text-b3-grey font-neue-montreal-medium focus:ring-b3-primary-blue/20 w-full rounded-xl p-4 focus:outline-none focus:ring-2", value: email, onChange: e => setEmail(e.target.value), disabled: otpSent || (isLinking && linkingMethod === "email") })] })), selectedMethod === "phone" && ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-2", children: [(0, jsx_runtime_1.jsx)("label", { className: "text-b3-grey font-neue-montreal-medium text-sm", children: "Phone Number" }), (0, jsx_runtime_1.jsx)("input", { type: "tel", placeholder: "Enter your phone number", className: "bg-b3-line text-b3-grey font-neue-montreal-medium focus:ring-b3-primary-blue/20 w-full rounded-xl p-4 focus:outline-none focus:ring-2", value: phone, onChange: e => setPhone(e.target.value), disabled: otpSent || (isLinking && linkingMethod === "phone") }), (0, jsx_runtime_1.jsx)("p", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: "Include country code (e.g., +1 for US)" })] })), error && (0, jsx_runtime_1.jsx)("div", { className: "text-b3-negative font-neue-montreal-medium py-2 text-sm", children: error }), otpSent ? ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "space-y-2", children: [(0, jsx_runtime_1.jsx)("label", { className: "text-b3-grey font-neue-montreal-medium text-sm", children: "Verification Code" }), (0, jsx_runtime_1.jsx)("input", { type: "text", placeholder: "Enter verification code", className: "bg-b3-line text-b3-grey font-neue-montreal-medium focus:ring-b3-primary-blue/20 w-full rounded-xl p-4 focus:outline-none focus:ring-2", value: otp, onChange: e => setOtp(e.target.value) })] }), (0, jsx_runtime_1.jsx)(button_1.Button, { className: "bg-b3-primary-blue hover:bg-b3-primary-blue/90 font-neue-montreal-semibold h-12 w-full text-white", onClick: handleLinkAccount, children: "Link Account" })] })) : ((0, jsx_runtime_1.jsx)(button_1.Button, { className: "bg-b3-primary-blue hover:bg-b3-primary-blue/90 font-neue-montreal-semibold h-12 w-full text-white", onClick: handleSendOTP, disabled: (!email && !phone) || (isLinking && linkingMethod === selectedMethod), children: isLinking && linkingMethod === selectedMethod ? ((0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "animate-spin" })) : ("Send Verification Code") }))] }))] }));
|
|
228
241
|
}
|
|
@@ -140,5 +140,5 @@ function ManageAccount({ onLogout, onSwap: _onSwap, onDeposit: _onDeposit, chain
|
|
|
140
140
|
if (["balance", "assets", "apps", "settings"].includes(tab)) {
|
|
141
141
|
setActiveTab?.(tab);
|
|
142
142
|
}
|
|
143
|
-
}, children: [(0, jsx_runtime_1.jsxs)(react_1.TabsListPrimitive, { className: "font-neue-montreal-semibold text-b3-grey flex h-8 w-full items-start justify-start gap-8 border-0 text-xl md:p-4", children: [(0, jsx_runtime_1.jsx)(react_1.TabTriggerPrimitive, { value: "balance", className: "data-[state=active]:text-b3-primary-blue data-[state=active]:border-b-b3-primary-blue flex-none rounded-none border-0 p-0 pb-1 text-xl leading-none tracking-wide transition-colors data-[state=active]:border-b data-[state=active]:bg-white md:pb-4", children: "Overview" }), (0, jsx_runtime_1.jsx)(react_1.TabTriggerPrimitive, { value: "assets", className: "data-[state=active]:text-b3-primary-blue data-[state=active]:border-b-b3-primary-blue flex-none rounded-none border-0 p-0 pb-1 text-xl leading-none tracking-wide transition-colors data-[state=active]:border-b data-[state=active]:bg-white md:pb-4", children: "Mints" }), (0, jsx_runtime_1.jsx)(react_1.TabTriggerPrimitive, { value: "
|
|
143
|
+
}, children: [(0, jsx_runtime_1.jsxs)(react_1.TabsListPrimitive, { className: "font-neue-montreal-semibold text-b3-grey flex h-8 w-full items-start justify-start gap-8 border-0 text-xl md:p-4", children: [(0, jsx_runtime_1.jsx)(react_1.TabTriggerPrimitive, { value: "balance", className: "data-[state=active]:text-b3-primary-blue data-[state=active]:border-b-b3-primary-blue flex-none rounded-none border-0 p-0 pb-1 text-xl leading-none tracking-wide transition-colors data-[state=active]:border-b data-[state=active]:bg-white md:pb-4", children: "Overview" }), (0, jsx_runtime_1.jsx)(react_1.TabTriggerPrimitive, { value: "assets", className: "data-[state=active]:text-b3-primary-blue data-[state=active]:border-b-b3-primary-blue flex-none rounded-none border-0 p-0 pb-1 text-xl leading-none tracking-wide transition-colors data-[state=active]:border-b data-[state=active]:bg-white md:pb-4", children: "Mints" }), (0, jsx_runtime_1.jsx)(react_1.TabTriggerPrimitive, { value: "settings", className: "data-[state=active]:text-b3-primary-blue data-[state=active]:border-b-b3-primary-blue flex-none rounded-none border-0 p-0 pb-1 text-xl leading-none tracking-wide transition-colors data-[state=active]:border-b data-[state=active]:bg-white md:pb-4", children: "Settings" })] }), (0, jsx_runtime_1.jsx)(react_1.TabsContentPrimitive, { value: "balance", className: "pt-4 md:p-4", children: (0, jsx_runtime_1.jsx)(BalanceContent, {}) }), (0, jsx_runtime_1.jsx)(react_1.TabsContentPrimitive, { value: "assets", className: "pt-4 md:p-4", children: (0, jsx_runtime_1.jsx)(AssetsContent, {}) }), (0, jsx_runtime_1.jsx)(react_1.TabsContentPrimitive, { value: "apps", className: "pt-4 md:p-4", children: (0, jsx_runtime_1.jsx)(AppsContent, {}) }), (0, jsx_runtime_1.jsx)(react_1.TabsContentPrimitive, { value: "settings", className: "pt-4 md:p-4", children: (0, jsx_runtime_1.jsx)(SettingsContent, {}) })] }) }) }));
|
|
144
144
|
}
|
|
@@ -21,6 +21,7 @@ import { RecipientSelection } from "./common/RecipientSelection.js";
|
|
|
21
21
|
import { ESCROW_ABI } from "../../../anyspend/abis/escrow.js";
|
|
22
22
|
import { ArrowDown } from "lucide-react";
|
|
23
23
|
import { PanelOnramp } from "./common/PanelOnramp.js";
|
|
24
|
+
const SLIPPAGE_PERCENT = 3;
|
|
24
25
|
function generateEncodedDataForDepositHype(amount, beneficiary) {
|
|
25
26
|
invariant(BigInt(amount) > 0, "Amount must be greater than zero");
|
|
26
27
|
const encodedData = encodeFunctionData({
|
|
@@ -44,6 +45,7 @@ function AnySpendDepositHypeInner({ loadOrder, mode = "modal", recipientAddress,
|
|
|
44
45
|
onTransactionSuccess: onSuccess,
|
|
45
46
|
sourceTokenAddress,
|
|
46
47
|
sourceTokenChainId,
|
|
48
|
+
slippage: SLIPPAGE_PERCENT,
|
|
47
49
|
});
|
|
48
50
|
// Button state logic
|
|
49
51
|
const btnInfo = useMemo(() => {
|
|
@@ -127,7 +129,10 @@ function AnySpendDepositHypeInner({ loadOrder, mode = "modal", recipientAddress,
|
|
|
127
129
|
invariant(selectedRecipientAddress, "Recipient address is not found");
|
|
128
130
|
invariant(depositContractAddress, "Deposit contract address is not found");
|
|
129
131
|
const srcAmountBigInt = BigInt(activeInputAmountInWei);
|
|
130
|
-
|
|
132
|
+
// TODO: temp subtract 3% for slippage
|
|
133
|
+
const originalDepositAmountWei = anyspendQuote.data?.currencyOut?.amount || "0";
|
|
134
|
+
const depositAmountWei = ((BigInt(originalDepositAmountWei) * BigInt(100 - SLIPPAGE_PERCENT)) /
|
|
135
|
+
BigInt(100)).toString();
|
|
131
136
|
const encodedData = generateEncodedDataForDepositHype(depositAmountWei, selectedRecipientAddress);
|
|
132
137
|
createOrder({
|
|
133
138
|
recipientAddress: selectedRecipientAddress,
|
|
@@ -234,7 +239,6 @@ function AnySpendDepositHypeInner({ loadOrder, mode = "modal", recipientAddress,
|
|
|
234
239
|
setSelectedFiatPaymentMethod(method);
|
|
235
240
|
setActivePanel(PanelView.MAIN);
|
|
236
241
|
}, srcAmountOnRamp: srcAmount }));
|
|
237
|
-
console.log("activePanel", activePanel, orderId, oat);
|
|
238
242
|
// If showing token selection, render with panel transitions
|
|
239
243
|
return (_jsx(StyleRoot, { children: _jsx("div", { className: cn("anyspend-container font-inter mx-auto w-full max-w-[460px]", mode === "page" &&
|
|
240
244
|
"bg-as-surface-primary border-as-border-secondary overflow-hidden rounded-2xl border shadow-xl"), children: _jsx(TransitionPanel, { activeIndex: orderId
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
-
import { ALL_CHAINS, getChainName, getErrorDisplay, getExplorerTxUrl, getPaymentUrl, getStatusDisplay, isNativeToken, RELAY_ETH_ADDRESS, RELAY_SOLANA_MAINNET_CHAIN_ID, } from "../../../../anyspend/index.js";
|
|
3
|
+
import { ALL_CHAINS, DEPOSIT_HYPE_ACTION, getChainName, getErrorDisplay, getExplorerTxUrl, getPaymentUrl, getStatusDisplay, isNativeToken, RELAY_ETH_ADDRESS, RELAY_SOLANA_MAINNET_CHAIN_ID, } from "../../../../anyspend/index.js";
|
|
4
4
|
import { Badge, Button, CopyToClipboard, ShinyButton, Skeleton, TextLoop, TextShimmer, useAccountWallet, useModalStore, useProfile, useUnifiedChainSwitchAndExecute, } from "../../../../global-account/react/index.js";
|
|
5
5
|
import { useRouter, useSearchParams } from "../../../../shared/react/hooks/index.js";
|
|
6
6
|
import { cn } from "../../../../shared/utils/index.js";
|
|
@@ -43,6 +43,9 @@ function getOrderSuccessText({ order, tournament, formattedActualDstAmount, dstT
|
|
|
43
43
|
actionText = `funded ${tournament?.name}`;
|
|
44
44
|
return `Successfully ${actionText}`;
|
|
45
45
|
case "custom":
|
|
46
|
+
if (order.metadata.action === DEPOSIT_HYPE_ACTION) {
|
|
47
|
+
return `Successfully deposited ${formatTokenAmount(BigInt(order.payload?.amount || "0"), 18)} HYPE to ${recipient}`;
|
|
48
|
+
}
|
|
46
49
|
actionText = order.metadata.action || `executed contract`;
|
|
47
50
|
return `Successfully ${actionText}`;
|
|
48
51
|
default:
|
|
@@ -18,8 +18,9 @@ interface UseAnyspendFlowProps {
|
|
|
18
18
|
onTransactionSuccess?: () => void;
|
|
19
19
|
sourceTokenAddress?: string;
|
|
20
20
|
sourceTokenChainId?: number;
|
|
21
|
+
slippage?: number;
|
|
21
22
|
}
|
|
22
|
-
export declare function useAnyspendFlow({ paymentType, recipientAddress, loadOrder, isDepositMode, onOrderSuccess, onTransactionSuccess, sourceTokenAddress, sourceTokenChainId, }: UseAnyspendFlowProps): {
|
|
23
|
+
export declare function useAnyspendFlow({ paymentType, recipientAddress, loadOrder, isDepositMode, onOrderSuccess, onTransactionSuccess, sourceTokenAddress, sourceTokenChainId, slippage, }: UseAnyspendFlowProps): {
|
|
23
24
|
activePanel: PanelView;
|
|
24
25
|
setActivePanel: import("react").Dispatch<import("react").SetStateAction<PanelView>>;
|
|
25
26
|
orderId: string | undefined;
|
|
@@ -18,7 +18,7 @@ export var PanelView;
|
|
|
18
18
|
PanelView[PanelView["ORDER_DETAILS"] = 4] = "ORDER_DETAILS";
|
|
19
19
|
PanelView[PanelView["LOADING"] = 5] = "LOADING";
|
|
20
20
|
})(PanelView || (PanelView = {}));
|
|
21
|
-
export function useAnyspendFlow({ paymentType = "crypto", recipientAddress, loadOrder, isDepositMode = false, onOrderSuccess, onTransactionSuccess, sourceTokenAddress, sourceTokenChainId, }) {
|
|
21
|
+
export function useAnyspendFlow({ paymentType = "crypto", recipientAddress, loadOrder, isDepositMode = false, onOrderSuccess, onTransactionSuccess, sourceTokenAddress, sourceTokenChainId, slippage = 0, }) {
|
|
22
22
|
const searchParams = useSearchParamsSSR();
|
|
23
23
|
const router = useRouter();
|
|
24
24
|
// Panel and order state
|
|
@@ -99,13 +99,15 @@ export function useAnyspendFlow({ paymentType = "crypto", recipientAddress, load
|
|
|
99
99
|
if (anyspendQuote?.data?.currencyOut?.amount && anyspendQuote.data.currencyOut.currency?.decimals) {
|
|
100
100
|
const amount = anyspendQuote.data.currencyOut.amount;
|
|
101
101
|
const decimals = anyspendQuote.data.currencyOut.currency.decimals;
|
|
102
|
-
|
|
102
|
+
// Apply slippage (0-100) - reduce amount by slippage percentageFixed slippage value
|
|
103
|
+
const amountWithSlippage = (BigInt(amount) * BigInt(100 - slippage)) / BigInt(100);
|
|
104
|
+
const formattedAmount = formatTokenAmount(amountWithSlippage, decimals, 6, false);
|
|
103
105
|
setDstAmount(formattedAmount);
|
|
104
106
|
}
|
|
105
107
|
else {
|
|
106
108
|
setDstAmount("");
|
|
107
109
|
}
|
|
108
|
-
}, [anyspendQuote]);
|
|
110
|
+
}, [anyspendQuote, slippage]);
|
|
109
111
|
// Update useEffect for URL parameter to not override loadOrder
|
|
110
112
|
useEffect(() => {
|
|
111
113
|
if (loadOrder)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ecosystemWalletId } from "../../../../shared/constants/index.js";
|
|
2
3
|
import { client } from "../../../../shared/utils/thirdweb.js";
|
|
3
4
|
import { Loader2 } from "lucide-react";
|
|
4
5
|
import { useCallback, useEffect, useState } from "react";
|
|
@@ -94,6 +95,10 @@ export function LinkAccount({ onSuccess: onSuccessCallback, onError, onClose, ch
|
|
|
94
95
|
client,
|
|
95
96
|
strategy: "email",
|
|
96
97
|
email,
|
|
98
|
+
ecosystem: {
|
|
99
|
+
id: ecosystemWalletId,
|
|
100
|
+
partnerId: partnerId,
|
|
101
|
+
},
|
|
97
102
|
});
|
|
98
103
|
}
|
|
99
104
|
else if (selectedMethod === "phone") {
|
|
@@ -101,6 +106,10 @@ export function LinkAccount({ onSuccess: onSuccessCallback, onError, onClose, ch
|
|
|
101
106
|
client,
|
|
102
107
|
strategy: "phone",
|
|
103
108
|
phoneNumber: phone,
|
|
109
|
+
ecosystem: {
|
|
110
|
+
id: ecosystemWalletId,
|
|
111
|
+
partnerId: partnerId,
|
|
112
|
+
},
|
|
104
113
|
});
|
|
105
114
|
}
|
|
106
115
|
setOtpSent(true);
|
|
@@ -114,10 +123,12 @@ export function LinkAccount({ onSuccess: onSuccessCallback, onError, onClose, ch
|
|
|
114
123
|
};
|
|
115
124
|
const handleLinkAccount = async () => {
|
|
116
125
|
if (!otp) {
|
|
126
|
+
console.error("No OTP entered");
|
|
117
127
|
setError("Please enter the verification code");
|
|
118
128
|
return;
|
|
119
129
|
}
|
|
120
130
|
try {
|
|
131
|
+
setOtpSent(false);
|
|
121
132
|
setLinkingState(true, selectedMethod);
|
|
122
133
|
setError(null);
|
|
123
134
|
if (selectedMethod === "email") {
|
|
@@ -136,17 +147,12 @@ export function LinkAccount({ onSuccess: onSuccessCallback, onError, onClose, ch
|
|
|
136
147
|
verificationCode: otp,
|
|
137
148
|
}, mutationOptions);
|
|
138
149
|
}
|
|
139
|
-
onSuccess?.();
|
|
140
|
-
onClose?.();
|
|
141
150
|
}
|
|
142
151
|
catch (error) {
|
|
143
152
|
console.error("Error linking account:", error);
|
|
144
153
|
setError(error instanceof Error ? error.message : "Failed to link account");
|
|
145
154
|
onError?.(error);
|
|
146
155
|
}
|
|
147
|
-
finally {
|
|
148
|
-
setLinkingState(false);
|
|
149
|
-
}
|
|
150
156
|
};
|
|
151
157
|
const handleSocialLink = async (strategy) => {
|
|
152
158
|
try {
|
|
@@ -197,17 +203,24 @@ export function LinkAccount({ onSuccess: onSuccessCallback, onError, onClose, ch
|
|
|
197
203
|
setError(null);
|
|
198
204
|
setLinkingState(false);
|
|
199
205
|
}, [isLinking, setSelectedMethod, setEmail, setPhone, setOtp, setOtpSent, setError, setLinkingState]);
|
|
206
|
+
const handleFinishedLinking = useCallback((success) => {
|
|
207
|
+
if (success) {
|
|
208
|
+
onSuccess?.();
|
|
209
|
+
onClose?.();
|
|
210
|
+
}
|
|
211
|
+
setLinkingState(false);
|
|
212
|
+
navigateBack();
|
|
213
|
+
setB3ModalContentType({
|
|
214
|
+
type: "manageAccount",
|
|
215
|
+
activeTab: "settings",
|
|
216
|
+
setActiveTab: () => { },
|
|
217
|
+
chain,
|
|
218
|
+
partnerId,
|
|
219
|
+
});
|
|
220
|
+
}, [chain, navigateBack, partnerId, setB3ModalContentType, setLinkingState, onSuccess, onClose]);
|
|
200
221
|
useEffect(() => {
|
|
201
222
|
if (isLinking) {
|
|
202
|
-
|
|
203
|
-
navigateBack();
|
|
204
|
-
setB3ModalContentType({
|
|
205
|
-
type: "manageAccount",
|
|
206
|
-
activeTab: "settings",
|
|
207
|
-
setActiveTab: () => { },
|
|
208
|
-
chain,
|
|
209
|
-
partnerId,
|
|
210
|
-
});
|
|
223
|
+
handleFinishedLinking(true);
|
|
211
224
|
}
|
|
212
225
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
213
226
|
}, [profiles.length]);
|
|
@@ -221,5 +234,5 @@ export function LinkAccount({ onSuccess: onSuccessCallback, onError, onClose, ch
|
|
|
221
234
|
else {
|
|
222
235
|
handleSocialLink(method.id);
|
|
223
236
|
}
|
|
224
|
-
}, disabled: linkingMethod === method.id, children: isLinking && linkingMethod === method.id ? _jsx(Loader2, { className: "animate-spin" }) : method.label }, method.id))), availableAuthMethods.length === 0 && (_jsx("div", { className: "text-b3-foreground-muted py-8 text-center", children: "All available authentication methods have been connected" }))] })) : (_jsxs("div", { className: "space-y-4", children: [selectedMethod === "email" && (_jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "text-b3-grey font-neue-montreal-medium text-sm", children: "Email Address" }), _jsx("input", { type: "email", placeholder: "Enter your email", className: "bg-b3-line text-b3-grey font-neue-montreal-medium focus:ring-b3-primary-blue/20 w-full rounded-xl p-4 focus:outline-none focus:ring-2", value: email, onChange: e => setEmail(e.target.value), disabled: otpSent || (isLinking && linkingMethod === "email") })] })), selectedMethod === "phone" && (_jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "text-b3-grey font-neue-montreal-medium text-sm", children: "Phone Number" }), _jsx("input", { type: "tel", placeholder: "Enter your phone number", className: "bg-b3-line text-b3-grey font-neue-montreal-medium focus:ring-b3-primary-blue/20 w-full rounded-xl p-4 focus:outline-none focus:ring-2", value: phone, onChange: e => setPhone(e.target.value), disabled: otpSent || (isLinking && linkingMethod === "phone") }), _jsx("p", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: "Include country code (e.g., +1 for US)" })] })), error && _jsx("div", { className: "text-b3-negative font-neue-montreal-medium py-2 text-sm", children: error }), otpSent ? (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "text-b3-grey font-neue-montreal-medium text-sm", children: "Verification Code" }), _jsx("input", { type: "text", placeholder: "Enter verification code", className: "bg-b3-line text-b3-grey font-neue-montreal-medium focus:ring-b3-primary-blue/20 w-full rounded-xl p-4 focus:outline-none focus:ring-2", value: otp, onChange: e => setOtp(e.target.value)
|
|
237
|
+
}, disabled: linkingMethod === method.id, children: isLinking && linkingMethod === method.id ? _jsx(Loader2, { className: "animate-spin" }) : method.label }, method.id))), availableAuthMethods.length === 0 && (_jsx("div", { className: "text-b3-foreground-muted py-8 text-center", children: "All available authentication methods have been connected" }))] })) : (_jsxs("div", { className: "space-y-4", children: [selectedMethod === "email" && (_jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "text-b3-grey font-neue-montreal-medium text-sm", children: "Email Address" }), _jsx("input", { type: "email", placeholder: "Enter your email", className: "bg-b3-line text-b3-grey font-neue-montreal-medium focus:ring-b3-primary-blue/20 w-full rounded-xl p-4 focus:outline-none focus:ring-2", value: email, onChange: e => setEmail(e.target.value), disabled: otpSent || (isLinking && linkingMethod === "email") })] })), selectedMethod === "phone" && (_jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "text-b3-grey font-neue-montreal-medium text-sm", children: "Phone Number" }), _jsx("input", { type: "tel", placeholder: "Enter your phone number", className: "bg-b3-line text-b3-grey font-neue-montreal-medium focus:ring-b3-primary-blue/20 w-full rounded-xl p-4 focus:outline-none focus:ring-2", value: phone, onChange: e => setPhone(e.target.value), disabled: otpSent || (isLinking && linkingMethod === "phone") }), _jsx("p", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: "Include country code (e.g., +1 for US)" })] })), error && _jsx("div", { className: "text-b3-negative font-neue-montreal-medium py-2 text-sm", children: error }), otpSent ? (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "text-b3-grey font-neue-montreal-medium text-sm", children: "Verification Code" }), _jsx("input", { type: "text", placeholder: "Enter verification code", className: "bg-b3-line text-b3-grey font-neue-montreal-medium focus:ring-b3-primary-blue/20 w-full rounded-xl p-4 focus:outline-none focus:ring-2", value: otp, onChange: e => setOtp(e.target.value) })] }), _jsx(Button, { className: "bg-b3-primary-blue hover:bg-b3-primary-blue/90 font-neue-montreal-semibold h-12 w-full text-white", onClick: handleLinkAccount, children: "Link Account" })] })) : (_jsx(Button, { className: "bg-b3-primary-blue hover:bg-b3-primary-blue/90 font-neue-montreal-semibold h-12 w-full text-white", onClick: handleSendOTP, disabled: (!email && !phone) || (isLinking && linkingMethod === selectedMethod), children: isLinking && linkingMethod === selectedMethod ? (_jsx(Loader2, { className: "animate-spin" })) : ("Send Verification Code") }))] }))] }));
|
|
225
238
|
}
|
|
@@ -134,5 +134,5 @@ export function ManageAccount({ onLogout, onSwap: _onSwap, onDeposit: _onDeposit
|
|
|
134
134
|
if (["balance", "assets", "apps", "settings"].includes(tab)) {
|
|
135
135
|
setActiveTab?.(tab);
|
|
136
136
|
}
|
|
137
|
-
}, children: [_jsxs(TabsListPrimitive, { className: "font-neue-montreal-semibold text-b3-grey flex h-8 w-full items-start justify-start gap-8 border-0 text-xl md:p-4", children: [_jsx(TabTriggerPrimitive, { value: "balance", className: "data-[state=active]:text-b3-primary-blue data-[state=active]:border-b-b3-primary-blue flex-none rounded-none border-0 p-0 pb-1 text-xl leading-none tracking-wide transition-colors data-[state=active]:border-b data-[state=active]:bg-white md:pb-4", children: "Overview" }), _jsx(TabTriggerPrimitive, { value: "assets", className: "data-[state=active]:text-b3-primary-blue data-[state=active]:border-b-b3-primary-blue flex-none rounded-none border-0 p-0 pb-1 text-xl leading-none tracking-wide transition-colors data-[state=active]:border-b data-[state=active]:bg-white md:pb-4", children: "Mints" }), _jsx(TabTriggerPrimitive, { value: "
|
|
137
|
+
}, children: [_jsxs(TabsListPrimitive, { className: "font-neue-montreal-semibold text-b3-grey flex h-8 w-full items-start justify-start gap-8 border-0 text-xl md:p-4", children: [_jsx(TabTriggerPrimitive, { value: "balance", className: "data-[state=active]:text-b3-primary-blue data-[state=active]:border-b-b3-primary-blue flex-none rounded-none border-0 p-0 pb-1 text-xl leading-none tracking-wide transition-colors data-[state=active]:border-b data-[state=active]:bg-white md:pb-4", children: "Overview" }), _jsx(TabTriggerPrimitive, { value: "assets", className: "data-[state=active]:text-b3-primary-blue data-[state=active]:border-b-b3-primary-blue flex-none rounded-none border-0 p-0 pb-1 text-xl leading-none tracking-wide transition-colors data-[state=active]:border-b data-[state=active]:bg-white md:pb-4", children: "Mints" }), _jsx(TabTriggerPrimitive, { value: "settings", className: "data-[state=active]:text-b3-primary-blue data-[state=active]:border-b-b3-primary-blue flex-none rounded-none border-0 p-0 pb-1 text-xl leading-none tracking-wide transition-colors data-[state=active]:border-b data-[state=active]:bg-white md:pb-4", children: "Settings" })] }), _jsx(TabsContentPrimitive, { value: "balance", className: "pt-4 md:p-4", children: _jsx(BalanceContent, {}) }), _jsx(TabsContentPrimitive, { value: "assets", className: "pt-4 md:p-4", children: _jsx(AssetsContent, {}) }), _jsx(TabsContentPrimitive, { value: "apps", className: "pt-4 md:p-4", children: _jsx(AppsContent, {}) }), _jsx(TabsContentPrimitive, { value: "settings", className: "pt-4 md:p-4", children: _jsx(SettingsContent, {}) })] }) }) }));
|
|
138
138
|
}
|
|
@@ -18,8 +18,9 @@ interface UseAnyspendFlowProps {
|
|
|
18
18
|
onTransactionSuccess?: () => void;
|
|
19
19
|
sourceTokenAddress?: string;
|
|
20
20
|
sourceTokenChainId?: number;
|
|
21
|
+
slippage?: number;
|
|
21
22
|
}
|
|
22
|
-
export declare function useAnyspendFlow({ paymentType, recipientAddress, loadOrder, isDepositMode, onOrderSuccess, onTransactionSuccess, sourceTokenAddress, sourceTokenChainId, }: UseAnyspendFlowProps): {
|
|
23
|
+
export declare function useAnyspendFlow({ paymentType, recipientAddress, loadOrder, isDepositMode, onOrderSuccess, onTransactionSuccess, sourceTokenAddress, sourceTokenChainId, slippage, }: UseAnyspendFlowProps): {
|
|
23
24
|
activePanel: PanelView;
|
|
24
25
|
setActivePanel: import("react").Dispatch<import("react").SetStateAction<PanelView>>;
|
|
25
26
|
orderId: string | undefined;
|
package/package.json
CHANGED
|
@@ -22,6 +22,8 @@ import { ESCROW_ABI } from "@b3dotfun/sdk/anyspend/abis/escrow";
|
|
|
22
22
|
import { ArrowDown } from "lucide-react";
|
|
23
23
|
import { PanelOnramp } from "./common/PanelOnramp";
|
|
24
24
|
|
|
25
|
+
const SLIPPAGE_PERCENT = 3;
|
|
26
|
+
|
|
25
27
|
function generateEncodedDataForDepositHype(amount: string, beneficiary: string): string {
|
|
26
28
|
invariant(BigInt(amount) > 0, "Amount must be greater than zero");
|
|
27
29
|
const encodedData = encodeFunctionData({
|
|
@@ -107,6 +109,7 @@ function AnySpendDepositHypeInner({
|
|
|
107
109
|
onTransactionSuccess: onSuccess,
|
|
108
110
|
sourceTokenAddress,
|
|
109
111
|
sourceTokenChainId,
|
|
112
|
+
slippage: SLIPPAGE_PERCENT,
|
|
110
113
|
});
|
|
111
114
|
|
|
112
115
|
// Button state logic
|
|
@@ -308,7 +311,12 @@ function AnySpendDepositHypeInner({
|
|
|
308
311
|
invariant(depositContractAddress, "Deposit contract address is not found");
|
|
309
312
|
|
|
310
313
|
const srcAmountBigInt = BigInt(activeInputAmountInWei);
|
|
311
|
-
|
|
314
|
+
// TODO: temp subtract 3% for slippage
|
|
315
|
+
const originalDepositAmountWei = anyspendQuote.data?.currencyOut?.amount || "0";
|
|
316
|
+
const depositAmountWei = (
|
|
317
|
+
(BigInt(originalDepositAmountWei) * BigInt(100 - SLIPPAGE_PERCENT)) /
|
|
318
|
+
BigInt(100)
|
|
319
|
+
).toString();
|
|
312
320
|
const encodedData = generateEncodedDataForDepositHype(depositAmountWei, selectedRecipientAddress);
|
|
313
321
|
|
|
314
322
|
createOrder({
|
|
@@ -472,8 +480,6 @@ function AnySpendDepositHypeInner({
|
|
|
472
480
|
/>
|
|
473
481
|
);
|
|
474
482
|
|
|
475
|
-
console.log("activePanel", activePanel, orderId, oat);
|
|
476
|
-
|
|
477
483
|
// If showing token selection, render with panel transitions
|
|
478
484
|
return (
|
|
479
485
|
<StyleRoot>
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
ALL_CHAINS,
|
|
5
|
+
DEPOSIT_HYPE_ACTION,
|
|
5
6
|
getChainName,
|
|
6
7
|
getErrorDisplay,
|
|
7
8
|
getExplorerTxUrl,
|
|
@@ -97,6 +98,9 @@ function getOrderSuccessText({
|
|
|
97
98
|
actionText = `funded ${tournament?.name}`;
|
|
98
99
|
return `Successfully ${actionText}`;
|
|
99
100
|
case "custom":
|
|
101
|
+
if (order.metadata.action === DEPOSIT_HYPE_ACTION) {
|
|
102
|
+
return `Successfully deposited ${formatTokenAmount(BigInt(order.payload?.amount || "0"), 18)} HYPE to ${recipient}`;
|
|
103
|
+
}
|
|
100
104
|
actionText = order.metadata.action || `executed contract`;
|
|
101
105
|
return `Successfully ${actionText}`;
|
|
102
106
|
default:
|
|
@@ -35,6 +35,7 @@ interface UseAnyspendFlowProps {
|
|
|
35
35
|
onTransactionSuccess?: () => void;
|
|
36
36
|
sourceTokenAddress?: string;
|
|
37
37
|
sourceTokenChainId?: number;
|
|
38
|
+
slippage?: number;
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
export function useAnyspendFlow({
|
|
@@ -46,6 +47,7 @@ export function useAnyspendFlow({
|
|
|
46
47
|
onTransactionSuccess,
|
|
47
48
|
sourceTokenAddress,
|
|
48
49
|
sourceTokenChainId,
|
|
50
|
+
slippage = 0,
|
|
49
51
|
}: UseAnyspendFlowProps) {
|
|
50
52
|
const searchParams = useSearchParamsSSR();
|
|
51
53
|
const router = useRouter();
|
|
@@ -144,12 +146,16 @@ export function useAnyspendFlow({
|
|
|
144
146
|
if (anyspendQuote?.data?.currencyOut?.amount && anyspendQuote.data.currencyOut.currency?.decimals) {
|
|
145
147
|
const amount = anyspendQuote.data.currencyOut.amount;
|
|
146
148
|
const decimals = anyspendQuote.data.currencyOut.currency.decimals;
|
|
147
|
-
|
|
149
|
+
|
|
150
|
+
// Apply slippage (0-100) - reduce amount by slippage percentageFixed slippage value
|
|
151
|
+
const amountWithSlippage = (BigInt(amount) * BigInt(100 - slippage)) / BigInt(100);
|
|
152
|
+
|
|
153
|
+
const formattedAmount = formatTokenAmount(amountWithSlippage, decimals, 6, false);
|
|
148
154
|
setDstAmount(formattedAmount);
|
|
149
155
|
} else {
|
|
150
156
|
setDstAmount("");
|
|
151
157
|
}
|
|
152
|
-
}, [anyspendQuote]);
|
|
158
|
+
}, [anyspendQuote, slippage]);
|
|
153
159
|
|
|
154
160
|
// Update useEffect for URL parameter to not override loadOrder
|
|
155
161
|
useEffect(() => {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ecosystemWalletId } from "@b3dotfun/sdk/shared/constants";
|
|
1
2
|
import { client } from "@b3dotfun/sdk/shared/utils/thirdweb";
|
|
2
3
|
import { Loader2 } from "lucide-react";
|
|
3
4
|
import { useCallback, useEffect, useState } from "react";
|
|
@@ -122,12 +123,20 @@ export function LinkAccount({
|
|
|
122
123
|
client,
|
|
123
124
|
strategy: "email",
|
|
124
125
|
email,
|
|
126
|
+
ecosystem: {
|
|
127
|
+
id: ecosystemWalletId,
|
|
128
|
+
partnerId: partnerId,
|
|
129
|
+
},
|
|
125
130
|
});
|
|
126
131
|
} else if (selectedMethod === "phone") {
|
|
127
132
|
await preAuthenticate({
|
|
128
133
|
client,
|
|
129
134
|
strategy: "phone",
|
|
130
135
|
phoneNumber: phone,
|
|
136
|
+
ecosystem: {
|
|
137
|
+
id: ecosystemWalletId,
|
|
138
|
+
partnerId: partnerId,
|
|
139
|
+
},
|
|
131
140
|
});
|
|
132
141
|
}
|
|
133
142
|
|
|
@@ -142,11 +151,13 @@ export function LinkAccount({
|
|
|
142
151
|
|
|
143
152
|
const handleLinkAccount = async () => {
|
|
144
153
|
if (!otp) {
|
|
154
|
+
console.error("No OTP entered");
|
|
145
155
|
setError("Please enter the verification code");
|
|
146
156
|
return;
|
|
147
157
|
}
|
|
148
158
|
|
|
149
159
|
try {
|
|
160
|
+
setOtpSent(false);
|
|
150
161
|
setLinkingState(true, selectedMethod);
|
|
151
162
|
setError(null);
|
|
152
163
|
|
|
@@ -171,15 +182,10 @@ export function LinkAccount({
|
|
|
171
182
|
mutationOptions,
|
|
172
183
|
);
|
|
173
184
|
}
|
|
174
|
-
|
|
175
|
-
onSuccess?.();
|
|
176
|
-
onClose?.();
|
|
177
185
|
} catch (error) {
|
|
178
186
|
console.error("Error linking account:", error);
|
|
179
187
|
setError(error instanceof Error ? error.message : "Failed to link account");
|
|
180
188
|
onError?.(error as Error);
|
|
181
|
-
} finally {
|
|
182
|
-
setLinkingState(false);
|
|
183
189
|
}
|
|
184
190
|
};
|
|
185
191
|
|
|
@@ -239,8 +245,13 @@ export function LinkAccount({
|
|
|
239
245
|
setLinkingState(false);
|
|
240
246
|
}, [isLinking, setSelectedMethod, setEmail, setPhone, setOtp, setOtpSent, setError, setLinkingState]);
|
|
241
247
|
|
|
242
|
-
|
|
243
|
-
|
|
248
|
+
const handleFinishedLinking = useCallback(
|
|
249
|
+
(success: boolean) => {
|
|
250
|
+
if (success) {
|
|
251
|
+
onSuccess?.();
|
|
252
|
+
onClose?.();
|
|
253
|
+
}
|
|
254
|
+
|
|
244
255
|
setLinkingState(false);
|
|
245
256
|
navigateBack();
|
|
246
257
|
setB3ModalContentType({
|
|
@@ -250,6 +261,13 @@ export function LinkAccount({
|
|
|
250
261
|
chain,
|
|
251
262
|
partnerId,
|
|
252
263
|
});
|
|
264
|
+
},
|
|
265
|
+
[chain, navigateBack, partnerId, setB3ModalContentType, setLinkingState, onSuccess, onClose],
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
useEffect(() => {
|
|
269
|
+
if (isLinking) {
|
|
270
|
+
handleFinishedLinking(true);
|
|
253
271
|
}
|
|
254
272
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
255
273
|
}, [profiles.length]);
|
|
@@ -338,15 +356,13 @@ export function LinkAccount({
|
|
|
338
356
|
className="bg-b3-line text-b3-grey font-neue-montreal-medium focus:ring-b3-primary-blue/20 w-full rounded-xl p-4 focus:outline-none focus:ring-2"
|
|
339
357
|
value={otp}
|
|
340
358
|
onChange={e => setOtp(e.target.value)}
|
|
341
|
-
disabled={isLinking && linkingMethod === selectedMethod}
|
|
342
359
|
/>
|
|
343
360
|
</div>
|
|
344
361
|
<Button
|
|
345
362
|
className="bg-b3-primary-blue hover:bg-b3-primary-blue/90 font-neue-montreal-semibold h-12 w-full text-white"
|
|
346
363
|
onClick={handleLinkAccount}
|
|
347
|
-
disabled={!otp || (isLinking && linkingMethod === selectedMethod)}
|
|
348
364
|
>
|
|
349
|
-
|
|
365
|
+
Link Account
|
|
350
366
|
</Button>
|
|
351
367
|
</div>
|
|
352
368
|
) : (
|
|
@@ -597,12 +597,16 @@ export function ManageAccount({
|
|
|
597
597
|
>
|
|
598
598
|
Mints
|
|
599
599
|
</TabTriggerPrimitive>
|
|
600
|
+
{/*
|
|
601
|
+
// TODO: Apps is a remnant of session key flow. Moving forward, we should find a way to properly associate apps from linked partners that a user has logged in with
|
|
602
|
+
https://linear.app/npclabs/issue/B3-2318/find-a-way-to-properly-display-which-partner-apps-a-user-has-logged-in
|
|
603
|
+
|
|
600
604
|
<TabTriggerPrimitive
|
|
601
605
|
value="apps"
|
|
602
606
|
className="data-[state=active]:text-b3-primary-blue data-[state=active]:border-b-b3-primary-blue flex-none rounded-none border-0 p-0 pb-1 text-xl leading-none tracking-wide transition-colors data-[state=active]:border-b data-[state=active]:bg-white md:pb-4"
|
|
603
607
|
>
|
|
604
608
|
Apps
|
|
605
|
-
</TabTriggerPrimitive>
|
|
609
|
+
</TabTriggerPrimitive> */}
|
|
606
610
|
<TabTriggerPrimitive
|
|
607
611
|
value="settings"
|
|
608
612
|
className="data-[state=active]:text-b3-primary-blue data-[state=active]:border-b-b3-primary-blue flex-none rounded-none border-0 p-0 pb-1 text-xl leading-none tracking-wide transition-colors data-[state=active]:border-b data-[state=active]:bg-white md:pb-4"
|