@b3dotfun/sdk 0.0.40-alpha.6 → 0.0.40-alpha.8

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 (53) hide show
  1. package/dist/cjs/anyspend/react/components/AnySpend.js +1 -1
  2. package/dist/cjs/anyspend/react/components/AnyspendDepositHype.js +1 -1
  3. package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.js +38 -36
  4. package/dist/cjs/anyspend/react/components/common/PanelOnramp.d.ts +3 -1
  5. package/dist/cjs/anyspend/react/components/common/PanelOnramp.js +7 -6
  6. package/dist/cjs/anyspend/react/contexts/FeatureFlagsContext.d.ts +11 -0
  7. package/dist/cjs/anyspend/react/contexts/FeatureFlagsContext.js +21 -0
  8. package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.d.ts +1 -65
  9. package/dist/cjs/anyspend/react/providers/AnyspendProvider.d.ts +5 -2
  10. package/dist/cjs/anyspend/react/providers/AnyspendProvider.js +5 -3
  11. package/dist/cjs/anyspend/react/providers/index.d.ts +1 -0
  12. package/dist/cjs/anyspend/react/providers/index.js +3 -0
  13. package/dist/cjs/anyspend/types/api_req_res.d.ts +8 -1
  14. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.d.ts +3 -2
  15. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.js +35 -16
  16. package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStepCustom.js +4 -3
  17. package/dist/cjs/global-account/react/hooks/useAuthentication.js +1 -2
  18. package/dist/esm/anyspend/react/components/AnySpend.js +1 -1
  19. package/dist/esm/anyspend/react/components/AnyspendDepositHype.js +1 -1
  20. package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.js +38 -36
  21. package/dist/esm/anyspend/react/components/common/PanelOnramp.d.ts +3 -1
  22. package/dist/esm/anyspend/react/components/common/PanelOnramp.js +7 -6
  23. package/dist/esm/anyspend/react/contexts/FeatureFlagsContext.d.ts +11 -0
  24. package/dist/esm/anyspend/react/contexts/FeatureFlagsContext.js +17 -0
  25. package/dist/esm/anyspend/react/hooks/useAnyspendFlow.d.ts +1 -65
  26. package/dist/esm/anyspend/react/providers/AnyspendProvider.d.ts +5 -2
  27. package/dist/esm/anyspend/react/providers/AnyspendProvider.js +5 -3
  28. package/dist/esm/anyspend/react/providers/index.d.ts +1 -0
  29. package/dist/esm/anyspend/react/providers/index.js +1 -0
  30. package/dist/esm/anyspend/types/api_req_res.d.ts +8 -1
  31. package/dist/esm/global-account/react/components/B3Provider/B3Provider.d.ts +3 -2
  32. package/dist/esm/global-account/react/components/B3Provider/B3Provider.js +36 -17
  33. package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStepCustom.js +3 -2
  34. package/dist/esm/global-account/react/hooks/useAuthentication.js +1 -2
  35. package/dist/types/anyspend/react/components/common/PanelOnramp.d.ts +3 -1
  36. package/dist/types/anyspend/react/contexts/FeatureFlagsContext.d.ts +11 -0
  37. package/dist/types/anyspend/react/hooks/useAnyspendFlow.d.ts +1 -65
  38. package/dist/types/anyspend/react/providers/AnyspendProvider.d.ts +5 -2
  39. package/dist/types/anyspend/react/providers/index.d.ts +1 -0
  40. package/dist/types/anyspend/types/api_req_res.d.ts +8 -1
  41. package/dist/types/global-account/react/components/B3Provider/B3Provider.d.ts +3 -2
  42. package/package.json +6 -5
  43. package/src/anyspend/react/components/AnySpend.tsx +1 -0
  44. package/src/anyspend/react/components/AnyspendDepositHype.tsx +1 -0
  45. package/src/anyspend/react/components/common/CryptoReceiveSection.tsx +56 -45
  46. package/src/anyspend/react/components/common/PanelOnramp.tsx +22 -16
  47. package/src/anyspend/react/contexts/FeatureFlagsContext.tsx +34 -0
  48. package/src/anyspend/react/providers/AnyspendProvider.tsx +11 -6
  49. package/src/anyspend/react/providers/index.ts +1 -0
  50. package/src/anyspend/types/api_req_res.ts +10 -1
  51. package/src/global-account/react/components/B3Provider/B3Provider.tsx +49 -24
  52. package/src/global-account/react/components/SignInWithB3/steps/LoginStepCustom.tsx +4 -2
  53. package/src/global-account/react/hooks/useAuthentication.ts +1 -2
@@ -78,71 +78,7 @@ export declare function useAnyspendFlow({ paymentType, recipientAddress, loadOrd
78
78
  globalAddress: string | undefined;
79
79
  hasEnoughBalance: boolean;
80
80
  isBalanceLoading: boolean;
81
- anyspendQuote: {
82
- success: boolean;
83
- message: string;
84
- data: {
85
- operation?: string;
86
- sender?: string;
87
- recipient?: string;
88
- currencyIn?: {
89
- currency?: {
90
- chainId?: number;
91
- address?: string;
92
- symbol?: string;
93
- name?: string;
94
- decimals?: number;
95
- metadata?: {
96
- logoURI?: string;
97
- };
98
- };
99
- amount?: string;
100
- amountFormatted?: string;
101
- amountUsd?: string;
102
- minimumAmount?: string;
103
- };
104
- currencyOut?: {
105
- currency?: {
106
- chainId?: number;
107
- address?: string;
108
- symbol?: string;
109
- name?: string;
110
- decimals?: number;
111
- metadata?: {
112
- logoURI?: string;
113
- };
114
- };
115
- amount?: string;
116
- amountFormatted?: string;
117
- amountUsd?: string;
118
- minimumAmount?: string;
119
- };
120
- totalImpact?: {
121
- usd?: string;
122
- percent?: string;
123
- };
124
- swapImpact?: {
125
- usd?: string;
126
- percent?: string;
127
- };
128
- rate?: string;
129
- slippageTolerance?: {
130
- origin?: {
131
- usd?: string;
132
- value?: string;
133
- percent?: string;
134
- };
135
- destination?: {
136
- usd?: string;
137
- value?: string;
138
- percent?: string;
139
- };
140
- };
141
- timeEstimate?: number;
142
- userBalance?: string;
143
- };
144
- statusCode: number;
145
- } | undefined;
81
+ anyspendQuote: import("../../types/api_req_res").GetQuoteResponse | undefined;
146
82
  isLoadingAnyspendQuote: boolean;
147
83
  getAnyspendQuoteError: Error | null;
148
84
  activeInputAmountInWei: string;
@@ -1,6 +1,8 @@
1
1
  import { ReactNode } from "react";
2
+ import { FeatureFlags } from "../contexts/FeatureFlagsContext";
2
3
  interface AnyspendProviderProps {
3
4
  children: ReactNode;
5
+ featureFlags?: FeatureFlags;
4
6
  }
5
7
  /**
6
8
  * AnyspendProvider is a top-level provider that wraps your application to provide
@@ -12,17 +14,18 @@ interface AnyspendProviderProps {
12
14
  * - Safe to use at the application root
13
15
  * - Configures sensible defaults for query caching
14
16
  * - Handles Stripe payment redirects and modal state
17
+ * - Provides feature flags configuration
15
18
  *
16
19
  * @example
17
20
  * ```tsx
18
21
  * function App() {
19
22
  * return (
20
- * <AnyspendProvider>
23
+ * <AnyspendProvider featureFlags={{ showPoints: true }}>
21
24
  * <YourApp />
22
25
  * </AnyspendProvider>
23
26
  * );
24
27
  * }
25
28
  * ```
26
29
  */
27
- export declare const AnyspendProvider: ({ children }: AnyspendProviderProps) => import("react/jsx-runtime").JSX.Element;
30
+ export declare const AnyspendProvider: ({ children, featureFlags }: AnyspendProviderProps) => import("react/jsx-runtime").JSX.Element;
28
31
  export {};
@@ -1,2 +1,3 @@
1
1
  export * from "./AnyspendProvider";
2
2
  export * from "./StripeRedirectHandler";
3
+ export { useFeatureFlags, type FeatureFlags } from "../contexts/FeatureFlagsContext";
@@ -1,10 +1,17 @@
1
1
  import { paths } from "./api";
2
2
  export type GetOrderAndTxsResponse = paths["/orders/{orderId}"]["get"]["responses"]["200"]["content"]["application/json"];
3
3
  export type GetQuoteRequest = paths["/orders/quote"]["post"]["requestBody"]["content"]["application/json"];
4
- export type GetQuoteResponse = paths["/orders/quote"]["post"]["responses"]["200"]["content"]["application/json"];
4
+ type BaseGetQuoteResponse = paths["/orders/quote"]["post"]["responses"]["200"]["content"]["application/json"];
5
+ export type GetQuoteResponse = BaseGetQuoteResponse & {
6
+ data: BaseGetQuoteResponse["data"] & {
7
+ pointsAmount?: number;
8
+ pointsMultiplier?: number;
9
+ };
10
+ };
5
11
  export type GetCoinbaseOnrampOptionsResponse = paths["/onramp/coinbase/options"]["get"]["responses"]["200"]["content"]["application/json"];
6
12
  export type GetOrderHistoryResponse = paths["/orders"]["get"]["responses"]["200"]["content"]["application/json"];
7
13
  export type GetTokenListResponse = paths["/chains/{chainId}/tokens"]["get"]["responses"]["200"]["content"]["application/json"];
8
14
  export type CreateOrderResponse = paths["/orders"]["post"]["responses"]["200"]["content"]["application/json"];
9
15
  export type GetStripeSupportedResponse = paths["/onramp/stripe/supported"]["get"]["responses"]["200"]["content"]["application/json"];
10
16
  export type GetStripeClientSecret = paths["/stripe/clientSecret"]["get"]["responses"]["200"]["content"]["application/json"];
17
+ export {};
@@ -1,12 +1,12 @@
1
1
  import { PermissionsConfig } from "@b3dotfun/sdk/global-account/types/permissions";
2
+ import "@reservoir0x/relay-kit-ui/styles.css";
2
3
  import { Account } from "thirdweb/wallets";
3
4
  import { ClientType } from "../../../client-manager";
4
5
  import { B3ContextType } from "./types";
5
- import "@reservoir0x/relay-kit-ui/styles.css";
6
6
  /**
7
7
  * Main B3Provider component
8
8
  */
9
- export declare function B3Provider({ theme, children, accountOverride, environment, automaticallySetFirstEoa, simDuneApiKey, toaster, clientType, rpcUrls, }: {
9
+ export declare function B3Provider({ theme, children, accountOverride, environment, automaticallySetFirstEoa, simDuneApiKey, toaster, clientType, rpcUrls, partnerId, }: {
10
10
  theme: "light" | "dark";
11
11
  children: React.ReactNode;
12
12
  accountOverride?: Account;
@@ -19,6 +19,7 @@ export declare function B3Provider({ theme, children, accountOverride, environme
19
19
  };
20
20
  clientType?: ClientType;
21
21
  rpcUrls?: Record<number, string>;
22
+ partnerId?: string;
22
23
  }): import("react/jsx-runtime").JSX.Element;
23
24
  /**
24
25
  * Inner provider component that provides the actual B3Context
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@b3dotfun/sdk",
3
- "version": "0.0.40-alpha.6",
3
+ "version": "0.0.40-alpha.8",
4
4
  "source": "src/index.ts",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "react-native": "./dist/cjs/index.native.js",
@@ -241,8 +241,8 @@
241
241
  "@b3dotfun/basement-api": "0.0.11",
242
242
  "@feathersjs/authentication-client": "5.0.33",
243
243
  "@feathersjs/feathers": "5.0.33",
244
- "@feathersjs/socketio-client": "5.0.33",
245
244
  "@feathersjs/rest-client": "5.0.33",
245
+ "@feathersjs/socketio-client": "5.0.33",
246
246
  "@feathersjs/typebox": "5.0.33",
247
247
  "@fingerprintjs/fingerprintjs-pro-react": "^2.7.0",
248
248
  "@hey-api/client-fetch": "0.8.3",
@@ -261,6 +261,7 @@
261
261
  "@solana/web3.js": "^1.98.2",
262
262
  "@stripe/react-stripe-js": "^3.7.0",
263
263
  "@stripe/stripe-js": "^7.3.1",
264
+ "@thirdweb-dev/wagmi-adapter": "^0.2.141",
264
265
  "@web3icons/react": "3.16.0",
265
266
  "big.js": "^7.0.1",
266
267
  "class-variance-authority": "0.7.0",
@@ -329,10 +330,10 @@
329
330
  "react": "^18.0.0 || ^19.0.0",
330
331
  "react-dom": "^18.0.0 || ^19.0.0",
331
332
  "react-native-mmkv": "^3.2.0",
332
- "thirdweb": "^5.105.20",
333
+ "thirdweb": "5.106.0",
333
334
  "three": "^0.175.0",
334
- "wagmi": "^2.14.15",
335
- "viem": "^2.28.1"
335
+ "viem": "^2.28.1",
336
+ "wagmi": "^2.14.15"
336
337
  },
337
338
  "peerDependenciesMeta": {
338
339
  "@react-three/postprocessing": {
@@ -890,6 +890,7 @@ function AnySpendInner({
890
890
  fiatPaymentMethodIndex={PanelView.FIAT_PAYMENT_METHOD}
891
891
  recipientSelectionPanelIndex={PanelView.RECIPIENT_SELECTION}
892
892
  hideDstToken={isBuyMode}
893
+ anyspendQuote={anyspendQuote}
893
894
  />
894
895
  </motion.div>
895
896
  )}
@@ -223,6 +223,7 @@ function AnySpendDepositHypeInner({
223
223
  onDestinationChainChange={() => {}}
224
224
  fiatPaymentMethodIndex={PanelView.FIAT_PAYMENT_METHOD}
225
225
  recipientSelectionPanelIndex={PanelView.RECIPIENT_SELECTION}
226
+ anyspendQuote={anyspendQuote}
226
227
  />
227
228
  </motion.div>
228
229
  )}
@@ -4,7 +4,9 @@ import { shortenAddress } from "@b3dotfun/sdk/shared/utils/formatAddress";
4
4
  import { formatDisplayNumber } from "@b3dotfun/sdk/shared/utils/number";
5
5
  import { ChevronRight } from "lucide-react";
6
6
  import { motion } from "motion/react";
7
+ import { useEffect } from "react";
7
8
  import { components } from "../../../types/api";
9
+ import { useFeatureFlags } from "../../contexts/FeatureFlagsContext";
8
10
  import { OrderTokenAmount } from "./OrderTokenAmount";
9
11
 
10
12
  interface CryptoReceiveSectionProps {
@@ -45,6 +47,8 @@ export function CryptoReceiveSection({
45
47
  dstTokenSymbol,
46
48
  dstTokenLogoURI,
47
49
  }: CryptoReceiveSectionProps) {
50
+ const featureFlags = useFeatureFlags();
51
+
48
52
  return (
49
53
  <motion.div
50
54
  initial={{ opacity: 0, y: 20, filter: "blur(10px)" }}
@@ -100,61 +104,68 @@ export function CryptoReceiveSection({
100
104
  setToken={setSelectedDstToken || (() => {})}
101
105
  />
102
106
  )}
103
- <div className="text-as-primary/50 flex h-5 items-center text-sm">
104
- {formatDisplayNumber(anyspendQuote?.data?.currencyOut?.amountUsd, {
105
- style: "currency",
106
- fallback: "",
107
- })}
108
- {anyspendQuote?.data?.currencyIn?.amountUsd &&
109
- anyspendQuote?.data?.currencyOut?.amountUsd &&
110
- (() => {
111
- const calculatePriceImpact = (inputUsd?: string | number, outputUsd?: string | number) => {
112
- if (!inputUsd || !outputUsd) {
113
- return { percentage: "0.00", isNegative: false };
114
- }
107
+ <div className="text-as-primary/50 flex h-5 items-center justify-between text-sm">
108
+ <div className="flex items-center gap-2">
109
+ {formatDisplayNumber(anyspendQuote?.data?.currencyOut?.amountUsd, {
110
+ style: "currency",
111
+ fallback: "",
112
+ })}
113
+ {anyspendQuote?.data?.currencyIn?.amountUsd &&
114
+ anyspendQuote?.data?.currencyOut?.amountUsd &&
115
+ (() => {
116
+ const calculatePriceImpact = (inputUsd?: string | number, outputUsd?: string | number) => {
117
+ if (!inputUsd || !outputUsd) {
118
+ return { percentage: "0.00", isNegative: false };
119
+ }
115
120
 
116
- const input = Number(inputUsd);
117
- const output = Number(outputUsd);
121
+ const input = Number(inputUsd);
122
+ const output = Number(outputUsd);
118
123
 
119
- // Handle edge cases
120
- if (input === 0 || isNaN(input) || isNaN(output) || input <= output) {
121
- return { percentage: "0.00", isNegative: false };
122
- }
124
+ // Handle edge cases
125
+ if (input === 0 || isNaN(input) || isNaN(output) || input <= output) {
126
+ return { percentage: "0.00", isNegative: false };
127
+ }
123
128
 
124
- const percentageValue = ((output - input) / input) * 100;
129
+ const percentageValue = ((output - input) / input) * 100;
125
130
 
126
- // Handle the -0.00% case
127
- if (percentageValue > -0.005 && percentageValue < 0) {
128
- return { percentage: "0.00", isNegative: false };
129
- }
131
+ // Handle the -0.00% case
132
+ if (percentageValue > -0.005 && percentageValue < 0) {
133
+ return { percentage: "0.00", isNegative: false };
134
+ }
130
135
 
131
- return {
132
- percentage: Math.abs(percentageValue).toFixed(2),
133
- isNegative: percentageValue < 0,
136
+ return {
137
+ percentage: Math.abs(percentageValue).toFixed(2),
138
+ isNegative: percentageValue < 0,
139
+ };
134
140
  };
135
- };
136
141
 
137
- const { percentage, isNegative } = calculatePriceImpact(
138
- anyspendQuote.data.currencyIn.amountUsd,
139
- anyspendQuote.data.currencyOut.amountUsd,
140
- );
142
+ const { percentage, isNegative } = calculatePriceImpact(
143
+ anyspendQuote.data.currencyIn.amountUsd,
144
+ anyspendQuote.data.currencyOut.amountUsd,
145
+ );
141
146
 
142
- // Parse the percentage as a number for comparison
143
- const percentageNum = parseFloat(percentage);
147
+ // Parse the percentage as a number for comparison
148
+ const percentageNum = parseFloat(percentage);
144
149
 
145
- // Don't show if less than 1%
146
- if (percentageNum < 1) {
147
- return null;
148
- }
150
+ // Don't show if less than 1%
151
+ if (percentageNum < 1) {
152
+ return null;
153
+ }
149
154
 
150
- // Using inline style to ensure color displays
151
- return (
152
- <span className="ml-2" style={{ color: percentageNum >= 10 ? "red" : "#FFD700" }}>
153
- ({isNegative ? "-" : ""}
154
- {percentage}%)
155
- </span>
156
- );
157
- })()}
155
+ // Using inline style to ensure color displays
156
+ return (
157
+ <span className="ml-2" style={{ color: percentageNum >= 10 ? "red" : "#FFD700" }}>
158
+ ({isNegative ? "-" : ""}
159
+ {percentage}%)
160
+ </span>
161
+ );
162
+ })()}
163
+ </div>
164
+ {featureFlags.showPoints && anyspendQuote?.data?.pointsAmount && anyspendQuote.data.pointsAmount > 0 && (
165
+ <div key={`points-${anyspendQuote.data.pointsAmount}`} className="flex items-center gap-1">
166
+ <span className="text-as-brand font-medium">+{anyspendQuote.data.pointsAmount.toLocaleString()} pts</span>
167
+ </div>
168
+ )}
158
169
  </div>
159
170
  </motion.div>
160
171
  );
@@ -1,12 +1,14 @@
1
1
  import { useCoinbaseOnrampOptions, useGeoOnrampOptions } from "@b3dotfun/sdk/anyspend/react";
2
2
  import { components } from "@b3dotfun/sdk/anyspend/types/api";
3
+ import { GetQuoteResponse } from "@b3dotfun/sdk/anyspend/types/api_req_res";
3
4
  import { ALL_CHAINS } from "@b3dotfun/sdk/anyspend/utils/chain";
4
5
  import { Input, useGetGeo, useProfile } from "@b3dotfun/sdk/global-account/react";
5
6
  import { cn, formatUsername } from "@b3dotfun/sdk/shared/utils";
6
7
  import { formatAddress } from "@b3dotfun/sdk/shared/utils/formatAddress";
7
8
  import { ChevronRight, Wallet } from "lucide-react";
8
- import { useRef } from "react";
9
+ import { useRef, useEffect } from "react";
9
10
  import { toast } from "sonner";
11
+ import { useFeatureFlags } from "../../contexts/FeatureFlagsContext";
10
12
  import { FiatPaymentMethod } from "./FiatPaymentMethod";
11
13
  import { OrderTokenAmountFiat } from "./OrderTokenAmountFiat";
12
14
 
@@ -25,6 +27,7 @@ export function PanelOnramp({
25
27
  recipientSelectionPanelIndex,
26
28
  dstTokenSymbol,
27
29
  hideDstToken = false,
30
+ anyspendQuote,
28
31
  }: {
29
32
  srcAmountOnRamp: string;
30
33
  setSrcAmountOnRamp: (amount: string) => void;
@@ -40,7 +43,9 @@ export function PanelOnramp({
40
43
  recipientSelectionPanelIndex: number;
41
44
  dstTokenSymbol?: string;
42
45
  hideDstToken?: boolean;
46
+ anyspendQuote?: GetQuoteResponse;
43
47
  }) {
48
+ const featureFlags = useFeatureFlags();
44
49
  // Get geo-based onramp options to access fee information
45
50
  const { stripeWeb2Support } = useGeoOnrampOptions(srcAmountOnRamp);
46
51
 
@@ -245,21 +250,22 @@ export function PanelOnramp({
245
250
 
246
251
  <div className="">
247
252
  <div className="flex items-center justify-between">
248
- {(() => {
249
- const currentPaymentMethod = selectedPaymentMethod || FiatPaymentMethod.NONE;
250
- const fee = getFeeFromApi(currentPaymentMethod);
251
-
252
- return (
253
- <>
254
- <span className="text-as-tertiarry text-sm">
255
- {fee !== null ? `Total (included $${fee.toFixed(2)} fee)` : "Total"}
256
- </span>
257
- <span className="text-as-primary font-semibold">
258
- ${getTotalAmount(currentPaymentMethod).toFixed(2)}
259
- </span>
260
- </>
261
- );
262
- })()}
253
+ <div className="flex items-center gap-2">
254
+ <span className="text-as-tertiarry text-sm">
255
+ {(() => {
256
+ const fee = getFeeFromApi(selectedPaymentMethod || FiatPaymentMethod.NONE);
257
+ return fee !== null ? `Total (included $${fee.toFixed(2)} fee)` : "Total";
258
+ })()}
259
+ </span>
260
+ {featureFlags.showPoints && anyspendQuote?.data?.pointsAmount && anyspendQuote.data.pointsAmount > 0 && (
261
+ <span key={`points-${anyspendQuote.data.pointsAmount}`} className="text-as-brand text-sm font-medium">
262
+ +{anyspendQuote.data.pointsAmount.toLocaleString()} pts
263
+ </span>
264
+ )}
265
+ </div>
266
+ <span className="text-as-primary font-semibold">
267
+ ${getTotalAmount(selectedPaymentMethod || FiatPaymentMethod.NONE).toFixed(2)}
268
+ </span>
263
269
  </div>
264
270
  </div>
265
271
  </div>
@@ -0,0 +1,34 @@
1
+ "use client";
2
+
3
+ import { createContext, useContext, ReactNode } from "react";
4
+
5
+ export interface FeatureFlags {
6
+ showPoints?: boolean;
7
+ }
8
+
9
+ interface FeatureFlagsContextType {
10
+ featureFlags: FeatureFlags;
11
+ }
12
+
13
+ const FeatureFlagsContext = createContext<FeatureFlagsContextType | undefined>(undefined);
14
+
15
+ interface FeatureFlagsProviderProps {
16
+ children: ReactNode;
17
+ featureFlags?: FeatureFlags;
18
+ }
19
+
20
+ const defaultFeatureFlags: FeatureFlags = {
21
+ showPoints: false,
22
+ };
23
+
24
+ export function FeatureFlagsProvider({ children, featureFlags = defaultFeatureFlags }: FeatureFlagsProviderProps) {
25
+ return <FeatureFlagsContext.Provider value={{ featureFlags }}>{children}</FeatureFlagsContext.Provider>;
26
+ }
27
+
28
+ export function useFeatureFlags(): FeatureFlags {
29
+ const context = useContext(FeatureFlagsContext);
30
+ if (!context) {
31
+ return defaultFeatureFlags;
32
+ }
33
+ return context.featureFlags;
34
+ }
@@ -3,10 +3,12 @@
3
3
  import { TooltipProvider } from "@b3dotfun/sdk/global-account/react";
4
4
  import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
5
5
  import { ReactNode, useState } from "react";
6
+ import { FeatureFlags, FeatureFlagsProvider } from "../contexts/FeatureFlagsContext";
6
7
  import { StripeRedirectHandler } from "./StripeRedirectHandler";
7
8
 
8
9
  interface AnyspendProviderProps {
9
10
  children: ReactNode;
11
+ featureFlags?: FeatureFlags;
10
12
  }
11
13
 
12
14
  const defaultQueryClientConfig = {
@@ -29,27 +31,30 @@ const defaultQueryClientConfig = {
29
31
  * - Safe to use at the application root
30
32
  * - Configures sensible defaults for query caching
31
33
  * - Handles Stripe payment redirects and modal state
34
+ * - Provides feature flags configuration
32
35
  *
33
36
  * @example
34
37
  * ```tsx
35
38
  * function App() {
36
39
  * return (
37
- * <AnyspendProvider>
40
+ * <AnyspendProvider featureFlags={{ showPoints: true }}>
38
41
  * <YourApp />
39
42
  * </AnyspendProvider>
40
43
  * );
41
44
  * }
42
45
  * ```
43
46
  */
44
- export const AnyspendProvider = function AnyspendProvider({ children }: AnyspendProviderProps) {
47
+ export const AnyspendProvider = function AnyspendProvider({ children, featureFlags }: AnyspendProviderProps) {
45
48
  const [queryClient] = useState(() => new QueryClient(defaultQueryClientConfig));
46
49
 
47
50
  return (
48
51
  <QueryClientProvider client={queryClient}>
49
- <TooltipProvider>
50
- <StripeRedirectHandler />
51
- {children}
52
- </TooltipProvider>
52
+ <FeatureFlagsProvider featureFlags={featureFlags}>
53
+ <TooltipProvider>
54
+ <StripeRedirectHandler />
55
+ {children}
56
+ </TooltipProvider>
57
+ </FeatureFlagsProvider>
53
58
  </QueryClientProvider>
54
59
  );
55
60
  };
@@ -1,2 +1,3 @@
1
1
  export * from "./AnyspendProvider";
2
2
  export * from "./StripeRedirectHandler";
3
+ export { useFeatureFlags, type FeatureFlags } from "../contexts/FeatureFlagsContext";
@@ -3,7 +3,16 @@ import { paths } from "./api";
3
3
  export type GetOrderAndTxsResponse =
4
4
  paths["/orders/{orderId}"]["get"]["responses"]["200"]["content"]["application/json"];
5
5
  export type GetQuoteRequest = paths["/orders/quote"]["post"]["requestBody"]["content"]["application/json"];
6
- export type GetQuoteResponse = paths["/orders/quote"]["post"]["responses"]["200"]["content"]["application/json"];
6
+ // Base type from auto-generated API
7
+ type BaseGetQuoteResponse = paths["/orders/quote"]["post"]["responses"]["200"]["content"]["application/json"];
8
+
9
+ // Extended type with additional points fields
10
+ export type GetQuoteResponse = BaseGetQuoteResponse & {
11
+ data: BaseGetQuoteResponse["data"] & {
12
+ pointsAmount?: number;
13
+ pointsMultiplier?: number;
14
+ };
15
+ };
7
16
  export type GetCoinbaseOnrampOptionsResponse =
8
17
  paths["/onramp/coinbase/options"]["get"]["responses"]["200"]["content"]["application/json"];
9
18
  export type GetOrderHistoryResponse = paths["/orders"]["get"]["responses"]["200"]["content"]["application/json"];