@b3dotfun/sdk 0.0.70-alpha.0 → 0.0.70-alpha.2
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/index.d.ts +1 -0
- package/dist/cjs/anyspend/index.js +1 -0
- package/dist/cjs/anyspend/react/components/AnySpendCollectorClubPurchase.d.ts +57 -0
- package/dist/cjs/anyspend/react/components/AnySpendCollectorClubPurchase.js +82 -0
- package/dist/cjs/anyspend/react/components/AnySpendCustom.js +3 -1
- package/dist/cjs/anyspend/react/components/index.d.ts +1 -0
- package/dist/cjs/anyspend/react/components/index.js +3 -1
- package/dist/cjs/anyspend/react/hooks/useAnyspendCreateOnrampOrder.js +4 -0
- package/dist/cjs/anyspend/react/hooks/useAnyspendCreateOrder.js +4 -0
- package/dist/cjs/anyspend/react/hooks/useAnyspendOrderHistory.d.ts +16 -0
- package/dist/cjs/anyspend/react/hooks/useSigMint.d.ts +1 -1
- package/dist/cjs/anyspend/react/hooks/useValidatedClientReferenceId.d.ts +5 -0
- package/dist/cjs/anyspend/react/hooks/useValidatedClientReferenceId.js +35 -0
- package/dist/cjs/anyspend/services/anyspend.d.ts +2 -1
- package/dist/cjs/anyspend/services/anyspend.js +2 -1
- package/dist/cjs/anyspend/types/api.d.ts +295 -0
- package/dist/cjs/anyspend/utils/validation.d.ts +67 -0
- package/dist/cjs/anyspend/utils/validation.js +157 -0
- package/dist/cjs/global-account/react/components/B3DynamicModal.js +2 -0
- package/dist/cjs/global-account/react/components/B3Provider/B3Provider.d.ts +4 -2
- package/dist/cjs/global-account/react/components/B3Provider/B3Provider.js +4 -3
- package/dist/cjs/global-account/react/components/B3Provider/types.d.ts +1 -0
- package/dist/cjs/global-account/react/components/B3Provider/types.js +1 -0
- package/dist/cjs/global-account/react/hooks/useAuthentication.d.ts +1 -1
- package/dist/cjs/global-account/react/hooks/useUserQuery.d.ts +1 -1
- package/dist/cjs/global-account/react/stores/useModalStore.d.ts +27 -1
- package/dist/esm/anyspend/index.d.ts +1 -0
- package/dist/esm/anyspend/index.js +1 -0
- package/dist/esm/anyspend/react/components/AnySpendCollectorClubPurchase.d.ts +57 -0
- package/dist/esm/anyspend/react/components/AnySpendCollectorClubPurchase.js +79 -0
- package/dist/esm/anyspend/react/components/AnySpendCustom.js +3 -1
- package/dist/esm/anyspend/react/components/index.d.ts +1 -0
- package/dist/esm/anyspend/react/components/index.js +1 -0
- package/dist/esm/anyspend/react/hooks/useAnyspendCreateOnrampOrder.js +4 -0
- package/dist/esm/anyspend/react/hooks/useAnyspendCreateOrder.js +4 -0
- package/dist/esm/anyspend/react/hooks/useAnyspendOrderHistory.d.ts +16 -0
- package/dist/esm/anyspend/react/hooks/useSigMint.d.ts +1 -1
- package/dist/esm/anyspend/react/hooks/useValidatedClientReferenceId.d.ts +5 -0
- package/dist/esm/anyspend/react/hooks/useValidatedClientReferenceId.js +32 -0
- package/dist/esm/anyspend/services/anyspend.d.ts +2 -1
- package/dist/esm/anyspend/services/anyspend.js +2 -1
- package/dist/esm/anyspend/types/api.d.ts +295 -0
- package/dist/esm/anyspend/utils/validation.d.ts +67 -0
- package/dist/esm/anyspend/utils/validation.js +153 -0
- package/dist/esm/global-account/react/components/B3DynamicModal.js +3 -1
- package/dist/esm/global-account/react/components/B3Provider/B3Provider.d.ts +4 -2
- package/dist/esm/global-account/react/components/B3Provider/B3Provider.js +4 -3
- package/dist/esm/global-account/react/components/B3Provider/types.d.ts +1 -0
- package/dist/esm/global-account/react/components/B3Provider/types.js +1 -0
- package/dist/esm/global-account/react/hooks/useAuthentication.d.ts +1 -1
- package/dist/esm/global-account/react/hooks/useUserQuery.d.ts +1 -1
- package/dist/esm/global-account/react/stores/useModalStore.d.ts +27 -1
- package/dist/types/anyspend/index.d.ts +1 -0
- package/dist/types/anyspend/react/components/AnySpendCollectorClubPurchase.d.ts +57 -0
- package/dist/types/anyspend/react/components/index.d.ts +1 -0
- package/dist/types/anyspend/react/hooks/useAnyspendOrderHistory.d.ts +16 -0
- package/dist/types/anyspend/react/hooks/useSigMint.d.ts +1 -1
- package/dist/types/anyspend/react/hooks/useValidatedClientReferenceId.d.ts +5 -0
- package/dist/types/anyspend/services/anyspend.d.ts +2 -1
- package/dist/types/anyspend/types/api.d.ts +295 -0
- package/dist/types/anyspend/utils/validation.d.ts +67 -0
- package/dist/types/global-account/react/components/B3Provider/B3Provider.d.ts +4 -2
- package/dist/types/global-account/react/components/B3Provider/types.d.ts +1 -0
- package/dist/types/global-account/react/hooks/useAuthentication.d.ts +1 -1
- package/dist/types/global-account/react/hooks/useUserQuery.d.ts +1 -1
- package/dist/types/global-account/react/stores/useModalStore.d.ts +27 -1
- package/package.json +1 -1
- package/src/anyspend/index.ts +1 -0
- package/src/anyspend/react/components/AnySpendCollectorClubPurchase.tsx +178 -0
- package/src/anyspend/react/components/AnySpendCustom.tsx +3 -1
- package/src/anyspend/react/components/index.ts +1 -0
- package/src/anyspend/react/hooks/useAnyspendCreateOnrampOrder.ts +5 -0
- package/src/anyspend/react/hooks/useAnyspendCreateOrder.ts +5 -0
- package/src/anyspend/react/hooks/useValidatedClientReferenceId.ts +40 -0
- package/src/anyspend/services/anyspend.ts +3 -0
- package/src/anyspend/types/api.ts +295 -0
- package/src/anyspend/utils/validation.ts +209 -0
- package/src/global-account/react/components/B3DynamicModal.tsx +3 -0
- package/src/global-account/react/components/B3Provider/B3Provider.tsx +6 -0
- package/src/global-account/react/components/B3Provider/types.ts +2 -0
- package/src/global-account/react/stores/useModalStore.ts +29 -1
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
export interface ValidationResult {
|
|
2
|
+
isValid: boolean;
|
|
3
|
+
error?: string;
|
|
4
|
+
cleaned?: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface StringValidationOptions {
|
|
8
|
+
// Required/Optional
|
|
9
|
+
required?: boolean;
|
|
10
|
+
defaultValue?: () => string; // Generator for default (e.g., UUID)
|
|
11
|
+
|
|
12
|
+
// Length constraints
|
|
13
|
+
minLength?: number;
|
|
14
|
+
maxLength?: number;
|
|
15
|
+
|
|
16
|
+
// Character constraints
|
|
17
|
+
pattern?: RegExp;
|
|
18
|
+
patternErrorMessage?: string;
|
|
19
|
+
|
|
20
|
+
// Pre-processing
|
|
21
|
+
trim?: boolean; // Default: true
|
|
22
|
+
toLowerCase?: boolean;
|
|
23
|
+
toUpperCase?: boolean;
|
|
24
|
+
|
|
25
|
+
// Custom validation
|
|
26
|
+
customValidator?: (value: string) => { valid: boolean; error?: string };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Generic string validator with configurable rules
|
|
31
|
+
*/
|
|
32
|
+
export function validateString(value: string | undefined, options: StringValidationOptions): ValidationResult {
|
|
33
|
+
const {
|
|
34
|
+
required = false,
|
|
35
|
+
defaultValue,
|
|
36
|
+
minLength,
|
|
37
|
+
maxLength,
|
|
38
|
+
pattern,
|
|
39
|
+
patternErrorMessage,
|
|
40
|
+
trim = true,
|
|
41
|
+
toLowerCase = false,
|
|
42
|
+
toUpperCase = false,
|
|
43
|
+
customValidator,
|
|
44
|
+
} = options;
|
|
45
|
+
|
|
46
|
+
// Handle empty/undefined
|
|
47
|
+
if (!value || (trim && value.trim() === "")) {
|
|
48
|
+
if (required && !defaultValue) {
|
|
49
|
+
return { isValid: false, error: "This field is required" };
|
|
50
|
+
}
|
|
51
|
+
if (defaultValue) {
|
|
52
|
+
return { isValid: true, cleaned: defaultValue() };
|
|
53
|
+
}
|
|
54
|
+
return { isValid: true, cleaned: undefined };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Pre-processing
|
|
58
|
+
let cleaned = value;
|
|
59
|
+
if (trim) cleaned = cleaned.trim();
|
|
60
|
+
if (toLowerCase) cleaned = cleaned.toLowerCase();
|
|
61
|
+
if (toUpperCase) cleaned = cleaned.toUpperCase();
|
|
62
|
+
|
|
63
|
+
// Length validation
|
|
64
|
+
if (minLength !== undefined && cleaned.length < minLength) {
|
|
65
|
+
return {
|
|
66
|
+
isValid: false,
|
|
67
|
+
error: `Minimum length is ${minLength} characters`,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (maxLength !== undefined && cleaned.length > maxLength) {
|
|
72
|
+
return {
|
|
73
|
+
isValid: false,
|
|
74
|
+
error: `Maximum length is ${maxLength} characters`,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Pattern validation
|
|
79
|
+
if (pattern && !pattern.test(cleaned)) {
|
|
80
|
+
return {
|
|
81
|
+
isValid: false,
|
|
82
|
+
error: patternErrorMessage || "Invalid format",
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Custom validation
|
|
87
|
+
if (customValidator) {
|
|
88
|
+
const customResult = customValidator(cleaned);
|
|
89
|
+
if (!customResult.valid) {
|
|
90
|
+
return { isValid: false, error: customResult.error };
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return { isValid: true, cleaned };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Common validation patterns
|
|
99
|
+
*/
|
|
100
|
+
export const ValidationPatterns = {
|
|
101
|
+
ALPHANUMERIC: /^[a-zA-Z0-9]+$/,
|
|
102
|
+
ALPHANUMERIC_WITH_DASH_UNDERSCORE: /^[a-zA-Z0-9_-]+$/,
|
|
103
|
+
ALPHANUMERIC_WITH_SAFE_CHARS: /^[a-zA-Z0-9_.\-]+$/,
|
|
104
|
+
SAFE_IDENTIFIER: /^[a-zA-Z0-9_.\-]+$/, // For IDs, references
|
|
105
|
+
NO_CONTROL_CHARS: /^[^\x00-\x1F\x7F]+$/,
|
|
106
|
+
URL_SAFE: /^[a-zA-Z0-9_.\-~]+$/,
|
|
107
|
+
NUMERIC: /^\d+$/,
|
|
108
|
+
HEX: /^[0-9a-fA-F]+$/,
|
|
109
|
+
} as const;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Pre-configured validators for common use cases
|
|
113
|
+
*/
|
|
114
|
+
export const Validators = {
|
|
115
|
+
/**
|
|
116
|
+
* Validates client reference IDs (alphanumeric + safe chars)
|
|
117
|
+
* Returns undefined if not provided
|
|
118
|
+
*/
|
|
119
|
+
clientReferenceId: (value?: string) =>
|
|
120
|
+
validateString(value, {
|
|
121
|
+
required: false,
|
|
122
|
+
maxLength: 255,
|
|
123
|
+
pattern: ValidationPatterns.SAFE_IDENTIFIER,
|
|
124
|
+
patternErrorMessage: "Only letters, numbers, hyphens, underscores, and dots allowed",
|
|
125
|
+
trim: true,
|
|
126
|
+
customValidator: val => {
|
|
127
|
+
// Additional security checks
|
|
128
|
+
const dangerous = /('|"|;|--|\/\*|\*\/|<|>|script)/i;
|
|
129
|
+
if (dangerous.test(val)) {
|
|
130
|
+
return {
|
|
131
|
+
valid: false,
|
|
132
|
+
error: "Contains potentially dangerous characters",
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
return { valid: true };
|
|
136
|
+
},
|
|
137
|
+
}),
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Validates alphanumeric strings (letters and numbers only)
|
|
141
|
+
*/
|
|
142
|
+
alphanumeric: (value?: string, required = false) =>
|
|
143
|
+
validateString(value, {
|
|
144
|
+
required,
|
|
145
|
+
pattern: ValidationPatterns.ALPHANUMERIC,
|
|
146
|
+
patternErrorMessage: "Only letters and numbers allowed",
|
|
147
|
+
trim: true,
|
|
148
|
+
}),
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Validates wallet addresses (hex format)
|
|
152
|
+
*/
|
|
153
|
+
walletAddress: (value?: string, required = true) =>
|
|
154
|
+
validateString(value, {
|
|
155
|
+
required,
|
|
156
|
+
minLength: 42,
|
|
157
|
+
maxLength: 42,
|
|
158
|
+
pattern: /^0x[a-fA-F0-9]{40}$/,
|
|
159
|
+
patternErrorMessage: "Invalid wallet address format",
|
|
160
|
+
trim: true,
|
|
161
|
+
toLowerCase: true,
|
|
162
|
+
}),
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Validates order IDs (UUID format)
|
|
166
|
+
*/
|
|
167
|
+
orderId: (value?: string) =>
|
|
168
|
+
validateString(value, {
|
|
169
|
+
required: false,
|
|
170
|
+
pattern: /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,
|
|
171
|
+
patternErrorMessage: "Invalid order ID format",
|
|
172
|
+
trim: true,
|
|
173
|
+
toLowerCase: true,
|
|
174
|
+
}),
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Validates URL-safe strings
|
|
178
|
+
*/
|
|
179
|
+
urlSafe: (value?: string, maxLength = 255) =>
|
|
180
|
+
validateString(value, {
|
|
181
|
+
maxLength,
|
|
182
|
+
pattern: ValidationPatterns.URL_SAFE,
|
|
183
|
+
patternErrorMessage: "Contains invalid URL characters",
|
|
184
|
+
trim: true,
|
|
185
|
+
}),
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Validates safe identifiers (no injection risks)
|
|
189
|
+
*/
|
|
190
|
+
safeIdentifier: (value?: string, required = false) =>
|
|
191
|
+
validateString(value, {
|
|
192
|
+
required,
|
|
193
|
+
maxLength: 255,
|
|
194
|
+
pattern: ValidationPatterns.SAFE_IDENTIFIER,
|
|
195
|
+
patternErrorMessage: "Invalid identifier format",
|
|
196
|
+
customValidator: val => {
|
|
197
|
+
// Additional security checks
|
|
198
|
+
const dangerous = /('|"|;|--|\/\*|\*\/|<|>|script)/i;
|
|
199
|
+
if (dangerous.test(val)) {
|
|
200
|
+
return {
|
|
201
|
+
valid: false,
|
|
202
|
+
error: "Contains potentially dangerous characters",
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
return { valid: true };
|
|
206
|
+
},
|
|
207
|
+
trim: true,
|
|
208
|
+
}),
|
|
209
|
+
};
|
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
AnySpend,
|
|
3
3
|
AnySpendBondKit,
|
|
4
4
|
AnySpendBuySpin,
|
|
5
|
+
AnySpendCollectorClubPurchase,
|
|
5
6
|
AnySpendNFT,
|
|
6
7
|
AnyspendSignatureMint,
|
|
7
8
|
AnySpendStakeB3,
|
|
@@ -143,6 +144,8 @@ export function B3DynamicModal() {
|
|
|
143
144
|
return <LinkAccount {...contentType} />;
|
|
144
145
|
case "anySpendDepositHype":
|
|
145
146
|
return <AnySpendDepositHype {...contentType} mode="modal" />;
|
|
147
|
+
case "anySpendCollectorClubPurchase":
|
|
148
|
+
return <AnySpendCollectorClubPurchase {...contentType} mode="modal" />;
|
|
146
149
|
case "avatarEditor":
|
|
147
150
|
return <AvatarEditor onSetAvatar={contentType.onSuccess} />;
|
|
148
151
|
case "profileEditor":
|
|
@@ -58,6 +58,7 @@ export function B3Provider({
|
|
|
58
58
|
onConnect,
|
|
59
59
|
connectors,
|
|
60
60
|
overrideDefaultConnectors = false,
|
|
61
|
+
createClientReferenceId,
|
|
61
62
|
}: {
|
|
62
63
|
theme: "light" | "dark";
|
|
63
64
|
children: React.ReactNode;
|
|
@@ -75,6 +76,7 @@ export function B3Provider({
|
|
|
75
76
|
onConnect?: (wallet: Wallet, b3Jwt: string) => void | Promise<void>;
|
|
76
77
|
connectors?: CreateConnectorFn[];
|
|
77
78
|
overrideDefaultConnectors?: boolean;
|
|
79
|
+
createClientReferenceId?: () => string;
|
|
78
80
|
}) {
|
|
79
81
|
// Initialize Google Analytics on mount
|
|
80
82
|
useEffect(() => {
|
|
@@ -100,6 +102,7 @@ export function B3Provider({
|
|
|
100
102
|
automaticallySetFirstEoa={!!automaticallySetFirstEoa}
|
|
101
103
|
clientType={clientType}
|
|
102
104
|
partnerId={partnerId}
|
|
105
|
+
createClientReferenceId={createClientReferenceId}
|
|
103
106
|
>
|
|
104
107
|
<RelayKitProviderWrapper simDuneApiKey={simDuneApiKey}>
|
|
105
108
|
{children}
|
|
@@ -128,6 +131,7 @@ export function InnerProvider({
|
|
|
128
131
|
theme = "light",
|
|
129
132
|
clientType = "socket",
|
|
130
133
|
partnerId,
|
|
134
|
+
createClientReferenceId,
|
|
131
135
|
}: {
|
|
132
136
|
children: React.ReactNode;
|
|
133
137
|
accountOverride?: Account;
|
|
@@ -137,6 +141,7 @@ export function InnerProvider({
|
|
|
137
141
|
theme: "light" | "dark";
|
|
138
142
|
clientType?: ClientType;
|
|
139
143
|
partnerId: string;
|
|
144
|
+
createClientReferenceId?: () => string;
|
|
140
145
|
}) {
|
|
141
146
|
const activeAccount = useActiveAccount();
|
|
142
147
|
const [manuallySelectedWallet, setManuallySelectedWallet] = useState<Wallet | undefined>(undefined);
|
|
@@ -204,6 +209,7 @@ export function InnerProvider({
|
|
|
204
209
|
theme,
|
|
205
210
|
clientType,
|
|
206
211
|
partnerId: partnerId,
|
|
212
|
+
createClientReferenceId,
|
|
207
213
|
}}
|
|
208
214
|
>
|
|
209
215
|
<InnerProvider2>{children}</InnerProvider2>
|
|
@@ -22,6 +22,7 @@ export interface B3ContextType {
|
|
|
22
22
|
theme: "light" | "dark";
|
|
23
23
|
clientType: ClientType;
|
|
24
24
|
partnerId: string;
|
|
25
|
+
createClientReferenceId?: () => string;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
/**
|
|
@@ -41,4 +42,5 @@ export const B3Context = createContext<B3ContextType>({
|
|
|
41
42
|
theme: "light",
|
|
42
43
|
clientType: "rest",
|
|
43
44
|
partnerId: "",
|
|
45
|
+
createClientReferenceId: undefined,
|
|
44
46
|
});
|
|
@@ -128,6 +128,8 @@ export interface AnySpendModalProps extends BaseModalProps {
|
|
|
128
128
|
destinationTokenChainId?: number;
|
|
129
129
|
/** Custom USD input values for quick amount buttons in fiat onramp */
|
|
130
130
|
customUsdInputValues?: string[];
|
|
131
|
+
/** Client-provided reference ID for tracking orders */
|
|
132
|
+
clientReferenceId?: string;
|
|
131
133
|
}
|
|
132
134
|
|
|
133
135
|
/**
|
|
@@ -143,6 +145,8 @@ export interface AnySpendNftProps extends BaseModalProps {
|
|
|
143
145
|
recipientAddress?: string;
|
|
144
146
|
/** Callback function called when the NFT is successfully transferred */
|
|
145
147
|
onSuccess?: (txHash?: string) => void;
|
|
148
|
+
/** Client-provided reference ID for tracking orders */
|
|
149
|
+
clientReferenceId?: string;
|
|
146
150
|
}
|
|
147
151
|
|
|
148
152
|
/**
|
|
@@ -401,6 +405,29 @@ export interface ProfileEditorModalProps extends BaseModalProps {
|
|
|
401
405
|
onSuccess?: () => void;
|
|
402
406
|
}
|
|
403
407
|
|
|
408
|
+
/**
|
|
409
|
+
* Props for the AnySpend Collector Club Purchase modal
|
|
410
|
+
* Handles Collector Club pack purchases
|
|
411
|
+
*/
|
|
412
|
+
export interface AnySpendCollectorClubPurchaseProps extends BaseModalProps {
|
|
413
|
+
/** Modal type identifier */
|
|
414
|
+
type: "anySpendCollectorClubPurchase";
|
|
415
|
+
/** The pack ID to purchase */
|
|
416
|
+
packId: number;
|
|
417
|
+
/** The number of packs to purchase */
|
|
418
|
+
packAmount: number;
|
|
419
|
+
/** Price per pack in wei (e.g., "10000" for 0.01 USDC with 6 decimals) */
|
|
420
|
+
pricePerPack: string;
|
|
421
|
+
/** Recipient address to receive the packs */
|
|
422
|
+
recipientAddress: string;
|
|
423
|
+
/** Payment type - crypto or fiat */
|
|
424
|
+
paymentType?: "crypto" | "fiat";
|
|
425
|
+
/** Callback function called when the purchase is successful */
|
|
426
|
+
onSuccess?: (txHash?: string) => void;
|
|
427
|
+
/** Client-provided reference ID for tracking orders */
|
|
428
|
+
clientReferenceId?: string;
|
|
429
|
+
}
|
|
430
|
+
|
|
404
431
|
/**
|
|
405
432
|
* Union type of all possible modal content types
|
|
406
433
|
*/
|
|
@@ -425,7 +452,8 @@ export type ModalContentType =
|
|
|
425
452
|
| LinkAccountModalProps
|
|
426
453
|
| AnySpendDepositHypeProps
|
|
427
454
|
| AvatarEditorModalProps
|
|
428
|
-
| ProfileEditorModalProps
|
|
455
|
+
| ProfileEditorModalProps
|
|
456
|
+
| AnySpendCollectorClubPurchaseProps;
|
|
429
457
|
// Add other modal types here like: | OtherModalProps | AnotherModalProps
|
|
430
458
|
|
|
431
459
|
/**
|