@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.
Files changed (81) hide show
  1. package/dist/cjs/anyspend/index.d.ts +1 -0
  2. package/dist/cjs/anyspend/index.js +1 -0
  3. package/dist/cjs/anyspend/react/components/AnySpendCollectorClubPurchase.d.ts +57 -0
  4. package/dist/cjs/anyspend/react/components/AnySpendCollectorClubPurchase.js +82 -0
  5. package/dist/cjs/anyspend/react/components/AnySpendCustom.js +3 -1
  6. package/dist/cjs/anyspend/react/components/index.d.ts +1 -0
  7. package/dist/cjs/anyspend/react/components/index.js +3 -1
  8. package/dist/cjs/anyspend/react/hooks/useAnyspendCreateOnrampOrder.js +4 -0
  9. package/dist/cjs/anyspend/react/hooks/useAnyspendCreateOrder.js +4 -0
  10. package/dist/cjs/anyspend/react/hooks/useAnyspendOrderHistory.d.ts +16 -0
  11. package/dist/cjs/anyspend/react/hooks/useSigMint.d.ts +1 -1
  12. package/dist/cjs/anyspend/react/hooks/useValidatedClientReferenceId.d.ts +5 -0
  13. package/dist/cjs/anyspend/react/hooks/useValidatedClientReferenceId.js +35 -0
  14. package/dist/cjs/anyspend/services/anyspend.d.ts +2 -1
  15. package/dist/cjs/anyspend/services/anyspend.js +2 -1
  16. package/dist/cjs/anyspend/types/api.d.ts +295 -0
  17. package/dist/cjs/anyspend/utils/validation.d.ts +67 -0
  18. package/dist/cjs/anyspend/utils/validation.js +157 -0
  19. package/dist/cjs/global-account/react/components/B3DynamicModal.js +2 -0
  20. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.d.ts +4 -2
  21. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.js +4 -3
  22. package/dist/cjs/global-account/react/components/B3Provider/types.d.ts +1 -0
  23. package/dist/cjs/global-account/react/components/B3Provider/types.js +1 -0
  24. package/dist/cjs/global-account/react/hooks/useAuthentication.d.ts +1 -1
  25. package/dist/cjs/global-account/react/hooks/useUserQuery.d.ts +1 -1
  26. package/dist/cjs/global-account/react/stores/useModalStore.d.ts +27 -1
  27. package/dist/esm/anyspend/index.d.ts +1 -0
  28. package/dist/esm/anyspend/index.js +1 -0
  29. package/dist/esm/anyspend/react/components/AnySpendCollectorClubPurchase.d.ts +57 -0
  30. package/dist/esm/anyspend/react/components/AnySpendCollectorClubPurchase.js +79 -0
  31. package/dist/esm/anyspend/react/components/AnySpendCustom.js +3 -1
  32. package/dist/esm/anyspend/react/components/index.d.ts +1 -0
  33. package/dist/esm/anyspend/react/components/index.js +1 -0
  34. package/dist/esm/anyspend/react/hooks/useAnyspendCreateOnrampOrder.js +4 -0
  35. package/dist/esm/anyspend/react/hooks/useAnyspendCreateOrder.js +4 -0
  36. package/dist/esm/anyspend/react/hooks/useAnyspendOrderHistory.d.ts +16 -0
  37. package/dist/esm/anyspend/react/hooks/useSigMint.d.ts +1 -1
  38. package/dist/esm/anyspend/react/hooks/useValidatedClientReferenceId.d.ts +5 -0
  39. package/dist/esm/anyspend/react/hooks/useValidatedClientReferenceId.js +32 -0
  40. package/dist/esm/anyspend/services/anyspend.d.ts +2 -1
  41. package/dist/esm/anyspend/services/anyspend.js +2 -1
  42. package/dist/esm/anyspend/types/api.d.ts +295 -0
  43. package/dist/esm/anyspend/utils/validation.d.ts +67 -0
  44. package/dist/esm/anyspend/utils/validation.js +153 -0
  45. package/dist/esm/global-account/react/components/B3DynamicModal.js +3 -1
  46. package/dist/esm/global-account/react/components/B3Provider/B3Provider.d.ts +4 -2
  47. package/dist/esm/global-account/react/components/B3Provider/B3Provider.js +4 -3
  48. package/dist/esm/global-account/react/components/B3Provider/types.d.ts +1 -0
  49. package/dist/esm/global-account/react/components/B3Provider/types.js +1 -0
  50. package/dist/esm/global-account/react/hooks/useAuthentication.d.ts +1 -1
  51. package/dist/esm/global-account/react/hooks/useUserQuery.d.ts +1 -1
  52. package/dist/esm/global-account/react/stores/useModalStore.d.ts +27 -1
  53. package/dist/types/anyspend/index.d.ts +1 -0
  54. package/dist/types/anyspend/react/components/AnySpendCollectorClubPurchase.d.ts +57 -0
  55. package/dist/types/anyspend/react/components/index.d.ts +1 -0
  56. package/dist/types/anyspend/react/hooks/useAnyspendOrderHistory.d.ts +16 -0
  57. package/dist/types/anyspend/react/hooks/useSigMint.d.ts +1 -1
  58. package/dist/types/anyspend/react/hooks/useValidatedClientReferenceId.d.ts +5 -0
  59. package/dist/types/anyspend/services/anyspend.d.ts +2 -1
  60. package/dist/types/anyspend/types/api.d.ts +295 -0
  61. package/dist/types/anyspend/utils/validation.d.ts +67 -0
  62. package/dist/types/global-account/react/components/B3Provider/B3Provider.d.ts +4 -2
  63. package/dist/types/global-account/react/components/B3Provider/types.d.ts +1 -0
  64. package/dist/types/global-account/react/hooks/useAuthentication.d.ts +1 -1
  65. package/dist/types/global-account/react/hooks/useUserQuery.d.ts +1 -1
  66. package/dist/types/global-account/react/stores/useModalStore.d.ts +27 -1
  67. package/package.json +1 -1
  68. package/src/anyspend/index.ts +1 -0
  69. package/src/anyspend/react/components/AnySpendCollectorClubPurchase.tsx +178 -0
  70. package/src/anyspend/react/components/AnySpendCustom.tsx +3 -1
  71. package/src/anyspend/react/components/index.ts +1 -0
  72. package/src/anyspend/react/hooks/useAnyspendCreateOnrampOrder.ts +5 -0
  73. package/src/anyspend/react/hooks/useAnyspendCreateOrder.ts +5 -0
  74. package/src/anyspend/react/hooks/useValidatedClientReferenceId.ts +40 -0
  75. package/src/anyspend/services/anyspend.ts +3 -0
  76. package/src/anyspend/types/api.ts +295 -0
  77. package/src/anyspend/utils/validation.ts +209 -0
  78. package/src/global-account/react/components/B3DynamicModal.tsx +3 -0
  79. package/src/global-account/react/components/B3Provider/B3Provider.tsx +6 -0
  80. package/src/global-account/react/components/B3Provider/types.ts +2 -0
  81. package/src/global-account/react/stores/useModalStore.ts +29 -1
@@ -0,0 +1,67 @@
1
+ export interface ValidationResult {
2
+ isValid: boolean;
3
+ error?: string;
4
+ cleaned?: string;
5
+ }
6
+ export interface StringValidationOptions {
7
+ required?: boolean;
8
+ defaultValue?: () => string;
9
+ minLength?: number;
10
+ maxLength?: number;
11
+ pattern?: RegExp;
12
+ patternErrorMessage?: string;
13
+ trim?: boolean;
14
+ toLowerCase?: boolean;
15
+ toUpperCase?: boolean;
16
+ customValidator?: (value: string) => {
17
+ valid: boolean;
18
+ error?: string;
19
+ };
20
+ }
21
+ /**
22
+ * Generic string validator with configurable rules
23
+ */
24
+ export declare function validateString(value: string | undefined, options: StringValidationOptions): ValidationResult;
25
+ /**
26
+ * Common validation patterns
27
+ */
28
+ export declare const ValidationPatterns: {
29
+ readonly ALPHANUMERIC: RegExp;
30
+ readonly ALPHANUMERIC_WITH_DASH_UNDERSCORE: RegExp;
31
+ readonly ALPHANUMERIC_WITH_SAFE_CHARS: RegExp;
32
+ readonly SAFE_IDENTIFIER: RegExp;
33
+ readonly NO_CONTROL_CHARS: RegExp;
34
+ readonly URL_SAFE: RegExp;
35
+ readonly NUMERIC: RegExp;
36
+ readonly HEX: RegExp;
37
+ };
38
+ /**
39
+ * Pre-configured validators for common use cases
40
+ */
41
+ export declare const Validators: {
42
+ /**
43
+ * Validates client reference IDs (alphanumeric + safe chars)
44
+ * Returns undefined if not provided
45
+ */
46
+ clientReferenceId: (value?: string) => ValidationResult;
47
+ /**
48
+ * Validates alphanumeric strings (letters and numbers only)
49
+ */
50
+ alphanumeric: (value?: string, required?: boolean) => ValidationResult;
51
+ /**
52
+ * Validates wallet addresses (hex format)
53
+ */
54
+ walletAddress: (value?: string, required?: boolean) => ValidationResult;
55
+ /**
56
+ * Validates order IDs (UUID format)
57
+ */
58
+ orderId: (value?: string) => ValidationResult;
59
+ /**
60
+ * Validates URL-safe strings
61
+ */
62
+ urlSafe: (value?: string, maxLength?: number) => ValidationResult;
63
+ /**
64
+ * Validates safe identifiers (no injection risks)
65
+ */
66
+ safeIdentifier: (value?: string, required?: boolean) => ValidationResult;
67
+ };
@@ -7,7 +7,7 @@ import { B3ContextType } from "./types";
7
7
  /**
8
8
  * Main B3Provider component
9
9
  */
10
- export declare function B3Provider({ theme, children, accountOverride, environment, automaticallySetFirstEoa, simDuneApiKey, toaster, clientType, rpcUrls, partnerId, onConnect, connectors, overrideDefaultConnectors, }: {
10
+ export declare function B3Provider({ theme, children, accountOverride, environment, automaticallySetFirstEoa, simDuneApiKey, toaster, clientType, rpcUrls, partnerId, onConnect, connectors, overrideDefaultConnectors, createClientReferenceId, }: {
11
11
  theme: "light" | "dark";
12
12
  children: React.ReactNode;
13
13
  accountOverride?: Account;
@@ -24,11 +24,12 @@ export declare function B3Provider({ theme, children, accountOverride, environme
24
24
  onConnect?: (wallet: Wallet, b3Jwt: string) => void | Promise<void>;
25
25
  connectors?: CreateConnectorFn[];
26
26
  overrideDefaultConnectors?: boolean;
27
+ createClientReferenceId?: () => string;
27
28
  }): import("react/jsx-runtime").JSX.Element;
28
29
  /**
29
30
  * Inner provider component that provides the actual B3Context
30
31
  */
31
- export declare function InnerProvider({ children, accountOverride, environment, defaultPermissions, automaticallySetFirstEoa, theme, clientType, partnerId, }: {
32
+ export declare function InnerProvider({ children, accountOverride, environment, defaultPermissions, automaticallySetFirstEoa, theme, clientType, partnerId, createClientReferenceId, }: {
32
33
  children: React.ReactNode;
33
34
  accountOverride?: Account;
34
35
  environment: B3ContextType["environment"];
@@ -37,4 +38,5 @@ export declare function InnerProvider({ children, accountOverride, environment,
37
38
  theme: "light" | "dark";
38
39
  clientType?: ClientType;
39
40
  partnerId: string;
41
+ createClientReferenceId?: () => string;
40
42
  }): import("react/jsx-runtime").JSX.Element;
@@ -20,6 +20,7 @@ export interface B3ContextType {
20
20
  theme: "light" | "dark";
21
21
  clientType: ClientType;
22
22
  partnerId: string;
23
+ createClientReferenceId?: () => string;
23
24
  }
24
25
  /**
25
26
  * Context for B3 provider
@@ -13,8 +13,8 @@ export declare function useAuthentication(partnerId: string): {
13
13
  onConnect: (_walleAutoConnectedWith: Wallet, allConnectedWallets: Wallet[]) => Promise<void>;
14
14
  user: {
15
15
  email?: string | undefined;
16
- username?: string | undefined;
17
16
  telNumber?: string | undefined;
17
+ username?: string | undefined;
18
18
  ens?: string | undefined;
19
19
  avatar?: string | undefined;
20
20
  preferences?: {} | undefined;
@@ -8,8 +8,8 @@ import { Users } from "@b3dotfun/b3-api";
8
8
  export declare function useUserQuery(): {
9
9
  user: {
10
10
  email?: string | undefined;
11
- username?: string | undefined;
12
11
  telNumber?: string | undefined;
12
+ username?: string | undefined;
13
13
  ens?: string | undefined;
14
14
  avatar?: string | undefined;
15
15
  preferences?: {} | undefined;
@@ -122,6 +122,8 @@ export interface AnySpendModalProps extends BaseModalProps {
122
122
  destinationTokenChainId?: number;
123
123
  /** Custom USD input values for quick amount buttons in fiat onramp */
124
124
  customUsdInputValues?: string[];
125
+ /** Client-provided reference ID for tracking orders */
126
+ clientReferenceId?: string;
125
127
  }
126
128
  /**
127
129
  * Props for the AnySpend NFT modal
@@ -136,6 +138,8 @@ export interface AnySpendNftProps extends BaseModalProps {
136
138
  recipientAddress?: string;
137
139
  /** Callback function called when the NFT is successfully transferred */
138
140
  onSuccess?: (txHash?: string) => void;
141
+ /** Client-provided reference ID for tracking orders */
142
+ clientReferenceId?: string;
139
143
  }
140
144
  /**
141
145
  * Props for the AnySpend tournament modal
@@ -377,10 +381,32 @@ export interface ProfileEditorModalProps extends BaseModalProps {
377
381
  /** Callback function called when profile is successfully updated */
378
382
  onSuccess?: () => void;
379
383
  }
384
+ /**
385
+ * Props for the AnySpend Collector Club Purchase modal
386
+ * Handles Collector Club pack purchases
387
+ */
388
+ export interface AnySpendCollectorClubPurchaseProps extends BaseModalProps {
389
+ /** Modal type identifier */
390
+ type: "anySpendCollectorClubPurchase";
391
+ /** The pack ID to purchase */
392
+ packId: number;
393
+ /** The number of packs to purchase */
394
+ packAmount: number;
395
+ /** Price per pack in wei (e.g., "10000" for 0.01 USDC with 6 decimals) */
396
+ pricePerPack: string;
397
+ /** Recipient address to receive the packs */
398
+ recipientAddress: string;
399
+ /** Payment type - crypto or fiat */
400
+ paymentType?: "crypto" | "fiat";
401
+ /** Callback function called when the purchase is successful */
402
+ onSuccess?: (txHash?: string) => void;
403
+ /** Client-provided reference ID for tracking orders */
404
+ clientReferenceId?: string;
405
+ }
380
406
  /**
381
407
  * Union type of all possible modal content types
382
408
  */
383
- export type ModalContentType = SignInWithB3ModalProps | RequestPermissionsModalProps | ManageAccountModalProps | AnySpendModalProps | AnyspendOrderDetailsProps | AnySpendNftProps | AnySpendJoinTournamentProps | AnySpendFundTournamentProps | AnySpendOrderHistoryProps | AnySpendStakeB3Props | AnySpendStakeB3ExactInProps | AnySpendStakeUpsideProps | AnySpendStakeUpsideExactInProps | AnySpendDepositUpsideProps | AnySpendBuySpinProps | AnySpendSignatureMintProps | AnySpendBondKitProps | LinkAccountModalProps | AnySpendDepositHypeProps | AvatarEditorModalProps | ProfileEditorModalProps;
409
+ export type ModalContentType = SignInWithB3ModalProps | RequestPermissionsModalProps | ManageAccountModalProps | AnySpendModalProps | AnyspendOrderDetailsProps | AnySpendNftProps | AnySpendJoinTournamentProps | AnySpendFundTournamentProps | AnySpendOrderHistoryProps | AnySpendStakeB3Props | AnySpendStakeB3ExactInProps | AnySpendStakeUpsideProps | AnySpendStakeUpsideExactInProps | AnySpendDepositUpsideProps | AnySpendBuySpinProps | AnySpendSignatureMintProps | AnySpendBondKitProps | LinkAccountModalProps | AnySpendDepositHypeProps | AvatarEditorModalProps | ProfileEditorModalProps | AnySpendCollectorClubPurchaseProps;
384
410
  /**
385
411
  * State interface for the modal store
386
412
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@b3dotfun/sdk",
3
- "version": "0.0.70-alpha.0",
3
+ "version": "0.0.70-alpha.2",
4
4
  "source": "src/index.ts",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "react-native": "./dist/cjs/index.native.js",
@@ -9,6 +9,7 @@ export * from "./utils/json";
9
9
  export * from "./utils/number";
10
10
  export * from "./utils/string";
11
11
  export * from "./utils/token";
12
+ export * from "./utils/validation";
12
13
 
13
14
  // Constants
14
15
  export * from "./constants";
@@ -0,0 +1,178 @@
1
+ /**
2
+ * AnySpend component for Collector Club pack purchases
3
+ *
4
+ * This component enables users to purchase Collector Club packs using any token via AnySpend.
5
+ * It calls the `buyPacksFor` function on the Collector Club Shop contract on Base.
6
+ * Uses exact-out flow to ensure the contract receives exactly the required USDC amount.
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * import { AnySpendCollectorClubPurchase } from "@b3dotfun/sdk";
11
+ * import { USDC_BASE } from "@b3dotfun/sdk/anyspend/constants";
12
+ *
13
+ * function MyComponent() {
14
+ * return (
15
+ * <AnySpendCollectorClubPurchase
16
+ * packId={1}
17
+ * packAmount={5}
18
+ * pricePerPack="10000" // 0.01 USDC in wei (6 decimals)
19
+ * paymentToken={USDC_BASE}
20
+ * recipientAddress="0x123..."
21
+ * onSuccess={(txHash) => console.log("Purchase successful!", txHash)}
22
+ * />
23
+ * );
24
+ * }
25
+ * ```
26
+ */
27
+ import { USDC_BASE } from "@b3dotfun/sdk/anyspend/constants";
28
+ import { components } from "@b3dotfun/sdk/anyspend/types/api";
29
+ import { GetQuoteResponse } from "@b3dotfun/sdk/anyspend/types/api_req_res";
30
+ import React, { useMemo } from "react";
31
+ import { encodeFunctionData } from "viem";
32
+ import { AnySpendCustom } from "./AnySpendCustom";
33
+
34
+ // Collector Club Shop contract on Base
35
+ const CC_SHOP_ADDRESS = "0x68B32D594E3c7E5B8cd8046BD66AfB0DB5b9BF9c";
36
+ const BASE_CHAIN_ID = 8453;
37
+
38
+ // ABI for buyPacksFor function only
39
+ const BUY_PACKS_FOR_ABI = {
40
+ inputs: [
41
+ { internalType: "address", name: "user", type: "address" },
42
+ { internalType: "uint256", name: "packId", type: "uint256" },
43
+ { internalType: "uint256", name: "amount", type: "uint256" },
44
+ ],
45
+ name: "buyPacksFor",
46
+ outputs: [],
47
+ stateMutability: "nonpayable",
48
+ type: "function",
49
+ } as const;
50
+
51
+ export interface AnySpendCollectorClubPurchaseProps {
52
+ /**
53
+ * Optional order ID to load existing order
54
+ */
55
+ loadOrder?: string;
56
+ /**
57
+ * Display mode
58
+ */
59
+ mode?: "modal" | "page";
60
+ /**
61
+ * Active tab (crypto or fiat payment)
62
+ */
63
+ activeTab?: "crypto" | "fiat";
64
+ /**
65
+ * The pack ID to purchase
66
+ */
67
+ packId: number;
68
+ /**
69
+ * The number of packs to purchase
70
+ */
71
+ packAmount: number;
72
+ /**
73
+ * Price per pack in wei (e.g., "10000" for 0.01 USDC with 6 decimals)
74
+ */
75
+ pricePerPack: string;
76
+ /**
77
+ * The payment token (defaults to USDC on Base)
78
+ */
79
+ paymentToken?: components["schemas"]["Token"];
80
+ /**
81
+ * Address that will receive the packs
82
+ */
83
+ recipientAddress: string;
84
+ /**
85
+ * Optional spender address (defaults to contract address)
86
+ */
87
+ spenderAddress?: string;
88
+ /**
89
+ * Success callback
90
+ */
91
+ onSuccess?: (txHash?: string) => void;
92
+ /**
93
+ * Optional custom header component
94
+ */
95
+ header?: (props: {
96
+ anyspendPrice: GetQuoteResponse | undefined;
97
+ isLoadingAnyspendPrice: boolean;
98
+ }) => React.JSX.Element;
99
+ /**
100
+ * Show recipient selection (default: true)
101
+ */
102
+ showRecipient?: boolean;
103
+ }
104
+
105
+ export function AnySpendCollectorClubPurchase({
106
+ loadOrder,
107
+ mode = "modal",
108
+ activeTab = "crypto",
109
+ packId,
110
+ packAmount,
111
+ pricePerPack,
112
+ paymentToken = USDC_BASE,
113
+ recipientAddress,
114
+ spenderAddress = CC_SHOP_ADDRESS,
115
+ onSuccess,
116
+ header,
117
+ showRecipient = true,
118
+ }: AnySpendCollectorClubPurchaseProps) {
119
+ // Calculate total amount needed (pricePerPack * packAmount)
120
+ const totalAmount = useMemo(() => {
121
+ try {
122
+ return (BigInt(pricePerPack) * BigInt(packAmount)).toString();
123
+ } catch (error) {
124
+ console.error("Failed to calculate total amount from props", { pricePerPack, packAmount, error });
125
+ return "0";
126
+ }
127
+ }, [pricePerPack, packAmount]);
128
+
129
+ // Encode the buyPacksFor function call
130
+ const encodedData = useMemo(() => {
131
+ try {
132
+ return encodeFunctionData({
133
+ abi: [BUY_PACKS_FOR_ABI],
134
+ functionName: "buyPacksFor",
135
+ args: [recipientAddress as `0x${string}`, BigInt(packId), BigInt(packAmount)],
136
+ });
137
+ } catch (error) {
138
+ console.error("Failed to encode function data", { recipientAddress, packId, packAmount, error });
139
+ return "0x";
140
+ }
141
+ }, [recipientAddress, packId, packAmount]);
142
+
143
+ // Default header if not provided
144
+ const defaultHeader = () => (
145
+ <div className="mb-4 flex flex-col items-center gap-3 text-center">
146
+ <div>
147
+ <h1 className="text-as-primary text-xl font-bold">Buy Collector Club Packs</h1>
148
+ <p className="text-as-secondary text-sm">
149
+ Purchase {packAmount} pack{packAmount !== 1 ? "s" : ""} using any token
150
+ </p>
151
+ </div>
152
+ </div>
153
+ );
154
+
155
+ return (
156
+ <AnySpendCustom
157
+ loadOrder={loadOrder}
158
+ mode={mode}
159
+ activeTab={activeTab}
160
+ recipientAddress={recipientAddress}
161
+ spenderAddress={spenderAddress}
162
+ orderType="custom"
163
+ dstChainId={BASE_CHAIN_ID}
164
+ dstToken={paymentToken}
165
+ dstAmount={totalAmount}
166
+ contractAddress={CC_SHOP_ADDRESS}
167
+ encodedData={encodedData}
168
+ metadata={{
169
+ packId,
170
+ packAmount,
171
+ pricePerPack,
172
+ }}
173
+ header={header || defaultHeader}
174
+ onSuccess={onSuccess}
175
+ showRecipient={showRecipient}
176
+ />
177
+ );
178
+ }
@@ -534,7 +534,9 @@ function AnySpendCustomInner({
534
534
  expectedDstAmount: anyspendQuote?.data?.currencyOut?.amount?.toString() || "0",
535
535
  });
536
536
  } else {
537
- void createRegularOrder(createOrderParams);
537
+ void createRegularOrder({
538
+ ...createOrderParams,
539
+ });
538
540
  }
539
541
  } catch (err) {
540
542
  console.error(err);
@@ -2,6 +2,7 @@
2
2
  export { AnySpend } from "./AnySpend";
3
3
  export { AnySpendBondKit } from "./AnySpendBondKit";
4
4
  export { AnySpendBuySpin } from "./AnySpendBuySpin";
5
+ export { AnySpendCollectorClubPurchase } from "./AnySpendCollectorClubPurchase";
5
6
  export { AnySpendCustom } from "./AnySpendCustom";
6
7
  export { AnySpendCustomExactIn } from "./AnySpendCustomExactIn";
7
8
  export { AnySpendDepositHype, HYPE_TOKEN_DETAILS } from "./AnyspendDepositHype";
@@ -10,6 +10,7 @@ import { useMemo } from "react";
10
10
  import { parseUnits } from "viem";
11
11
  import { base } from "viem/chains";
12
12
  import { CreateOrderParams } from "./useAnyspendCreateOrder";
13
+ import { useValidatedClientReferenceId } from "./useValidatedClientReferenceId";
13
14
 
14
15
  export type OnrampOptions = {
15
16
  vendor: components["schemas"]["OnrampMetadata"]["vendor"];
@@ -33,6 +34,9 @@ export type UseAnyspendCreateOnrampOrderProps = {
33
34
  * Specifically handles orders that involve fiat-to-crypto onramp functionality
34
35
  */
35
36
  export function useAnyspendCreateOnrampOrder({ onSuccess, onError }: UseAnyspendCreateOnrampOrderProps = {}) {
37
+ // Get validated client reference ID from B3 context
38
+ const validatedClientReferenceId = useValidatedClientReferenceId();
39
+
36
40
  // Get fingerprint data
37
41
  const { data: fpData } = useVisitorData({ extendedResult: true }, { immediate: true });
38
42
  const visitorData: VisitorData | undefined = fpData && {
@@ -102,6 +106,7 @@ export function useAnyspendCreateOnrampOrder({ onSuccess, onError }: UseAnyspend
102
106
  }),
103
107
  creatorAddress: creatorAddress ? normalizeAddress(creatorAddress) : undefined,
104
108
  partnerId,
109
+ clientReferenceId: validatedClientReferenceId,
105
110
  visitorData,
106
111
  });
107
112
  } catch (error: any) {
@@ -5,6 +5,7 @@ import { buildMetadata, buildPayload, normalizeAddress } from "@b3dotfun/sdk/any
5
5
  import { useVisitorData } from "@fingerprintjs/fingerprintjs-pro-react";
6
6
  import { useMutation } from "@tanstack/react-query";
7
7
  import { useMemo } from "react";
8
+ import { useValidatedClientReferenceId } from "./useValidatedClientReferenceId";
8
9
 
9
10
  export type CreateOrderParams = {
10
11
  recipientAddress: string;
@@ -33,6 +34,9 @@ export type UseAnyspendCreateOrderProps = {
33
34
  * For onramp orders, use useAnyspendCreateOnrampOrder instead.
34
35
  */
35
36
  export function useAnyspendCreateOrder({ onSuccess, onError }: UseAnyspendCreateOrderProps = {}) {
37
+ // Get validated client reference ID from B3 context
38
+ const validatedClientReferenceId = useValidatedClientReferenceId();
39
+
36
40
  // Get fingerprint data
37
41
  const { data: fpData } = useVisitorData({ extendedResult: true }, { immediate: true });
38
42
  const visitorData: VisitorData | undefined = fpData && {
@@ -75,6 +79,7 @@ export function useAnyspendCreateOrder({ onSuccess, onError }: UseAnyspendCreate
75
79
  },
76
80
  }),
77
81
  creatorAddress: creatorAddress ? normalizeAddress(creatorAddress) : undefined,
82
+ clientReferenceId: validatedClientReferenceId,
78
83
  visitorData,
79
84
  });
80
85
  } catch (error: any) {
@@ -0,0 +1,40 @@
1
+ import { Validators } from "@b3dotfun/sdk/anyspend/utils/validation";
2
+ import { useB3 } from "@b3dotfun/sdk/global-account/react";
3
+ import { useMemo } from "react";
4
+
5
+ /**
6
+ * Hook that provides a validated client reference ID
7
+ * Gets the createClientReferenceId function from B3 context and validates the result
8
+ */
9
+ export function useValidatedClientReferenceId() {
10
+ const { createClientReferenceId } = useB3();
11
+
12
+ const validatedClientReferenceId = useMemo(() => {
13
+ // If no function provided, return undefined
14
+ if (!createClientReferenceId) {
15
+ return undefined;
16
+ }
17
+
18
+ try {
19
+ // Call the function to generate the ID
20
+ const generatedId = createClientReferenceId();
21
+
22
+ // Validate the generated ID
23
+ const validation = Validators.clientReferenceId(generatedId);
24
+
25
+ if (!validation.isValid) {
26
+ console.error(
27
+ `[AnySpend] Invalid clientReferenceId generated: ${validation.error || "Validation failed"}. Will be set to undefined.`,
28
+ );
29
+ return undefined;
30
+ }
31
+
32
+ return validation.cleaned;
33
+ } catch (error) {
34
+ console.error("[AnySpend] Error generating clientReferenceId:", error);
35
+ return undefined;
36
+ }
37
+ }, [createClientReferenceId]);
38
+
39
+ return validatedClientReferenceId;
40
+ }
@@ -67,6 +67,7 @@ export const anyspendService = {
67
67
  metadata,
68
68
  creatorAddress,
69
69
  partnerId,
70
+ clientReferenceId,
70
71
  visitorData,
71
72
  }: {
72
73
  recipientAddress: string;
@@ -81,6 +82,7 @@ export const anyspendService = {
81
82
  metadata: Record<string, any>;
82
83
  creatorAddress?: string;
83
84
  partnerId?: string;
85
+ clientReferenceId?: string;
84
86
  visitorData?: VisitorData;
85
87
  }) => {
86
88
  const response = await fetch(`${ANYSPEND_MAINNET_BASE_URL}/orders`, {
@@ -103,6 +105,7 @@ export const anyspendService = {
103
105
  metadata,
104
106
  creatorAddress,
105
107
  partnerId,
108
+ ...(clientReferenceId && { clientReferenceId }),
106
109
  }),
107
110
  });
108
111
  const data: CreateOrderResponse = await response.json();