@b3dotfun/sdk 0.0.68-alpha.0 → 0.0.69-test.0

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.
@@ -0,0 +1,57 @@
1
+ import { components } from "../../../anyspend/types/api";
2
+ import { GetQuoteResponse } from "../../../anyspend/types/api_req_res";
3
+ import React from "react";
4
+ export interface AnySpendCollectorClubPurchaseProps {
5
+ /**
6
+ * Optional order ID to load existing order
7
+ */
8
+ loadOrder?: string;
9
+ /**
10
+ * Display mode
11
+ */
12
+ mode?: "modal" | "page";
13
+ /**
14
+ * Active tab (crypto or fiat payment)
15
+ */
16
+ activeTab?: "crypto" | "fiat";
17
+ /**
18
+ * The pack ID to purchase
19
+ */
20
+ packId: number;
21
+ /**
22
+ * The number of packs to purchase
23
+ */
24
+ packAmount: number;
25
+ /**
26
+ * Price per pack in wei (e.g., "10000" for 0.01 USDC with 6 decimals)
27
+ */
28
+ pricePerPack: string;
29
+ /**
30
+ * The payment token (defaults to USDC on Base)
31
+ */
32
+ paymentToken?: components["schemas"]["Token"];
33
+ /**
34
+ * Address that will receive the packs
35
+ */
36
+ recipientAddress: string;
37
+ /**
38
+ * Optional spender address (defaults to contract address)
39
+ */
40
+ spenderAddress?: string;
41
+ /**
42
+ * Success callback
43
+ */
44
+ onSuccess?: (txHash?: string) => void;
45
+ /**
46
+ * Optional custom header component
47
+ */
48
+ header?: (props: {
49
+ anyspendPrice: GetQuoteResponse | undefined;
50
+ isLoadingAnyspendPrice: boolean;
51
+ }) => React.JSX.Element;
52
+ /**
53
+ * Show recipient selection (default: true)
54
+ */
55
+ showRecipient?: boolean;
56
+ }
57
+ export declare function AnySpendCollectorClubPurchase({ loadOrder, mode, activeTab, packId, packAmount, pricePerPack, paymentToken, recipientAddress, spenderAddress, onSuccess, header, showRecipient, }: AnySpendCollectorClubPurchaseProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AnySpendCollectorClubPurchase = AnySpendCollectorClubPurchase;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ /**
6
+ * AnySpend component for Collector Club pack purchases
7
+ *
8
+ * This component enables users to purchase Collector Club packs using any token via AnySpend.
9
+ * It calls the `buyPacksFor` function on the Collector Club Shop contract on Base.
10
+ * Uses exact-out flow to ensure the contract receives exactly the required USDC amount.
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * import { AnySpendCollectorClubPurchase } from "../../..";
15
+ * import { USDC_BASE } from "../../../anyspend/constants";
16
+ *
17
+ * function MyComponent() {
18
+ * return (
19
+ * <AnySpendCollectorClubPurchase
20
+ * packId={1}
21
+ * packAmount={5}
22
+ * pricePerPack="10000" // 0.01 USDC in wei (6 decimals)
23
+ * paymentToken={USDC_BASE}
24
+ * recipientAddress="0x123..."
25
+ * onSuccess={(txHash) => console.log("Purchase successful!", txHash)}
26
+ * />
27
+ * );
28
+ * }
29
+ * ```
30
+ */
31
+ const constants_1 = require("../../../anyspend/constants");
32
+ const react_1 = require("react");
33
+ const viem_1 = require("viem");
34
+ const AnySpendCustom_1 = require("./AnySpendCustom");
35
+ // Collector Club Shop contract on Base
36
+ const CC_SHOP_ADDRESS = "0x68B32D594E3c7E5B8cd8046BD66AfB0DB5b9BF9c";
37
+ const BASE_CHAIN_ID = 8453;
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
+ };
50
+ function AnySpendCollectorClubPurchase({ loadOrder, mode = "modal", activeTab = "crypto", packId, packAmount, pricePerPack, paymentToken = constants_1.USDC_BASE, recipientAddress, spenderAddress = CC_SHOP_ADDRESS, onSuccess, header, showRecipient = true, }) {
51
+ // Calculate total amount needed (pricePerPack * packAmount)
52
+ const totalAmount = (0, react_1.useMemo)(() => {
53
+ try {
54
+ return (BigInt(pricePerPack) * BigInt(packAmount)).toString();
55
+ }
56
+ catch (error) {
57
+ console.error("Failed to calculate total amount from props", { pricePerPack, packAmount, error });
58
+ return "0";
59
+ }
60
+ }, [pricePerPack, packAmount]);
61
+ // Encode the buyPacksFor function call
62
+ const encodedData = (0, react_1.useMemo)(() => {
63
+ try {
64
+ return (0, viem_1.encodeFunctionData)({
65
+ abi: [BUY_PACKS_FOR_ABI],
66
+ functionName: "buyPacksFor",
67
+ args: [recipientAddress, BigInt(packId), BigInt(packAmount)],
68
+ });
69
+ }
70
+ catch (error) {
71
+ console.error("Failed to encode function data", { recipientAddress, packId, packAmount, error });
72
+ return "0x";
73
+ }
74
+ }, [recipientAddress, packId, packAmount]);
75
+ // Default header if not provided
76
+ const defaultHeader = () => ((0, jsx_runtime_1.jsx)("div", { className: "mb-4 flex flex-col items-center gap-3 text-center", children: (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-as-primary text-xl font-bold", children: "Buy Collector Club Packs" }), (0, jsx_runtime_1.jsxs)("p", { className: "text-as-secondary text-sm", children: ["Purchase ", packAmount, " pack", packAmount !== 1 ? "s" : "", " using any token"] })] }) }));
77
+ return ((0, jsx_runtime_1.jsx)(AnySpendCustom_1.AnySpendCustom, { loadOrder: loadOrder, mode: mode, activeTab: activeTab, recipientAddress: recipientAddress, spenderAddress: spenderAddress, orderType: "custom", dstChainId: BASE_CHAIN_ID, dstToken: paymentToken, dstAmount: totalAmount, contractAddress: CC_SHOP_ADDRESS, encodedData: encodedData, metadata: {
78
+ packId,
79
+ packAmount,
80
+ pricePerPack,
81
+ }, header: header || defaultHeader, onSuccess: onSuccess, showRecipient: showRecipient }));
82
+ }
@@ -1,6 +1,7 @@
1
1
  export { AnySpend } from "./AnySpend";
2
2
  export { AnySpendBondKit } from "./AnySpendBondKit";
3
3
  export { AnySpendBuySpin } from "./AnySpendBuySpin";
4
+ export { AnySpendCollectorClubPurchase } from "./AnySpendCollectorClubPurchase";
4
5
  export { AnySpendCustom } from "./AnySpendCustom";
5
6
  export { AnySpendCustomExactIn } from "./AnySpendCustomExactIn";
6
7
  export { AnySpendDepositHype, HYPE_TOKEN_DETAILS } from "./AnyspendDepositHype";
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.WebviewOnrampPayment = exports.WebviewOnrampOrderStatus = exports.TransferCryptoDetails = exports.TokenBalance = exports.StepProgress = exports.RecipientSelection = exports.OrderTokenAmount = exports.OrderToken = exports.OrderStatus = exports.OrderHistoryItem = exports.OrderHistory = exports.OrderDetailsCollapsible = exports.OrderDetails = exports.CryptoReceiveSection = exports.CryptoPaySection = exports.ChainTokenIcon = exports.AnySpendNFTButton = exports.AnySpendTournament = exports.AnySpendStakeUpsideExactIn = exports.AnySpendStakeUpside = exports.AnySpendStakeB3ExactIn = exports.AnySpendStakeB3 = exports.AnyspendSignatureMint = exports.AnySpendNFT = exports.HYPE_TOKEN_DETAILS = exports.AnySpendDepositHype = exports.AnySpendCustomExactIn = exports.AnySpendCustom = exports.AnySpendBuySpin = exports.AnySpendBondKit = exports.AnySpend = void 0;
17
+ exports.WebviewOnrampPayment = exports.WebviewOnrampOrderStatus = exports.TransferCryptoDetails = exports.TokenBalance = exports.StepProgress = exports.RecipientSelection = exports.OrderTokenAmount = exports.OrderToken = exports.OrderStatus = exports.OrderHistoryItem = exports.OrderHistory = exports.OrderDetailsCollapsible = exports.OrderDetails = exports.CryptoReceiveSection = exports.CryptoPaySection = exports.ChainTokenIcon = exports.AnySpendNFTButton = exports.AnySpendTournament = exports.AnySpendStakeUpsideExactIn = exports.AnySpendStakeUpside = exports.AnySpendStakeB3ExactIn = exports.AnySpendStakeB3 = exports.AnyspendSignatureMint = exports.AnySpendNFT = exports.HYPE_TOKEN_DETAILS = exports.AnySpendDepositHype = exports.AnySpendCustomExactIn = exports.AnySpendCustom = exports.AnySpendCollectorClubPurchase = exports.AnySpendBuySpin = exports.AnySpendBondKit = exports.AnySpend = void 0;
18
18
  // Components
19
19
  var AnySpend_1 = require("./AnySpend");
20
20
  Object.defineProperty(exports, "AnySpend", { enumerable: true, get: function () { return AnySpend_1.AnySpend; } });
@@ -22,6 +22,8 @@ var AnySpendBondKit_1 = require("./AnySpendBondKit");
22
22
  Object.defineProperty(exports, "AnySpendBondKit", { enumerable: true, get: function () { return AnySpendBondKit_1.AnySpendBondKit; } });
23
23
  var AnySpendBuySpin_1 = require("./AnySpendBuySpin");
24
24
  Object.defineProperty(exports, "AnySpendBuySpin", { enumerable: true, get: function () { return AnySpendBuySpin_1.AnySpendBuySpin; } });
25
+ var AnySpendCollectorClubPurchase_1 = require("./AnySpendCollectorClubPurchase");
26
+ Object.defineProperty(exports, "AnySpendCollectorClubPurchase", { enumerable: true, get: function () { return AnySpendCollectorClubPurchase_1.AnySpendCollectorClubPurchase; } });
25
27
  var AnySpendCustom_1 = require("./AnySpendCustom");
26
28
  Object.defineProperty(exports, "AnySpendCustom", { enumerable: true, get: function () { return AnySpendCustom_1.AnySpendCustom; } });
27
29
  var AnySpendCustomExactIn_1 = require("./AnySpendCustomExactIn");
@@ -118,6 +118,8 @@ function B3DynamicModal() {
118
118
  return (0, jsx_runtime_1.jsx)(LinkAccount_1.LinkAccount, { ...contentType });
119
119
  case "anySpendDepositHype":
120
120
  return (0, jsx_runtime_1.jsx)(AnyspendDepositHype_1.AnySpendDepositHype, { ...contentType, mode: "modal" });
121
+ case "anySpendCollectorClubPurchase":
122
+ return (0, jsx_runtime_1.jsx)(react_1.AnySpendCollectorClubPurchase, { ...contentType, mode: "modal" });
121
123
  case "avatarEditor":
122
124
  return (0, jsx_runtime_1.jsx)(AvatarEditor_1.AvatarEditor, { onSetAvatar: contentType.onSuccess });
123
125
  case "profileEditor":
@@ -377,10 +377,30 @@ export interface ProfileEditorModalProps extends BaseModalProps {
377
377
  /** Callback function called when profile is successfully updated */
378
378
  onSuccess?: () => void;
379
379
  }
380
+ /**
381
+ * Props for the AnySpend Collector Club Purchase modal
382
+ * Handles Collector Club pack purchases
383
+ */
384
+ export interface AnySpendCollectorClubPurchaseProps extends BaseModalProps {
385
+ /** Modal type identifier */
386
+ type: "anySpendCollectorClubPurchase";
387
+ /** The pack ID to purchase */
388
+ packId: number;
389
+ /** The number of packs to purchase */
390
+ packAmount: number;
391
+ /** Price per pack in wei (e.g., "10000" for 0.01 USDC with 6 decimals) */
392
+ pricePerPack: string;
393
+ /** Recipient address to receive the packs */
394
+ recipientAddress: string;
395
+ /** Payment type - crypto or fiat */
396
+ paymentType?: "crypto" | "fiat";
397
+ /** Callback function called when the purchase is successful */
398
+ onSuccess?: (txHash?: string) => void;
399
+ }
380
400
  /**
381
401
  * Union type of all possible modal content types
382
402
  */
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;
403
+ 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
404
  /**
385
405
  * State interface for the modal store
386
406
  */
@@ -0,0 +1,57 @@
1
+ import { components } from "../../../anyspend/types/api";
2
+ import { GetQuoteResponse } from "../../../anyspend/types/api_req_res";
3
+ import React from "react";
4
+ export interface AnySpendCollectorClubPurchaseProps {
5
+ /**
6
+ * Optional order ID to load existing order
7
+ */
8
+ loadOrder?: string;
9
+ /**
10
+ * Display mode
11
+ */
12
+ mode?: "modal" | "page";
13
+ /**
14
+ * Active tab (crypto or fiat payment)
15
+ */
16
+ activeTab?: "crypto" | "fiat";
17
+ /**
18
+ * The pack ID to purchase
19
+ */
20
+ packId: number;
21
+ /**
22
+ * The number of packs to purchase
23
+ */
24
+ packAmount: number;
25
+ /**
26
+ * Price per pack in wei (e.g., "10000" for 0.01 USDC with 6 decimals)
27
+ */
28
+ pricePerPack: string;
29
+ /**
30
+ * The payment token (defaults to USDC on Base)
31
+ */
32
+ paymentToken?: components["schemas"]["Token"];
33
+ /**
34
+ * Address that will receive the packs
35
+ */
36
+ recipientAddress: string;
37
+ /**
38
+ * Optional spender address (defaults to contract address)
39
+ */
40
+ spenderAddress?: string;
41
+ /**
42
+ * Success callback
43
+ */
44
+ onSuccess?: (txHash?: string) => void;
45
+ /**
46
+ * Optional custom header component
47
+ */
48
+ header?: (props: {
49
+ anyspendPrice: GetQuoteResponse | undefined;
50
+ isLoadingAnyspendPrice: boolean;
51
+ }) => React.JSX.Element;
52
+ /**
53
+ * Show recipient selection (default: true)
54
+ */
55
+ showRecipient?: boolean;
56
+ }
57
+ export declare function AnySpendCollectorClubPurchase({ loadOrder, mode, activeTab, packId, packAmount, pricePerPack, paymentToken, recipientAddress, spenderAddress, onSuccess, header, showRecipient, }: AnySpendCollectorClubPurchaseProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,79 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * AnySpend component for Collector Club pack purchases
4
+ *
5
+ * This component enables users to purchase Collector Club packs using any token via AnySpend.
6
+ * It calls the `buyPacksFor` function on the Collector Club Shop contract on Base.
7
+ * Uses exact-out flow to ensure the contract receives exactly the required USDC amount.
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * import { AnySpendCollectorClubPurchase } from "../../..";
12
+ * import { USDC_BASE } from "../../../anyspend/constants/index.js";
13
+ *
14
+ * function MyComponent() {
15
+ * return (
16
+ * <AnySpendCollectorClubPurchase
17
+ * packId={1}
18
+ * packAmount={5}
19
+ * pricePerPack="10000" // 0.01 USDC in wei (6 decimals)
20
+ * paymentToken={USDC_BASE}
21
+ * recipientAddress="0x123..."
22
+ * onSuccess={(txHash) => console.log("Purchase successful!", txHash)}
23
+ * />
24
+ * );
25
+ * }
26
+ * ```
27
+ */
28
+ import { USDC_BASE } from "../../../anyspend/constants/index.js";
29
+ import { useMemo } from "react";
30
+ import { encodeFunctionData } from "viem";
31
+ import { AnySpendCustom } from "./AnySpendCustom.js";
32
+ // Collector Club Shop contract on Base
33
+ const CC_SHOP_ADDRESS = "0x68B32D594E3c7E5B8cd8046BD66AfB0DB5b9BF9c";
34
+ const BASE_CHAIN_ID = 8453;
35
+ // ABI for buyPacksFor function only
36
+ const BUY_PACKS_FOR_ABI = {
37
+ inputs: [
38
+ { internalType: "address", name: "user", type: "address" },
39
+ { internalType: "uint256", name: "packId", type: "uint256" },
40
+ { internalType: "uint256", name: "amount", type: "uint256" },
41
+ ],
42
+ name: "buyPacksFor",
43
+ outputs: [],
44
+ stateMutability: "nonpayable",
45
+ type: "function",
46
+ };
47
+ export function AnySpendCollectorClubPurchase({ loadOrder, mode = "modal", activeTab = "crypto", packId, packAmount, pricePerPack, paymentToken = USDC_BASE, recipientAddress, spenderAddress = CC_SHOP_ADDRESS, onSuccess, header, showRecipient = true, }) {
48
+ // Calculate total amount needed (pricePerPack * packAmount)
49
+ const totalAmount = useMemo(() => {
50
+ try {
51
+ return (BigInt(pricePerPack) * BigInt(packAmount)).toString();
52
+ }
53
+ catch (error) {
54
+ console.error("Failed to calculate total amount from props", { pricePerPack, packAmount, error });
55
+ return "0";
56
+ }
57
+ }, [pricePerPack, packAmount]);
58
+ // Encode the buyPacksFor function call
59
+ const encodedData = useMemo(() => {
60
+ try {
61
+ return encodeFunctionData({
62
+ abi: [BUY_PACKS_FOR_ABI],
63
+ functionName: "buyPacksFor",
64
+ args: [recipientAddress, BigInt(packId), BigInt(packAmount)],
65
+ });
66
+ }
67
+ catch (error) {
68
+ console.error("Failed to encode function data", { recipientAddress, packId, packAmount, error });
69
+ return "0x";
70
+ }
71
+ }, [recipientAddress, packId, packAmount]);
72
+ // Default header if not provided
73
+ const defaultHeader = () => (_jsx("div", { className: "mb-4 flex flex-col items-center gap-3 text-center", children: _jsxs("div", { children: [_jsx("h1", { className: "text-as-primary text-xl font-bold", children: "Buy Collector Club Packs" }), _jsxs("p", { className: "text-as-secondary text-sm", children: ["Purchase ", packAmount, " pack", packAmount !== 1 ? "s" : "", " using any token"] })] }) }));
74
+ return (_jsx(AnySpendCustom, { loadOrder: loadOrder, mode: mode, activeTab: activeTab, recipientAddress: recipientAddress, spenderAddress: spenderAddress, orderType: "custom", dstChainId: BASE_CHAIN_ID, dstToken: paymentToken, dstAmount: totalAmount, contractAddress: CC_SHOP_ADDRESS, encodedData: encodedData, metadata: {
75
+ packId,
76
+ packAmount,
77
+ pricePerPack,
78
+ }, header: header || defaultHeader, onSuccess: onSuccess, showRecipient: showRecipient }));
79
+ }
@@ -1,6 +1,7 @@
1
1
  export { AnySpend } from "./AnySpend";
2
2
  export { AnySpendBondKit } from "./AnySpendBondKit";
3
3
  export { AnySpendBuySpin } from "./AnySpendBuySpin";
4
+ export { AnySpendCollectorClubPurchase } from "./AnySpendCollectorClubPurchase";
4
5
  export { AnySpendCustom } from "./AnySpendCustom";
5
6
  export { AnySpendCustomExactIn } from "./AnySpendCustomExactIn";
6
7
  export { AnySpendDepositHype, HYPE_TOKEN_DETAILS } from "./AnyspendDepositHype";
@@ -2,6 +2,7 @@
2
2
  export { AnySpend } from "./AnySpend.js";
3
3
  export { AnySpendBondKit } from "./AnySpendBondKit.js";
4
4
  export { AnySpendBuySpin } from "./AnySpendBuySpin.js";
5
+ export { AnySpendCollectorClubPurchase } from "./AnySpendCollectorClubPurchase.js";
5
6
  export { AnySpendCustom } from "./AnySpendCustom.js";
6
7
  export { AnySpendCustomExactIn } from "./AnySpendCustomExactIn.js";
7
8
  export { AnySpendDepositHype, HYPE_TOKEN_DETAILS } from "./AnyspendDepositHype.js";
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { AnySpend, AnySpendBondKit, AnySpendBuySpin, AnySpendNFT, AnyspendSignatureMint, AnySpendStakeB3, AnySpendStakeB3ExactIn, AnySpendTournament, OrderHistory, } from "../../../anyspend/react/index.js";
2
+ import { AnySpend, AnySpendBondKit, AnySpendBuySpin, AnySpendCollectorClubPurchase, AnySpendNFT, AnyspendSignatureMint, AnySpendStakeB3, AnySpendStakeB3ExactIn, AnySpendTournament, OrderHistory, } from "../../../anyspend/react/index.js";
3
3
  import { AnySpendDepositHype } from "../../../anyspend/react/components/AnyspendDepositHype.js";
4
4
  import { AnySpendStakeUpside } from "../../../anyspend/react/components/AnySpendStakeUpside.js";
5
5
  import { AnySpendStakeUpsideExactIn } from "../../../anyspend/react/components/AnySpendStakeUpsideExactIn.js";
@@ -115,6 +115,8 @@ export function B3DynamicModal() {
115
115
  return _jsx(LinkAccount, { ...contentType });
116
116
  case "anySpendDepositHype":
117
117
  return _jsx(AnySpendDepositHype, { ...contentType, mode: "modal" });
118
+ case "anySpendCollectorClubPurchase":
119
+ return _jsx(AnySpendCollectorClubPurchase, { ...contentType, mode: "modal" });
118
120
  case "avatarEditor":
119
121
  return _jsx(AvatarEditor, { onSetAvatar: contentType.onSuccess });
120
122
  case "profileEditor":
@@ -377,10 +377,30 @@ export interface ProfileEditorModalProps extends BaseModalProps {
377
377
  /** Callback function called when profile is successfully updated */
378
378
  onSuccess?: () => void;
379
379
  }
380
+ /**
381
+ * Props for the AnySpend Collector Club Purchase modal
382
+ * Handles Collector Club pack purchases
383
+ */
384
+ export interface AnySpendCollectorClubPurchaseProps extends BaseModalProps {
385
+ /** Modal type identifier */
386
+ type: "anySpendCollectorClubPurchase";
387
+ /** The pack ID to purchase */
388
+ packId: number;
389
+ /** The number of packs to purchase */
390
+ packAmount: number;
391
+ /** Price per pack in wei (e.g., "10000" for 0.01 USDC with 6 decimals) */
392
+ pricePerPack: string;
393
+ /** Recipient address to receive the packs */
394
+ recipientAddress: string;
395
+ /** Payment type - crypto or fiat */
396
+ paymentType?: "crypto" | "fiat";
397
+ /** Callback function called when the purchase is successful */
398
+ onSuccess?: (txHash?: string) => void;
399
+ }
380
400
  /**
381
401
  * Union type of all possible modal content types
382
402
  */
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;
403
+ 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
404
  /**
385
405
  * State interface for the modal store
386
406
  */
@@ -0,0 +1,57 @@
1
+ import { components } from "@b3dotfun/sdk/anyspend/types/api";
2
+ import { GetQuoteResponse } from "@b3dotfun/sdk/anyspend/types/api_req_res";
3
+ import React from "react";
4
+ export interface AnySpendCollectorClubPurchaseProps {
5
+ /**
6
+ * Optional order ID to load existing order
7
+ */
8
+ loadOrder?: string;
9
+ /**
10
+ * Display mode
11
+ */
12
+ mode?: "modal" | "page";
13
+ /**
14
+ * Active tab (crypto or fiat payment)
15
+ */
16
+ activeTab?: "crypto" | "fiat";
17
+ /**
18
+ * The pack ID to purchase
19
+ */
20
+ packId: number;
21
+ /**
22
+ * The number of packs to purchase
23
+ */
24
+ packAmount: number;
25
+ /**
26
+ * Price per pack in wei (e.g., "10000" for 0.01 USDC with 6 decimals)
27
+ */
28
+ pricePerPack: string;
29
+ /**
30
+ * The payment token (defaults to USDC on Base)
31
+ */
32
+ paymentToken?: components["schemas"]["Token"];
33
+ /**
34
+ * Address that will receive the packs
35
+ */
36
+ recipientAddress: string;
37
+ /**
38
+ * Optional spender address (defaults to contract address)
39
+ */
40
+ spenderAddress?: string;
41
+ /**
42
+ * Success callback
43
+ */
44
+ onSuccess?: (txHash?: string) => void;
45
+ /**
46
+ * Optional custom header component
47
+ */
48
+ header?: (props: {
49
+ anyspendPrice: GetQuoteResponse | undefined;
50
+ isLoadingAnyspendPrice: boolean;
51
+ }) => React.JSX.Element;
52
+ /**
53
+ * Show recipient selection (default: true)
54
+ */
55
+ showRecipient?: boolean;
56
+ }
57
+ export declare function AnySpendCollectorClubPurchase({ loadOrder, mode, activeTab, packId, packAmount, pricePerPack, paymentToken, recipientAddress, spenderAddress, onSuccess, header, showRecipient, }: AnySpendCollectorClubPurchaseProps): import("react/jsx-runtime").JSX.Element;
@@ -1,6 +1,7 @@
1
1
  export { AnySpend } from "./AnySpend";
2
2
  export { AnySpendBondKit } from "./AnySpendBondKit";
3
3
  export { AnySpendBuySpin } from "./AnySpendBuySpin";
4
+ export { AnySpendCollectorClubPurchase } from "./AnySpendCollectorClubPurchase";
4
5
  export { AnySpendCustom } from "./AnySpendCustom";
5
6
  export { AnySpendCustomExactIn } from "./AnySpendCustomExactIn";
6
7
  export { AnySpendDepositHype, HYPE_TOKEN_DETAILS } from "./AnyspendDepositHype";
@@ -377,10 +377,30 @@ export interface ProfileEditorModalProps extends BaseModalProps {
377
377
  /** Callback function called when profile is successfully updated */
378
378
  onSuccess?: () => void;
379
379
  }
380
+ /**
381
+ * Props for the AnySpend Collector Club Purchase modal
382
+ * Handles Collector Club pack purchases
383
+ */
384
+ export interface AnySpendCollectorClubPurchaseProps extends BaseModalProps {
385
+ /** Modal type identifier */
386
+ type: "anySpendCollectorClubPurchase";
387
+ /** The pack ID to purchase */
388
+ packId: number;
389
+ /** The number of packs to purchase */
390
+ packAmount: number;
391
+ /** Price per pack in wei (e.g., "10000" for 0.01 USDC with 6 decimals) */
392
+ pricePerPack: string;
393
+ /** Recipient address to receive the packs */
394
+ recipientAddress: string;
395
+ /** Payment type - crypto or fiat */
396
+ paymentType?: "crypto" | "fiat";
397
+ /** Callback function called when the purchase is successful */
398
+ onSuccess?: (txHash?: string) => void;
399
+ }
380
400
  /**
381
401
  * Union type of all possible modal content types
382
402
  */
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;
403
+ 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
404
  /**
385
405
  * State interface for the modal store
386
406
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@b3dotfun/sdk",
3
- "version": "0.0.68-alpha.0",
3
+ "version": "0.0.69-test.0",
4
4
  "source": "src/index.ts",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "react-native": "./dist/cjs/index.native.js",
@@ -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
+ }
@@ -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";
@@ -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":
@@ -401,6 +401,27 @@ export interface ProfileEditorModalProps extends BaseModalProps {
401
401
  onSuccess?: () => void;
402
402
  }
403
403
 
404
+ /**
405
+ * Props for the AnySpend Collector Club Purchase modal
406
+ * Handles Collector Club pack purchases
407
+ */
408
+ export interface AnySpendCollectorClubPurchaseProps extends BaseModalProps {
409
+ /** Modal type identifier */
410
+ type: "anySpendCollectorClubPurchase";
411
+ /** The pack ID to purchase */
412
+ packId: number;
413
+ /** The number of packs to purchase */
414
+ packAmount: number;
415
+ /** Price per pack in wei (e.g., "10000" for 0.01 USDC with 6 decimals) */
416
+ pricePerPack: string;
417
+ /** Recipient address to receive the packs */
418
+ recipientAddress: string;
419
+ /** Payment type - crypto or fiat */
420
+ paymentType?: "crypto" | "fiat";
421
+ /** Callback function called when the purchase is successful */
422
+ onSuccess?: (txHash?: string) => void;
423
+ }
424
+
404
425
  /**
405
426
  * Union type of all possible modal content types
406
427
  */
@@ -425,7 +446,8 @@ export type ModalContentType =
425
446
  | LinkAccountModalProps
426
447
  | AnySpendDepositHypeProps
427
448
  | AvatarEditorModalProps
428
- | ProfileEditorModalProps;
449
+ | ProfileEditorModalProps
450
+ | AnySpendCollectorClubPurchaseProps;
429
451
  // Add other modal types here like: | OtherModalProps | AnotherModalProps
430
452
 
431
453
  /**