@b3dotfun/sdk 0.0.62 → 0.0.63-alpha.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.
- package/dist/cjs/anyspend/react/components/AnySpend.js +61 -23
- package/dist/cjs/anyspend/react/components/AnySpendCustom.js +3 -0
- package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.d.ts +34 -0
- package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.js +275 -0
- package/dist/cjs/anyspend/react/components/AnySpendStakeB3.js +5 -4
- package/dist/cjs/anyspend/react/components/AnySpendStakeB3ExactIn.d.ts +9 -0
- package/dist/cjs/anyspend/react/components/AnySpendStakeB3ExactIn.js +288 -0
- package/dist/cjs/anyspend/react/components/AnySpendStakeUpsideExactIn.d.ts +11 -0
- package/dist/cjs/anyspend/react/components/AnySpendStakeUpsideExactIn.js +33 -0
- package/dist/cjs/anyspend/react/components/AnyspendDepositHype.js +4 -4
- package/dist/cjs/anyspend/react/components/common/CryptoPaySection.js +4 -6
- package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.js +9 -17
- package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.d.ts +6 -1
- package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.js +11 -1
- package/dist/cjs/anyspend/react/components/common/OrderDetails.js +66 -147
- package/dist/cjs/anyspend/react/components/common/OrderDetailsCollapsible.js +2 -3
- package/dist/cjs/anyspend/react/components/common/OrderTokenAmount.d.ts +2 -1
- package/dist/cjs/anyspend/react/components/common/OrderTokenAmount.js +39 -15
- package/dist/cjs/anyspend/react/components/common/PaySection.js +1 -1
- package/dist/cjs/anyspend/react/components/common/TokenBalance.js +1 -1
- package/dist/cjs/anyspend/react/components/index.d.ts +5 -1
- package/dist/cjs/anyspend/react/components/index.js +11 -3
- package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.d.ts +25 -3
- package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.js +42 -19
- package/dist/cjs/anyspend/react/hooks/useAnyspendOrderHistory.d.ts +116 -0
- package/dist/cjs/anyspend/react/hooks/useAnyspendQuote.js +1 -1
- package/dist/cjs/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.d.ts +26 -0
- package/dist/cjs/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.js +56 -0
- package/dist/cjs/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.d.ts +10 -0
- package/dist/cjs/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.js +73 -0
- package/dist/cjs/anyspend/react/hooks/useConnectedWalletDisplay.d.ts +14 -0
- package/dist/cjs/anyspend/react/hooks/useConnectedWalletDisplay.js +57 -0
- package/dist/cjs/anyspend/react/hooks/usePhantomTransfer.d.ts +36 -0
- package/dist/cjs/anyspend/react/hooks/usePhantomTransfer.js +211 -0
- package/dist/cjs/anyspend/types/api.d.ts +665 -3
- package/dist/cjs/anyspend/utils/orderPayload.js +4 -0
- package/dist/cjs/global-account/react/components/B3DynamicModal.js +17 -4
- package/dist/cjs/global-account/react/components/ManageAccount/BalanceContent.js +3 -3
- package/dist/cjs/global-account/react/components/ProfileEditor/ProfileEditor.d.ts +6 -0
- package/dist/cjs/global-account/react/components/ProfileEditor/ProfileEditor.js +141 -0
- package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +3 -1
- package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStep.js +2 -2
- package/dist/cjs/global-account/react/components/index.d.ts +2 -0
- package/dist/cjs/global-account/react/components/index.js +7 -2
- package/dist/cjs/global-account/react/hooks/index.d.ts +2 -1
- package/dist/cjs/global-account/react/hooks/index.js +5 -3
- package/dist/cjs/global-account/react/hooks/useAuthentication.d.ts +2 -2
- package/dist/cjs/global-account/react/hooks/useAuthentication.js +7 -2
- package/dist/cjs/global-account/react/hooks/useSimBalance.d.ts +1 -1
- package/dist/cjs/global-account/react/hooks/useSimBalance.js +6 -5
- package/dist/cjs/global-account/react/hooks/useTokenBalanceDirect.d.ts +12 -0
- package/dist/cjs/global-account/react/hooks/useTokenBalanceDirect.js +62 -0
- package/dist/cjs/global-account/react/hooks/useTokenFromUrl.js +4 -3
- package/dist/cjs/global-account/react/stores/useModalStore.d.ts +37 -1
- package/dist/cjs/global-account/react/utils/profileDisplay.d.ts +6 -0
- package/dist/cjs/global-account/react/utils/profileDisplay.js +60 -4
- package/dist/esm/anyspend/react/components/AnySpend.js +62 -24
- package/dist/esm/anyspend/react/components/AnySpendCustom.js +3 -0
- package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.d.ts +34 -0
- package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.js +269 -0
- package/dist/esm/anyspend/react/components/AnySpendStakeB3.js +7 -6
- package/dist/esm/anyspend/react/components/AnySpendStakeB3ExactIn.d.ts +9 -0
- package/dist/esm/anyspend/react/components/AnySpendStakeB3ExactIn.js +285 -0
- package/dist/esm/anyspend/react/components/AnySpendStakeUpsideExactIn.d.ts +11 -0
- package/dist/esm/anyspend/react/components/AnySpendStakeUpsideExactIn.js +30 -0
- package/dist/esm/anyspend/react/components/AnyspendDepositHype.js +4 -4
- package/dist/esm/anyspend/react/components/common/CryptoPaySection.js +5 -7
- package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.js +9 -17
- package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.d.ts +6 -1
- package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.js +11 -1
- package/dist/esm/anyspend/react/components/common/OrderDetails.js +67 -148
- package/dist/esm/anyspend/react/components/common/OrderDetailsCollapsible.js +2 -3
- package/dist/esm/anyspend/react/components/common/OrderTokenAmount.d.ts +2 -1
- package/dist/esm/anyspend/react/components/common/OrderTokenAmount.js +40 -16
- package/dist/esm/anyspend/react/components/common/PaySection.js +1 -1
- package/dist/esm/anyspend/react/components/common/TokenBalance.js +2 -2
- package/dist/esm/anyspend/react/components/index.d.ts +5 -1
- package/dist/esm/anyspend/react/components/index.js +5 -1
- package/dist/esm/anyspend/react/hooks/useAnyspendFlow.d.ts +25 -3
- package/dist/esm/anyspend/react/hooks/useAnyspendFlow.js +42 -19
- package/dist/esm/anyspend/react/hooks/useAnyspendOrderHistory.d.ts +116 -0
- package/dist/esm/anyspend/react/hooks/useAnyspendQuote.js +1 -1
- package/dist/esm/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.d.ts +26 -0
- package/dist/esm/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.js +53 -0
- package/dist/esm/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.d.ts +10 -0
- package/dist/esm/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.js +70 -0
- package/dist/esm/anyspend/react/hooks/useConnectedWalletDisplay.d.ts +14 -0
- package/dist/esm/anyspend/react/hooks/useConnectedWalletDisplay.js +54 -0
- package/dist/esm/anyspend/react/hooks/usePhantomTransfer.d.ts +36 -0
- package/dist/esm/anyspend/react/hooks/usePhantomTransfer.js +208 -0
- package/dist/esm/anyspend/types/api.d.ts +665 -3
- package/dist/esm/anyspend/utils/orderPayload.js +4 -0
- package/dist/esm/global-account/react/components/B3DynamicModal.js +18 -5
- package/dist/esm/global-account/react/components/ManageAccount/BalanceContent.js +3 -3
- package/dist/esm/global-account/react/components/ProfileEditor/ProfileEditor.d.ts +6 -0
- package/dist/esm/global-account/react/components/ProfileEditor/ProfileEditor.js +135 -0
- package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +3 -1
- package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStep.js +2 -2
- package/dist/esm/global-account/react/components/index.d.ts +2 -0
- package/dist/esm/global-account/react/components/index.js +3 -0
- package/dist/esm/global-account/react/hooks/index.d.ts +2 -1
- package/dist/esm/global-account/react/hooks/index.js +2 -1
- package/dist/esm/global-account/react/hooks/useAuthentication.d.ts +2 -2
- package/dist/esm/global-account/react/hooks/useAuthentication.js +7 -2
- package/dist/esm/global-account/react/hooks/useSimBalance.d.ts +1 -1
- package/dist/esm/global-account/react/hooks/useSimBalance.js +6 -5
- package/dist/esm/global-account/react/hooks/useTokenBalanceDirect.d.ts +12 -0
- package/dist/esm/global-account/react/hooks/useTokenBalanceDirect.js +59 -0
- package/dist/esm/global-account/react/hooks/useTokenFromUrl.js +4 -3
- package/dist/esm/global-account/react/stores/useModalStore.d.ts +37 -1
- package/dist/esm/global-account/react/utils/profileDisplay.d.ts +6 -0
- package/dist/esm/global-account/react/utils/profileDisplay.js +59 -4
- package/dist/types/anyspend/react/components/AnySpendCustomExactIn.d.ts +34 -0
- package/dist/types/anyspend/react/components/AnySpendStakeB3ExactIn.d.ts +9 -0
- package/dist/types/anyspend/react/components/AnySpendStakeUpsideExactIn.d.ts +11 -0
- package/dist/types/anyspend/react/components/common/CryptoReceiveSection.d.ts +6 -1
- package/dist/types/anyspend/react/components/common/OrderTokenAmount.d.ts +2 -1
- package/dist/types/anyspend/react/components/index.d.ts +5 -1
- package/dist/types/anyspend/react/hooks/useAnyspendFlow.d.ts +25 -3
- package/dist/types/anyspend/react/hooks/useAnyspendOrderHistory.d.ts +116 -0
- package/dist/types/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.d.ts +26 -0
- package/dist/types/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.d.ts +10 -0
- package/dist/types/anyspend/react/hooks/useConnectedWalletDisplay.d.ts +14 -0
- package/dist/types/anyspend/react/hooks/usePhantomTransfer.d.ts +36 -0
- package/dist/types/anyspend/types/api.d.ts +665 -3
- package/dist/types/global-account/react/components/ProfileEditor/ProfileEditor.d.ts +6 -0
- package/dist/types/global-account/react/components/index.d.ts +2 -0
- package/dist/types/global-account/react/hooks/index.d.ts +2 -1
- package/dist/types/global-account/react/hooks/useAuthentication.d.ts +2 -2
- package/dist/types/global-account/react/hooks/useSimBalance.d.ts +1 -1
- package/dist/types/global-account/react/hooks/useTokenBalanceDirect.d.ts +12 -0
- package/dist/types/global-account/react/stores/useModalStore.d.ts +37 -1
- package/dist/types/global-account/react/utils/profileDisplay.d.ts +6 -0
- package/package.json +4 -3
- package/src/anyspend/react/components/AnySpend.tsx +73 -22
- package/src/anyspend/react/components/AnySpendCustom.tsx +4 -0
- package/src/anyspend/react/components/AnySpendCustomExactIn.tsx +595 -0
- package/src/anyspend/react/components/AnySpendStakeB3.tsx +8 -11
- package/src/anyspend/react/components/AnySpendStakeB3ExactIn.tsx +522 -0
- package/src/anyspend/react/components/AnySpendStakeUpsideExactIn.tsx +73 -0
- package/src/anyspend/react/components/AnyspendDepositHype.tsx +7 -3
- package/src/anyspend/react/components/common/CryptoPaySection.tsx +5 -7
- package/src/anyspend/react/components/common/CryptoPaymentMethod.tsx +9 -18
- package/src/anyspend/react/components/common/CryptoReceiveSection.tsx +22 -0
- package/src/anyspend/react/components/common/OrderDetails.tsx +76 -190
- package/src/anyspend/react/components/common/OrderDetailsCollapsible.tsx +2 -3
- package/src/anyspend/react/components/common/OrderTokenAmount.tsx +48 -17
- package/src/anyspend/react/components/common/PaySection.tsx +1 -0
- package/src/anyspend/react/components/common/TokenBalance.tsx +2 -2
- package/src/anyspend/react/components/index.ts +5 -1
- package/src/anyspend/react/hooks/useAnyspendFlow.ts +51 -18
- package/src/anyspend/react/hooks/useAnyspendQuote.ts +1 -1
- package/src/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.ts +72 -0
- package/src/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.ts +80 -0
- package/src/anyspend/react/hooks/useConnectedWalletDisplay.ts +69 -0
- package/src/anyspend/react/hooks/usePhantomTransfer.ts +301 -0
- package/src/anyspend/types/api.ts +669 -1
- package/src/anyspend/utils/orderPayload.ts +5 -1
- package/src/global-account/react/components/B3DynamicModal.tsx +18 -4
- package/src/global-account/react/components/ManageAccount/BalanceContent.tsx +4 -4
- package/src/global-account/react/components/ProfileEditor/ProfileEditor.tsx +265 -0
- package/src/global-account/react/components/SignInWithB3/SignInWithB3Flow.tsx +3 -1
- package/src/global-account/react/components/SignInWithB3/steps/LoginStep.tsx +2 -2
- package/src/global-account/react/components/index.ts +4 -0
- package/src/global-account/react/hooks/index.ts +2 -1
- package/src/global-account/react/hooks/useAuthentication.ts +10 -2
- package/src/global-account/react/hooks/useSimBalance.ts +6 -5
- package/src/global-account/react/hooks/useTokenBalanceDirect.tsx +84 -0
- package/src/global-account/react/hooks/useTokenFromUrl.tsx +6 -5
- package/src/global-account/react/stores/useModalStore.ts +43 -1
- package/src/global-account/react/utils/profileDisplay.ts +67 -4
|
@@ -210,6 +210,20 @@ export interface AnySpendStakeB3Props extends BaseModalProps {
|
|
|
210
210
|
/** Callback function called when the stake is successful */
|
|
211
211
|
onSuccess?: () => void;
|
|
212
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* Props for the AnySpend Stake B3 (Custom Exact In) modal
|
|
215
|
+
* Handles B3 token staking operations using the custom exact in flow
|
|
216
|
+
*/
|
|
217
|
+
export interface AnySpendStakeB3ExactInProps extends BaseModalProps {
|
|
218
|
+
/** Modal type identifier */
|
|
219
|
+
type: "anySpendStakeB3ExactIn";
|
|
220
|
+
/** Recipient address to stake B3 for */
|
|
221
|
+
recipientAddress: string;
|
|
222
|
+
/** Stake amount */
|
|
223
|
+
stakeAmount?: string;
|
|
224
|
+
/** Callback function called when the stake is successful */
|
|
225
|
+
onSuccess?: () => void;
|
|
226
|
+
}
|
|
213
227
|
/**
|
|
214
228
|
* Props for the AnySpend Stake Contract modal
|
|
215
229
|
* Handles token staking operations to a given contract
|
|
@@ -230,6 +244,22 @@ export interface AnySpendStakeUpsideProps extends BaseModalProps {
|
|
|
230
244
|
/** Callback function called when the stake is successful */
|
|
231
245
|
onSuccess?: () => void;
|
|
232
246
|
}
|
|
247
|
+
/**
|
|
248
|
+
* Props for the AnySpend Stake Upside (Exact In) modal
|
|
249
|
+
* Handles token staking operations using the custom exact in flow
|
|
250
|
+
*/
|
|
251
|
+
export interface AnySpendStakeUpsideExactInProps extends BaseModalProps {
|
|
252
|
+
/** Modal type identifier */
|
|
253
|
+
type: "anySpendStakeUpsideExactIn";
|
|
254
|
+
/** Recipient address to stake tokens for */
|
|
255
|
+
recipientAddress: string;
|
|
256
|
+
/** Staking contract address */
|
|
257
|
+
stakingContractAddress: string;
|
|
258
|
+
/** Token to stake */
|
|
259
|
+
token: components["schemas"]["Token"];
|
|
260
|
+
/** Callback function called when the stake is successful */
|
|
261
|
+
onSuccess?: () => void;
|
|
262
|
+
}
|
|
233
263
|
/**
|
|
234
264
|
* Props for the AnySpend Buy Spin modal
|
|
235
265
|
* Handles spin wheel entry purchases
|
|
@@ -321,10 +351,16 @@ export interface AvatarEditorModalProps extends BaseModalProps {
|
|
|
321
351
|
/** Callback function called when avatar is successfully set */
|
|
322
352
|
onSuccess?: () => void;
|
|
323
353
|
}
|
|
354
|
+
export interface ProfileEditorModalProps extends BaseModalProps {
|
|
355
|
+
/** Modal type identifier */
|
|
356
|
+
type: "profileEditor";
|
|
357
|
+
/** Callback function called when profile is successfully updated */
|
|
358
|
+
onSuccess?: () => void;
|
|
359
|
+
}
|
|
324
360
|
/**
|
|
325
361
|
* Union type of all possible modal content types
|
|
326
362
|
*/
|
|
327
|
-
export type ModalContentType = SignInWithB3ModalProps | RequestPermissionsModalProps | ManageAccountModalProps | AnySpendModalProps | AnyspendOrderDetailsProps | AnySpendNftProps | AnySpendJoinTournamentProps | AnySpendFundTournamentProps | AnySpendOrderHistoryProps | AnySpendStakeB3Props | AnySpendStakeUpsideProps | AnySpendBuySpinProps | AnySpendSignatureMintProps | AnySpendBondKitProps | LinkAccountModalProps | AnySpendDepositHypeProps | AvatarEditorModalProps;
|
|
363
|
+
export type ModalContentType = SignInWithB3ModalProps | RequestPermissionsModalProps | ManageAccountModalProps | AnySpendModalProps | AnyspendOrderDetailsProps | AnySpendNftProps | AnySpendJoinTournamentProps | AnySpendFundTournamentProps | AnySpendOrderHistoryProps | AnySpendStakeB3Props | AnySpendStakeB3ExactInProps | AnySpendStakeUpsideProps | AnySpendStakeUpsideExactInProps | AnySpendBuySpinProps | AnySpendSignatureMintProps | AnySpendBondKitProps | LinkAccountModalProps | AnySpendDepositHypeProps | AvatarEditorModalProps | ProfileEditorModalProps;
|
|
328
364
|
/**
|
|
329
365
|
* State interface for the modal store
|
|
330
366
|
*/
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { type Profile } from "thirdweb/wallets";
|
|
2
|
+
/**
|
|
3
|
+
* Validates that an image URL uses an allowed schema
|
|
4
|
+
* @param url - The URL to validate
|
|
5
|
+
* @returns The URL if valid, null otherwise
|
|
6
|
+
*/
|
|
7
|
+
export declare function validateImageUrl(url: string | null | undefined): string | null;
|
|
2
8
|
export interface ExtendedProfileDetails {
|
|
3
9
|
id?: string;
|
|
4
10
|
email?: string;
|
|
@@ -1,6 +1,62 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateImageUrl = validateImageUrl;
|
|
3
4
|
exports.getProfileDisplayInfo = getProfileDisplayInfo;
|
|
5
|
+
const debug_1 = require("../../../shared/utils/debug");
|
|
6
|
+
const debug = (0, debug_1.debugB3React)("profileDisplay");
|
|
7
|
+
/**
|
|
8
|
+
* Validates that an image URL uses an allowed schema
|
|
9
|
+
* @param url - The URL to validate
|
|
10
|
+
* @returns The URL if valid, null otherwise
|
|
11
|
+
*/
|
|
12
|
+
function validateImageUrl(url) {
|
|
13
|
+
if (!url)
|
|
14
|
+
return null;
|
|
15
|
+
try {
|
|
16
|
+
// For blob URLs (from createObjectURL)
|
|
17
|
+
if (url.startsWith("blob:")) {
|
|
18
|
+
return url;
|
|
19
|
+
}
|
|
20
|
+
// For IPFS protocol URLs
|
|
21
|
+
if (url.startsWith("ipfs://")) {
|
|
22
|
+
return url;
|
|
23
|
+
}
|
|
24
|
+
// Parse URL to validate protocol and hostname
|
|
25
|
+
const parsedUrl = new URL(url);
|
|
26
|
+
// Only allow http and https protocols
|
|
27
|
+
if (parsedUrl.protocol !== "http:" && parsedUrl.protocol !== "https:") {
|
|
28
|
+
debug("Rejected unsafe protocol:", parsedUrl.protocol, url);
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
// Whitelist of allowed IPFS gateway hostnames
|
|
32
|
+
const allowedIpfsGateways = [
|
|
33
|
+
"ipfs.io",
|
|
34
|
+
"gateway.pinata.cloud",
|
|
35
|
+
"cloudflare-ipfs.com",
|
|
36
|
+
"dweb.link",
|
|
37
|
+
"nftstorage.link",
|
|
38
|
+
"w3s.link",
|
|
39
|
+
];
|
|
40
|
+
// Check if hostname matches allowed IPFS gateways
|
|
41
|
+
const hostname = parsedUrl.hostname.toLowerCase();
|
|
42
|
+
const isAllowedIpfsGateway = allowedIpfsGateways.some(gateway => {
|
|
43
|
+
// Exact match or subdomain of the gateway
|
|
44
|
+
return hostname === gateway || hostname.endsWith(`.${gateway}`);
|
|
45
|
+
});
|
|
46
|
+
if (isAllowedIpfsGateway) {
|
|
47
|
+
return url;
|
|
48
|
+
}
|
|
49
|
+
// For standard HTTP(S) URLs from trusted sources
|
|
50
|
+
// Add additional hostname validation here if needed
|
|
51
|
+
// For now, allow all HTTP(S) URLs (can be restricted further if needed)
|
|
52
|
+
return url;
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
// Invalid URL format
|
|
56
|
+
debug("Invalid image URL format:", url, error);
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
4
60
|
function getProfileDisplayInfo(profile) {
|
|
5
61
|
const { type, details } = profile;
|
|
6
62
|
// Default display info
|
|
@@ -17,7 +73,7 @@ function getProfileDisplayInfo(profile) {
|
|
|
17
73
|
displayInfo = {
|
|
18
74
|
title: details.name || details.username || "Unknown",
|
|
19
75
|
subtitle: details.username ? `@${details.username}` : "X Account",
|
|
20
|
-
imageUrl: details.profileImageUrl
|
|
76
|
+
imageUrl: validateImageUrl(details.profileImageUrl),
|
|
21
77
|
initial: "X",
|
|
22
78
|
type,
|
|
23
79
|
};
|
|
@@ -26,7 +82,7 @@ function getProfileDisplayInfo(profile) {
|
|
|
26
82
|
displayInfo = {
|
|
27
83
|
title: details.name || details.username || "Unknown",
|
|
28
84
|
subtitle: details.username ? `@${details.username}` : "Farcaster Account",
|
|
29
|
-
imageUrl: details.profileImageUrl
|
|
85
|
+
imageUrl: validateImageUrl(details.profileImageUrl),
|
|
30
86
|
initial: "F",
|
|
31
87
|
type,
|
|
32
88
|
};
|
|
@@ -35,7 +91,7 @@ function getProfileDisplayInfo(profile) {
|
|
|
35
91
|
displayInfo = {
|
|
36
92
|
title: details.name || details.email || "Unknown",
|
|
37
93
|
subtitle: details.email || "Google Account",
|
|
38
|
-
imageUrl: details.profileImageUrl
|
|
94
|
+
imageUrl: validateImageUrl(details.profileImageUrl),
|
|
39
95
|
initial: "G",
|
|
40
96
|
type,
|
|
41
97
|
};
|
|
@@ -44,7 +100,7 @@ function getProfileDisplayInfo(profile) {
|
|
|
44
100
|
displayInfo = {
|
|
45
101
|
title: details.username || details.name || "Unknown",
|
|
46
102
|
subtitle: "Discord Account",
|
|
47
|
-
imageUrl: details.profileImageUrl
|
|
103
|
+
imageUrl: validateImageUrl(details.profileImageUrl),
|
|
48
104
|
initial: "D",
|
|
49
105
|
type,
|
|
50
106
|
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { getDefaultToken, USDC_BASE } from "../../../anyspend/index.js";
|
|
4
4
|
import { useAnyspendCreateOnrampOrder, useAnyspendCreateOrder, useAnyspendOrderAndTransactions, useAnyspendQuote, useGeoOnrampOptions, } from "../../../anyspend/react/index.js";
|
|
5
|
-
import { Button, ShinyButton, StyleRoot, TransitionPanel, useAccountWallet, useProfile, useRouter, useSearchParamsSSR, useTokenData, useTokenFromUrl, } from "../../../global-account/react/index.js";
|
|
5
|
+
import { Button, ShinyButton, StyleRoot, TransitionPanel, useAccountWallet, useProfile, useRouter, useSearchParamsSSR, useTokenBalanceDirect, useTokenData, useTokenFromUrl, } from "../../../global-account/react/index.js";
|
|
6
6
|
import { cn } from "../../../shared/utils/cn.js";
|
|
7
7
|
import { formatTokenAmount } from "../../../shared/utils/number.js";
|
|
8
8
|
import invariant from "invariant";
|
|
@@ -12,17 +12,19 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
|
12
12
|
import { toast } from "sonner";
|
|
13
13
|
import { parseUnits } from "viem";
|
|
14
14
|
import { base, mainnet } from "viem/chains";
|
|
15
|
+
import { useAutoSelectCryptoPaymentMethod } from "../hooks/useAutoSelectCryptoPaymentMethod.js";
|
|
16
|
+
import { useAutoSetActiveWalletFromWagmi } from "../hooks/useAutoSetActiveWalletFromWagmi.js";
|
|
15
17
|
import { AnySpendFingerprintWrapper, getFingerprintConfig } from "./AnySpendFingerprintWrapper.js";
|
|
16
18
|
import { CryptoPaymentMethod, CryptoPaymentMethodType } from "./common/CryptoPaymentMethod.js";
|
|
17
19
|
import { CryptoPaySection } from "./common/CryptoPaySection.js";
|
|
18
20
|
import { CryptoReceiveSection } from "./common/CryptoReceiveSection.js";
|
|
21
|
+
import { FeeDetailPanel } from "./common/FeeDetailPanel.js";
|
|
19
22
|
import { FiatPaymentMethod, FiatPaymentMethodComponent } from "./common/FiatPaymentMethod.js";
|
|
20
23
|
import { OrderDetails, OrderDetailsLoadingView } from "./common/OrderDetails.js";
|
|
21
24
|
import { OrderHistory } from "./common/OrderHistory.js";
|
|
22
25
|
import { PanelOnramp } from "./common/PanelOnramp.js";
|
|
23
26
|
import { PanelOnrampPayment } from "./common/PanelOnrampPayment.js";
|
|
24
27
|
import { PointsDetailPanel } from "./common/PointsDetailPanel.js";
|
|
25
|
-
import { FeeDetailPanel } from "./common/FeeDetailPanel.js";
|
|
26
28
|
import { RecipientSelection } from "./common/RecipientSelection.js";
|
|
27
29
|
import { TabSection } from "./common/TabSection.js";
|
|
28
30
|
export var PanelView;
|
|
@@ -304,13 +306,36 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
|
|
|
304
306
|
// );
|
|
305
307
|
// State for recipient selection
|
|
306
308
|
const [recipientAddress, setRecipientAddress] = useState();
|
|
307
|
-
const { address: globalAddress, wallet: globalWallet } = useAccountWallet();
|
|
309
|
+
const { address: globalAddress, wallet: globalWallet, connectedEOAWallet } = useAccountWallet();
|
|
308
310
|
const recipientProfile = useProfile({ address: recipientAddress, fresh: true });
|
|
309
311
|
const recipientName = recipientProfile.data?.name;
|
|
310
|
-
//
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
312
|
+
// Auto-set active wallet from wagmi
|
|
313
|
+
useAutoSetActiveWalletFromWagmi();
|
|
314
|
+
// Check token balance for crypto payments
|
|
315
|
+
const { rawBalance, isLoading: isBalanceLoading } = useTokenBalanceDirect({
|
|
316
|
+
token: selectedSrcToken,
|
|
317
|
+
address: connectedEOAWallet?.getAccount()?.address,
|
|
318
|
+
});
|
|
319
|
+
// Check if user has enough balanceuseAutoSetActiveWalletFromWagmi
|
|
320
|
+
const hasEnoughBalance = useMemo(() => {
|
|
321
|
+
if (!rawBalance || isBalanceLoading || activeTab !== "crypto")
|
|
322
|
+
return false;
|
|
323
|
+
try {
|
|
324
|
+
const requiredAmount = parseUnits(srcAmount.replace(/,/g, ""), selectedSrcToken.decimals);
|
|
325
|
+
return rawBalance >= requiredAmount;
|
|
326
|
+
}
|
|
327
|
+
catch {
|
|
328
|
+
return false;
|
|
329
|
+
}
|
|
330
|
+
}, [rawBalance, srcAmount, selectedSrcToken.decimals, isBalanceLoading, activeTab]);
|
|
331
|
+
// Auto-select crypto payment method based on available wallets and balance
|
|
332
|
+
useAutoSelectCryptoPaymentMethod({
|
|
333
|
+
paymentType: activeTab,
|
|
334
|
+
selectedCryptoPaymentMethod,
|
|
335
|
+
setSelectedCryptoPaymentMethod,
|
|
336
|
+
hasEnoughBalance,
|
|
337
|
+
isBalanceLoading,
|
|
338
|
+
});
|
|
314
339
|
// Get geo-based onramp options for fiat payments
|
|
315
340
|
const { geoData, coinbaseAvailablePaymentMethods, stripeWeb2Support } = useGeoOnrampOptions(srcAmountOnRamp);
|
|
316
341
|
// Helper function to map payment method to onramp vendor
|
|
@@ -474,17 +499,30 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
|
|
|
474
499
|
return { text: "Select a different token or chain", disable: true, error: false, loading: false };
|
|
475
500
|
if (isLoadingAnyspendQuote)
|
|
476
501
|
return { text: "Loading quote...", disable: true, error: false, loading: true };
|
|
477
|
-
if (!recipientAddress)
|
|
478
|
-
return { text: "Select recipient", disable: false, error: false, loading: false };
|
|
479
502
|
if (isCreatingOrder || isCreatingOnrampOrder)
|
|
480
503
|
return { text: "Creating order...", disable: true, error: false, loading: true };
|
|
481
504
|
if (!anyspendQuote || !anyspendQuote.success)
|
|
482
505
|
return { text: "No quote found", disable: true, error: false, loading: false };
|
|
506
|
+
if (activeTab === "fiat") {
|
|
507
|
+
// For fiat: check recipient first, then payment method
|
|
508
|
+
if (!recipientAddress)
|
|
509
|
+
return { text: "Select recipient", disable: false, error: false, loading: false };
|
|
510
|
+
// If no fiat payment method selected, show "Select payment method"
|
|
511
|
+
if (selectedFiatPaymentMethod === FiatPaymentMethod.NONE) {
|
|
512
|
+
return { text: "Select payment method", disable: false, error: false, loading: false };
|
|
513
|
+
}
|
|
514
|
+
// If payment method is selected, show "Buy"
|
|
515
|
+
return { text: "Buy", disable: false, error: false, loading: false };
|
|
516
|
+
}
|
|
483
517
|
if (activeTab === "crypto") {
|
|
518
|
+
// For crypto: check payment method first, then recipient
|
|
484
519
|
// If no payment method selected, show "Choose payment method"
|
|
485
520
|
if (selectedCryptoPaymentMethod === CryptoPaymentMethodType.NONE) {
|
|
486
521
|
return { text: "Choose payment method", disable: false, error: false, loading: false };
|
|
487
522
|
}
|
|
523
|
+
// Check recipient after payment method
|
|
524
|
+
if (!recipientAddress)
|
|
525
|
+
return { text: "Select recipient", disable: false, error: false, loading: false };
|
|
488
526
|
// If payment method selected, show appropriate action
|
|
489
527
|
if (selectedCryptoPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET ||
|
|
490
528
|
selectedCryptoPaymentMethod === CryptoPaymentMethodType.GLOBAL_WALLET) {
|
|
@@ -494,14 +532,6 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
|
|
|
494
532
|
return { text: "Continue to payment", disable: false, error: false, loading: false };
|
|
495
533
|
}
|
|
496
534
|
}
|
|
497
|
-
if (activeTab === "fiat") {
|
|
498
|
-
// If no fiat payment method selected, show "Select payment method"
|
|
499
|
-
if (selectedFiatPaymentMethod === FiatPaymentMethod.NONE) {
|
|
500
|
-
return { text: "Select payment method", disable: false, error: false, loading: false };
|
|
501
|
-
}
|
|
502
|
-
// If payment method is selected, show "Buy"
|
|
503
|
-
return { text: "Buy", disable: false, error: false, loading: false };
|
|
504
|
-
}
|
|
505
535
|
return { text: "Buy", disable: false, error: false, loading: false };
|
|
506
536
|
}, [
|
|
507
537
|
activeInputAmountInWei,
|
|
@@ -519,14 +549,15 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
|
|
|
519
549
|
const onMainButtonClick = async () => {
|
|
520
550
|
if (btnInfo.disable)
|
|
521
551
|
return;
|
|
522
|
-
if (!recipientAddress) {
|
|
523
|
-
navigateToPanel(PanelView.RECIPIENT_SELECTION, "forward");
|
|
524
|
-
return;
|
|
525
|
-
}
|
|
526
552
|
try {
|
|
527
553
|
invariant(anyspendQuote, "Relay price is not found");
|
|
528
|
-
invariant(recipientAddress, "Recipient address is not found");
|
|
529
554
|
if (activeTab === "fiat") {
|
|
555
|
+
// For fiat: check recipient first
|
|
556
|
+
if (!recipientAddress) {
|
|
557
|
+
navigateToPanel(PanelView.RECIPIENT_SELECTION, "forward");
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
invariant(recipientAddress, "Recipient address is not found");
|
|
530
561
|
// If no fiat payment method selected, show payment method selection
|
|
531
562
|
if (selectedFiatPaymentMethod === FiatPaymentMethod.NONE) {
|
|
532
563
|
navigateToPanel(PanelView.FIAT_PAYMENT_METHOD, "forward");
|
|
@@ -537,12 +568,19 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
|
|
|
537
568
|
return;
|
|
538
569
|
}
|
|
539
570
|
if (activeTab === "crypto") {
|
|
571
|
+
// For crypto: check payment method first, then recipient
|
|
540
572
|
// If no payment method selected, show payment method selection
|
|
541
573
|
if (selectedCryptoPaymentMethod === CryptoPaymentMethodType.NONE) {
|
|
542
574
|
console.log("No payment method selected, showing selection panel");
|
|
543
575
|
navigateToPanel(PanelView.CRYPTO_PAYMENT_METHOD, "forward");
|
|
544
576
|
return;
|
|
545
577
|
}
|
|
578
|
+
// Check recipient after payment method
|
|
579
|
+
if (!recipientAddress) {
|
|
580
|
+
navigateToPanel(PanelView.RECIPIENT_SELECTION, "forward");
|
|
581
|
+
return;
|
|
582
|
+
}
|
|
583
|
+
invariant(recipientAddress, "Recipient address is not found");
|
|
546
584
|
// If payment method is selected, create order with payment method info
|
|
547
585
|
if (selectedCryptoPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET ||
|
|
548
586
|
selectedCryptoPaymentMethod === CryptoPaymentMethodType.GLOBAL_WALLET ||
|
|
@@ -755,10 +793,10 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
|
|
|
755
793
|
const tempDstAmount = dstAmount;
|
|
756
794
|
setSrcAmount(tempDstAmount);
|
|
757
795
|
setDstAmount(tempSrcAmount);
|
|
758
|
-
}, children: _jsx("div", { className: "relative flex items-center justify-center transition-opacity", children: _jsx(ArrowDown, { className: "text-as-primary/50 h-5 w-5" }) }) }), activeTab === "crypto" && (_jsx(CryptoReceiveSection, { isDepositMode: false, isBuyMode: isBuyMode, selectedRecipientAddress: recipientAddress, recipientName: recipientName || undefined, onSelectRecipient: () => navigateToPanel(PanelView.RECIPIENT_SELECTION, "forward"), dstAmount: dstAmount, dstToken: selectedDstToken, selectedDstChainId: selectedDstChainId, setSelectedDstChainId: setSelectedDstChainId, setSelectedDstToken: setSelectedDstToken, isSrcInputDirty: isSrcInputDirty, onChangeDstAmount: value => {
|
|
796
|
+
}, children: _jsx("div", { className: "relative flex items-center justify-center transition-opacity", children: _jsx(ArrowDown, { className: "text-as-primary/50 h-5 w-5" }) }) }), activeTab === "crypto" && (_jsx(CryptoReceiveSection, { isDepositMode: false, isBuyMode: isBuyMode, selectedRecipientAddress: recipientAddress, recipientName: recipientName || undefined, onSelectRecipient: () => navigateToPanel(PanelView.RECIPIENT_SELECTION, "forward"), setRecipientAddress: setRecipientAddress, recipientAddressFromProps: recipientAddressFromProps, globalAddress: globalAddress, dstAmount: dstAmount, dstToken: selectedDstToken, selectedDstChainId: selectedDstChainId, setSelectedDstChainId: setSelectedDstChainId, setSelectedDstToken: setSelectedDstToken, isSrcInputDirty: isSrcInputDirty, onChangeDstAmount: value => {
|
|
759
797
|
setIsSrcInputDirty(false);
|
|
760
798
|
setDstAmount(value);
|
|
761
|
-
}, anyspendQuote: anyspendQuote, onShowPointsDetail: () => navigateToPanel(PanelView.POINTS_DETAIL, "forward"), onShowFeeDetail: () => navigateToPanel(PanelView.FEE_DETAIL, "forward") }))] }), _jsxs(motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0.2, ease: "easeInOut" }, className: cn("mt-4 flex w-full max-w-[460px] flex-col gap-2"), children: [_jsx(ShinyButton, { accentColor: "hsl(var(--as-brand))", disabled: btnInfo.disable, onClick: onMainButtonClick, className: cn("as-main-button relative w-full", btnInfo.error ? "!bg-as-red" : btnInfo.disable ? "!bg-as-on-surface-2" : "!bg-as-brand"), textClassName: cn(btnInfo.error ? "text-white" : btnInfo.disable ? "text-as-secondary" : "text-white"), children: _jsxs("div", { className: "flex items-center justify-center gap-2", children: [btnInfo.loading && _jsx(Loader2, { className: "h-4 w-4 animate-spin" }), btnInfo.text] }) }), !hideTransactionHistoryButton && (globalAddress || recipientAddress) ? (_jsxs(Button, { variant: "link", onClick: onClickHistory, className: "text-as-primary/50 hover:text-as-primary flex items-center gap-1 transition-colors", children: [_jsx(HistoryIcon, { className: "h-4 w-4" }), " ", _jsx("span", { className: "pr-4", children: "Transaction History" })] })) : null] })] }));
|
|
799
|
+
}, anyspendQuote: anyspendQuote, onShowPointsDetail: () => navigateToPanel(PanelView.POINTS_DETAIL, "forward"), onShowFeeDetail: () => navigateToPanel(PanelView.FEE_DETAIL, "forward"), selectedCryptoPaymentMethod: selectedCryptoPaymentMethod }))] }), _jsxs(motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0.2, ease: "easeInOut" }, className: cn("mt-4 flex w-full max-w-[460px] flex-col gap-2"), children: [_jsx(ShinyButton, { accentColor: "hsl(var(--as-brand))", disabled: btnInfo.disable, onClick: onMainButtonClick, className: cn("as-main-button relative w-full", btnInfo.error ? "!bg-as-red" : btnInfo.disable ? "!bg-as-on-surface-2" : "!bg-as-brand"), textClassName: cn(btnInfo.error ? "text-white" : btnInfo.disable ? "text-as-secondary" : "text-white"), children: _jsxs("div", { className: "flex items-center justify-center gap-2", children: [btnInfo.loading && _jsx(Loader2, { className: "h-4 w-4 animate-spin" }), btnInfo.text] }) }), !hideTransactionHistoryButton && (globalAddress || recipientAddress) ? (_jsxs(Button, { variant: "link", onClick: onClickHistory, className: "text-as-primary/50 hover:text-as-primary flex items-center gap-1 transition-colors", children: [_jsx(HistoryIcon, { className: "h-4 w-4" }), " ", _jsx("span", { className: "pr-4", children: "Transaction History" })] })) : null] })] }));
|
|
762
800
|
const onrampPaymentView = (_jsx(PanelOnrampPayment, { srcAmountOnRamp: srcAmountOnRamp, recipientName: recipientName || undefined, recipientAddress: recipientAddress, isBuyMode: isBuyMode, destinationTokenChainId: destinationTokenChainId, destinationTokenAddress: destinationTokenAddress, selectedDstChainId: selectedDstChainId, selectedDstToken: selectedDstToken, orderType: "swap", anyspendQuote: anyspendQuote, globalAddress: globalAddress, onOrderCreated: orderId => {
|
|
763
801
|
setOrderId(orderId);
|
|
764
802
|
navigateToPanel(PanelView.ORDER_DETAILS, "forward");
|
|
@@ -14,6 +14,7 @@ import React, { useCallback, useEffect, useMemo, useState } from "react";
|
|
|
14
14
|
import { toast } from "sonner";
|
|
15
15
|
import { base } from "viem/chains";
|
|
16
16
|
import { useFeatureFlags } from "../contexts/FeatureFlagsContext.js";
|
|
17
|
+
import { useAutoSetActiveWalletFromWagmi } from "../hooks/useAutoSetActiveWalletFromWagmi.js";
|
|
17
18
|
import { AnySpendFingerprintWrapper, getFingerprintConfig } from "./AnySpendFingerprintWrapper.js";
|
|
18
19
|
import { CryptoPaymentMethod, CryptoPaymentMethodType } from "./common/CryptoPaymentMethod.js";
|
|
19
20
|
import { FeeBreakDown } from "./common/FeeBreakDown.js";
|
|
@@ -110,6 +111,8 @@ function AnySpendCustomInner({ loadOrder, mode = "modal", activeTab: activeTabPr
|
|
|
110
111
|
const featureFlags = useFeatureFlags();
|
|
111
112
|
const searchParams = useSearchParamsSSR();
|
|
112
113
|
const router = useRouter();
|
|
114
|
+
// Auto-set active wallet from wagmi
|
|
115
|
+
useAutoSetActiveWalletFromWagmi();
|
|
113
116
|
const [activePanel, setActivePanel] = useState(loadOrder ? PanelView.ORDER_DETAILS : PanelView.CONFIRM_ORDER);
|
|
114
117
|
const [activeTab, setActiveTab] = useState(activeTabProps);
|
|
115
118
|
// Add state for selected payment methods
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { components } from "../../../anyspend/types/api";
|
|
2
|
+
import { GetQuoteResponse } from "../../../anyspend/types/api_req_res";
|
|
3
|
+
type CustomExactInConfig = {
|
|
4
|
+
functionAbi: string;
|
|
5
|
+
functionName: string;
|
|
6
|
+
functionArgs: string[];
|
|
7
|
+
to: string;
|
|
8
|
+
spenderAddress?: string;
|
|
9
|
+
action?: string;
|
|
10
|
+
};
|
|
11
|
+
export interface AnySpendCustomExactInProps {
|
|
12
|
+
loadOrder?: string;
|
|
13
|
+
mode?: "modal" | "page";
|
|
14
|
+
recipientAddress: string;
|
|
15
|
+
paymentType?: "crypto" | "fiat";
|
|
16
|
+
sourceTokenAddress?: string;
|
|
17
|
+
sourceTokenChainId?: number;
|
|
18
|
+
destinationToken: components["schemas"]["Token"];
|
|
19
|
+
destinationChainId: number;
|
|
20
|
+
onSuccess?: (amount: string) => void;
|
|
21
|
+
mainFooter?: React.ReactNode;
|
|
22
|
+
onTokenSelect?: (token: components["schemas"]["Token"], event: {
|
|
23
|
+
preventDefault: () => void;
|
|
24
|
+
}) => void;
|
|
25
|
+
customUsdInputValues?: string[];
|
|
26
|
+
preferEoa?: boolean;
|
|
27
|
+
customExactInConfig: CustomExactInConfig;
|
|
28
|
+
header?: ({ anyspendPrice, isLoadingAnyspendPrice, }: {
|
|
29
|
+
anyspendPrice: GetQuoteResponse | undefined;
|
|
30
|
+
isLoadingAnyspendPrice: boolean;
|
|
31
|
+
}) => React.JSX.Element;
|
|
32
|
+
}
|
|
33
|
+
export declare function AnySpendCustomExactIn(props: AnySpendCustomExactInProps): import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
export {};
|