@b3dotfun/sdk 0.1.0 → 0.1.1-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/dist/cjs/anyspend/react/components/AnySpend.js +1 -1
  2. package/dist/cjs/anyspend/react/components/AnySpendDeposit.d.ts +15 -10
  3. package/dist/cjs/anyspend/react/components/AnySpendDeposit.js +22 -14
  4. package/dist/cjs/anyspend/react/components/QRDeposit.js +31 -5
  5. package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.js +9 -2
  6. package/dist/cjs/anyspend/react/components/common/GasIndicator.d.ts +1 -1
  7. package/dist/cjs/anyspend/react/components/common/GasIndicator.js +6 -16
  8. package/dist/cjs/anyspend/react/components/common/TokenBalance.js +15 -4
  9. package/dist/cjs/anyspend/react/components/common/TransferResultScreen.d.ts +22 -0
  10. package/dist/cjs/anyspend/react/components/common/TransferResultScreen.js +25 -0
  11. package/dist/cjs/anyspend/react/hooks/index.d.ts +1 -0
  12. package/dist/cjs/anyspend/react/hooks/index.js +1 -0
  13. package/dist/cjs/anyspend/react/hooks/useWatchTransfer.d.ts +41 -0
  14. package/dist/cjs/anyspend/react/hooks/useWatchTransfer.js +75 -0
  15. package/dist/cjs/anyspend/react/providers/AnyspendProvider.js +1 -2
  16. package/dist/cjs/anyspend/utils/address.d.ts +5 -0
  17. package/dist/cjs/anyspend/utils/address.js +8 -0
  18. package/dist/cjs/global-account/react/components/AccountAssets/AccountAssets.js +7 -3
  19. package/dist/cjs/global-account/react/components/B3DynamicModal.js +4 -14
  20. package/dist/cjs/global-account/react/components/B3Provider/B3ConfigProvider.d.ts +31 -0
  21. package/dist/cjs/global-account/react/components/B3Provider/B3ConfigProvider.js +37 -0
  22. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.d.ts +4 -1
  23. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.js +3 -31
  24. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.native.js +4 -31
  25. package/dist/cjs/global-account/react/components/B3Provider/LocalSDKProvider.d.ts +6 -1
  26. package/dist/cjs/global-account/react/components/B3Provider/LocalSDKProvider.js +5 -1
  27. package/dist/cjs/global-account/react/components/B3Provider/useB3.d.ts +1 -12
  28. package/dist/cjs/global-account/react/components/B3Provider/useB3Config.d.ts +1 -17
  29. package/dist/cjs/global-account/react/components/B3Provider/useB3Config.js +2 -21
  30. package/dist/cjs/global-account/react/components/ManageAccount/NFTContent.js +2 -2
  31. package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +24 -4
  32. package/dist/cjs/global-account/react/components/SingleUserSearchSelector/SingleUserSearchSelector.d.ts +64 -0
  33. package/dist/cjs/global-account/react/components/SingleUserSearchSelector/SingleUserSearchSelector.js +163 -0
  34. package/dist/cjs/global-account/react/components/SingleUserSearchSelector/index.d.ts +2 -0
  35. package/dist/cjs/global-account/react/components/SingleUserSearchSelector/index.js +5 -0
  36. package/dist/cjs/global-account/react/components/WalletImage/WalletImage.d.ts +1 -1
  37. package/dist/cjs/global-account/react/components/index.d.ts +2 -0
  38. package/dist/cjs/global-account/react/components/index.js +6 -3
  39. package/dist/cjs/global-account/react/hooks/index.d.ts +2 -1
  40. package/dist/cjs/global-account/react/hooks/index.js +5 -1
  41. package/dist/cjs/global-account/react/hooks/useAuthentication.js +5 -2
  42. package/dist/cjs/global-account/react/hooks/useProfile.js +4 -23
  43. package/dist/cjs/global-account/react/hooks/useSimBalance.d.ts +7 -0
  44. package/dist/cjs/global-account/react/hooks/useSimBalance.js +43 -11
  45. package/dist/cjs/global-account/react/hooks/useSimCollectibles.d.ts +45 -0
  46. package/dist/cjs/global-account/react/hooks/useSimCollectibles.js +190 -0
  47. package/dist/cjs/global-account/react/stores/index.d.ts +0 -1
  48. package/dist/cjs/global-account/react/stores/index.js +1 -3
  49. package/dist/cjs/global-account/react/stores/useModalStore.d.ts +63 -1
  50. package/dist/cjs/global-account/react/stores/useModalStore.js +3 -0
  51. package/dist/cjs/global-account/react/utils/profileApi.d.ts +13 -0
  52. package/dist/cjs/global-account/react/utils/profileApi.js +29 -0
  53. package/dist/cjs/global-account/react/utils/simdune.d.ts +7 -0
  54. package/dist/cjs/global-account/react/utils/simdune.js +21 -0
  55. package/dist/esm/anyspend/react/components/AnySpend.js +1 -1
  56. package/dist/esm/anyspend/react/components/AnySpendDeposit.d.ts +15 -10
  57. package/dist/esm/anyspend/react/components/AnySpendDeposit.js +23 -15
  58. package/dist/esm/anyspend/react/components/QRDeposit.js +32 -6
  59. package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.js +10 -3
  60. package/dist/esm/anyspend/react/components/common/GasIndicator.d.ts +1 -1
  61. package/dist/esm/anyspend/react/components/common/GasIndicator.js +7 -17
  62. package/dist/esm/anyspend/react/components/common/TokenBalance.js +16 -5
  63. package/dist/esm/anyspend/react/components/common/TransferResultScreen.d.ts +22 -0
  64. package/dist/esm/anyspend/react/components/common/TransferResultScreen.js +22 -0
  65. package/dist/esm/anyspend/react/hooks/index.d.ts +1 -0
  66. package/dist/esm/anyspend/react/hooks/index.js +1 -0
  67. package/dist/esm/anyspend/react/hooks/useWatchTransfer.d.ts +41 -0
  68. package/dist/esm/anyspend/react/hooks/useWatchTransfer.js +72 -0
  69. package/dist/esm/anyspend/react/providers/AnyspendProvider.js +1 -2
  70. package/dist/esm/anyspend/utils/address.d.ts +5 -0
  71. package/dist/esm/anyspend/utils/address.js +7 -0
  72. package/dist/esm/global-account/react/components/AccountAssets/AccountAssets.js +7 -3
  73. package/dist/esm/global-account/react/components/B3DynamicModal.js +5 -15
  74. package/dist/esm/global-account/react/components/B3Provider/B3ConfigProvider.d.ts +31 -0
  75. package/dist/esm/global-account/react/components/B3Provider/B3ConfigProvider.js +33 -0
  76. package/dist/esm/global-account/react/components/B3Provider/B3Provider.d.ts +4 -1
  77. package/dist/esm/global-account/react/components/B3Provider/B3Provider.js +3 -31
  78. package/dist/esm/global-account/react/components/B3Provider/B3Provider.native.js +3 -30
  79. package/dist/esm/global-account/react/components/B3Provider/LocalSDKProvider.d.ts +6 -1
  80. package/dist/esm/global-account/react/components/B3Provider/LocalSDKProvider.js +5 -1
  81. package/dist/esm/global-account/react/components/B3Provider/useB3.d.ts +1 -12
  82. package/dist/esm/global-account/react/components/B3Provider/useB3Config.d.ts +1 -17
  83. package/dist/esm/global-account/react/components/B3Provider/useB3Config.js +1 -20
  84. package/dist/esm/global-account/react/components/ManageAccount/NFTContent.js +3 -3
  85. package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +25 -5
  86. package/dist/esm/global-account/react/components/SingleUserSearchSelector/SingleUserSearchSelector.d.ts +64 -0
  87. package/dist/esm/global-account/react/components/SingleUserSearchSelector/SingleUserSearchSelector.js +160 -0
  88. package/dist/esm/global-account/react/components/SingleUserSearchSelector/index.d.ts +2 -0
  89. package/dist/esm/global-account/react/components/SingleUserSearchSelector/index.js +1 -0
  90. package/dist/esm/global-account/react/components/WalletImage/WalletImage.d.ts +1 -1
  91. package/dist/esm/global-account/react/components/index.d.ts +2 -0
  92. package/dist/esm/global-account/react/components/index.js +2 -0
  93. package/dist/esm/global-account/react/hooks/index.d.ts +2 -1
  94. package/dist/esm/global-account/react/hooks/index.js +2 -1
  95. package/dist/esm/global-account/react/hooks/useAuthentication.js +5 -2
  96. package/dist/esm/global-account/react/hooks/useProfile.js +1 -20
  97. package/dist/esm/global-account/react/hooks/useSimBalance.d.ts +7 -0
  98. package/dist/esm/global-account/react/hooks/useSimBalance.js +42 -11
  99. package/dist/esm/global-account/react/hooks/useSimCollectibles.d.ts +45 -0
  100. package/dist/esm/global-account/react/hooks/useSimCollectibles.js +187 -0
  101. package/dist/esm/global-account/react/stores/index.d.ts +0 -1
  102. package/dist/esm/global-account/react/stores/index.js +0 -1
  103. package/dist/esm/global-account/react/stores/useModalStore.d.ts +63 -1
  104. package/dist/esm/global-account/react/stores/useModalStore.js +3 -0
  105. package/dist/esm/global-account/react/utils/profileApi.d.ts +13 -0
  106. package/dist/esm/global-account/react/utils/profileApi.js +25 -0
  107. package/dist/esm/global-account/react/utils/simdune.d.ts +7 -0
  108. package/dist/esm/global-account/react/utils/simdune.js +17 -0
  109. package/dist/styles/index.css +1 -1
  110. package/dist/types/anyspend/react/components/AnySpendDeposit.d.ts +15 -10
  111. package/dist/types/anyspend/react/components/common/GasIndicator.d.ts +1 -1
  112. package/dist/types/anyspend/react/components/common/TransferResultScreen.d.ts +22 -0
  113. package/dist/types/anyspend/react/hooks/index.d.ts +1 -0
  114. package/dist/types/anyspend/react/hooks/useWatchTransfer.d.ts +41 -0
  115. package/dist/types/anyspend/utils/address.d.ts +5 -0
  116. package/dist/types/global-account/react/components/B3Provider/B3ConfigProvider.d.ts +31 -0
  117. package/dist/types/global-account/react/components/B3Provider/B3Provider.d.ts +4 -1
  118. package/dist/types/global-account/react/components/B3Provider/LocalSDKProvider.d.ts +6 -1
  119. package/dist/types/global-account/react/components/B3Provider/useB3.d.ts +1 -12
  120. package/dist/types/global-account/react/components/B3Provider/useB3Config.d.ts +1 -17
  121. package/dist/types/global-account/react/components/SingleUserSearchSelector/SingleUserSearchSelector.d.ts +64 -0
  122. package/dist/types/global-account/react/components/SingleUserSearchSelector/index.d.ts +2 -0
  123. package/dist/types/global-account/react/components/WalletImage/WalletImage.d.ts +1 -1
  124. package/dist/types/global-account/react/components/index.d.ts +2 -0
  125. package/dist/types/global-account/react/hooks/index.d.ts +2 -1
  126. package/dist/types/global-account/react/hooks/useSimBalance.d.ts +7 -0
  127. package/dist/types/global-account/react/hooks/useSimCollectibles.d.ts +45 -0
  128. package/dist/types/global-account/react/stores/index.d.ts +0 -1
  129. package/dist/types/global-account/react/stores/useModalStore.d.ts +63 -1
  130. package/dist/types/global-account/react/utils/profileApi.d.ts +13 -0
  131. package/dist/types/global-account/react/utils/simdune.d.ts +7 -0
  132. package/package.json +6 -1
  133. package/src/anyspend/react/components/AnySpend.tsx +1 -0
  134. package/src/anyspend/react/components/AnySpendDeposit.tsx +60 -42
  135. package/src/anyspend/react/components/QRDeposit.tsx +57 -5
  136. package/src/anyspend/react/components/common/CryptoPaymentMethod.tsx +13 -3
  137. package/src/anyspend/react/components/common/GasIndicator.tsx +11 -30
  138. package/src/anyspend/react/components/common/TokenBalance.tsx +17 -5
  139. package/src/anyspend/react/components/common/TransferResultScreen.tsx +107 -0
  140. package/src/anyspend/react/hooks/index.ts +1 -0
  141. package/src/anyspend/react/hooks/useWatchTransfer.ts +114 -0
  142. package/src/anyspend/react/providers/AnyspendProvider.tsx +2 -5
  143. package/src/anyspend/utils/address.ts +13 -0
  144. package/src/global-account/react/components/AccountAssets/AccountAssets.tsx +25 -13
  145. package/src/global-account/react/components/B3DynamicModal.tsx +5 -17
  146. package/src/global-account/react/components/B3Provider/B3ConfigProvider.tsx +84 -0
  147. package/src/global-account/react/components/B3Provider/B3Provider.native.tsx +28 -36
  148. package/src/global-account/react/components/B3Provider/B3Provider.tsx +31 -39
  149. package/src/global-account/react/components/B3Provider/LocalSDKProvider.tsx +11 -0
  150. package/src/global-account/react/components/B3Provider/useB3Config.ts +1 -21
  151. package/src/global-account/react/components/ManageAccount/NFTContent.tsx +4 -4
  152. package/src/global-account/react/components/SignInWithB3/SignInWithB3Flow.tsx +29 -6
  153. package/src/global-account/react/components/SingleUserSearchSelector/README.md +266 -0
  154. package/src/global-account/react/components/SingleUserSearchSelector/SingleUserSearchSelector.tsx +330 -0
  155. package/src/global-account/react/components/SingleUserSearchSelector/index.ts +2 -0
  156. package/src/global-account/react/components/index.ts +7 -0
  157. package/src/global-account/react/hooks/index.ts +2 -1
  158. package/src/global-account/react/hooks/useAuthentication.ts +6 -2
  159. package/src/global-account/react/hooks/useProfile.ts +1 -32
  160. package/src/global-account/react/hooks/useSimBalance.ts +49 -12
  161. package/src/global-account/react/hooks/useSimCollectibles.ts +238 -0
  162. package/src/global-account/react/stores/index.ts +0 -1
  163. package/src/global-account/react/stores/useModalStore.ts +67 -1
  164. package/src/global-account/react/utils/profileApi.ts +38 -0
  165. package/src/global-account/react/utils/simdune.ts +20 -0
  166. package/dist/cjs/global-account/react/stores/configStore.d.ts +0 -24
  167. package/dist/cjs/global-account/react/stores/configStore.js +0 -30
  168. package/dist/esm/global-account/react/stores/configStore.d.ts +0 -24
  169. package/dist/esm/global-account/react/stores/configStore.js +0 -27
  170. package/dist/types/global-account/react/stores/configStore.d.ts +0 -24
  171. package/src/global-account/react/stores/configStore.ts +0 -51
@@ -0,0 +1,114 @@
1
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
+ import { formatUnits } from "viem";
3
+ import { useBalance } from "wagmi";
4
+ import { isNativeToken } from "../../utils";
5
+
6
+ export interface TransferResult {
7
+ amount: string;
8
+ formattedAmount: string;
9
+ txHash?: string;
10
+ timestamp: number;
11
+ }
12
+
13
+ export interface UseWatchTransferProps {
14
+ /** Address to watch for incoming transfers */
15
+ address: string;
16
+ /** Chain ID to watch on */
17
+ chainId: number;
18
+ /** Token address (use zero address for native token) */
19
+ tokenAddress: string;
20
+ /** Token decimals */
21
+ tokenDecimals: number;
22
+ /** Whether watching is enabled */
23
+ enabled?: boolean;
24
+ /** Callback when a transfer is detected */
25
+ onTransferDetected?: (result: TransferResult) => void;
26
+ }
27
+
28
+ /**
29
+ * Hook to watch for incoming transfers to an address by monitoring balance changes.
30
+ * When a transfer is detected (balance increases), it captures the amount and notifies.
31
+ */
32
+ export function useWatchTransfer({
33
+ address,
34
+ chainId,
35
+ tokenAddress,
36
+ tokenDecimals,
37
+ enabled = true,
38
+ onTransferDetected,
39
+ }: UseWatchTransferProps) {
40
+ const [transferResult, setTransferResult] = useState<TransferResult | null>(null);
41
+ const [isWatching, setIsWatching] = useState(false);
42
+ const initialBalanceRef = useRef<bigint | null>(null);
43
+ const transferDetectedRef = useRef(false);
44
+
45
+ const isNative = isNativeToken(tokenAddress);
46
+ // Get current balance
47
+ const { data: balanceData, refetch: refetchBalance } = useBalance({
48
+ address: address as `0x${string}`,
49
+ chainId,
50
+ token: isNative ? undefined : (tokenAddress as `0x${string}`),
51
+ query: {
52
+ enabled: enabled && !!address,
53
+ refetchInterval: 3000,
54
+ },
55
+ });
56
+
57
+ // Initialize or update the initial balance
58
+ useEffect(() => {
59
+ if (balanceData && initialBalanceRef.current === null && enabled) {
60
+ initialBalanceRef.current = balanceData.value;
61
+ setIsWatching(true);
62
+ }
63
+ }, [balanceData, enabled]);
64
+
65
+ // Check for balance increase (transfer detected)
66
+ useEffect(() => {
67
+ if (!enabled || transferDetectedRef.current || initialBalanceRef.current === null || !balanceData) {
68
+ return;
69
+ }
70
+
71
+ const currentBalance = balanceData.value;
72
+ const initialBalance = initialBalanceRef.current;
73
+
74
+ if (currentBalance > initialBalance) {
75
+ const transferAmount = currentBalance - initialBalance;
76
+ const formattedAmount = formatUnits(transferAmount, tokenDecimals);
77
+
78
+ const result: TransferResult = {
79
+ amount: transferAmount.toString(),
80
+ formattedAmount,
81
+ timestamp: Date.now(),
82
+ };
83
+
84
+ transferDetectedRef.current = true;
85
+ setTransferResult(result);
86
+ setIsWatching(false);
87
+ onTransferDetected?.(result);
88
+ }
89
+ }, [balanceData, enabled, tokenDecimals, onTransferDetected]);
90
+
91
+ // Reset function to start watching again
92
+ const reset = useCallback(() => {
93
+ transferDetectedRef.current = false;
94
+ initialBalanceRef.current = null;
95
+ setTransferResult(null);
96
+ setIsWatching(false);
97
+ }, []);
98
+
99
+ return useMemo(
100
+ () => ({
101
+ /** Whether currently watching for transfers */
102
+ isWatching,
103
+ /** The detected transfer result, if any */
104
+ transferResult,
105
+ /** Whether a transfer has been detected */
106
+ hasTransfer: transferResult !== null,
107
+ /** Reset and start watching again */
108
+ reset,
109
+ /** Manually refetch balance */
110
+ refetchBalance,
111
+ }),
112
+ [isWatching, transferResult, reset, refetchBalance],
113
+ );
114
+ }
@@ -1,6 +1,5 @@
1
1
  "use client";
2
2
 
3
- import { TooltipProvider } from "@b3dotfun/sdk/global-account/react";
4
3
  import { ReactNode } from "react";
5
4
  import { FeatureFlags, FeatureFlagsProvider } from "../contexts/FeatureFlagsContext";
6
5
  import { StripeRedirectHandler } from "./StripeRedirectHandler";
@@ -36,10 +35,8 @@ interface AnyspendProviderProps {
36
35
  export const AnyspendProvider = function AnyspendProvider({ children, featureFlags }: AnyspendProviderProps) {
37
36
  return (
38
37
  <FeatureFlagsProvider featureFlags={featureFlags}>
39
- <TooltipProvider>
40
- <StripeRedirectHandler />
41
- {children}
42
- </TooltipProvider>
38
+ <StripeRedirectHandler />
39
+ {children}
43
40
  </FeatureFlagsProvider>
44
41
  );
45
42
  };
@@ -38,3 +38,16 @@ export function eqci(a: string | null | undefined, b: string | null | undefined)
38
38
  if (!a || !b) return false;
39
39
  return a.toLowerCase() === b.toLowerCase();
40
40
  }
41
+
42
+ /**
43
+ * Check if source and destination represent the same token on the same chain.
44
+ * When true, this is a pure transfer (no swap/bridge needed).
45
+ */
46
+ export function isSameChainAndToken(
47
+ sourceChainId: number,
48
+ sourceTokenAddress: string,
49
+ destinationChainId: number,
50
+ destinationTokenAddress: string,
51
+ ): boolean {
52
+ return sourceChainId === destinationChainId && eqci(sourceTokenAddress, destinationTokenAddress);
53
+ }
@@ -38,6 +38,11 @@ export function AccountAssets({ nfts, isLoading }: AccountAssetsProps) {
38
38
  const [expandedCollections, setExpandedCollections] = useState<Set<string>>(
39
39
  () => new Set(collections.map(c => c.collection_id)),
40
40
  );
41
+ const [failedImages, setFailedImages] = useState<Set<string>>(() => new Set());
42
+
43
+ const handleImageError = (imageId: string) => {
44
+ setFailedImages(prev => new Set(prev).add(imageId));
45
+ };
41
46
 
42
47
  if (isLoading) {
43
48
  return (
@@ -72,7 +77,7 @@ export function AccountAssets({ nfts, isLoading }: AccountAssetsProps) {
72
77
  };
73
78
 
74
79
  return (
75
- <div className="flex flex-col gap-3 px-4">
80
+ <div className="flex flex-col gap-3">
76
81
  {collections.map(collection => {
77
82
  const isExpanded = expandedCollections.has(collection.collection_id);
78
83
 
@@ -84,11 +89,12 @@ export function AccountAssets({ nfts, isLoading }: AccountAssetsProps) {
84
89
  className="flex w-full items-center justify-between"
85
90
  >
86
91
  <div className="flex items-center gap-1">
87
- {collection.collection_image && (
92
+ {collection.collection_image && !failedImages.has(`collection-${collection.collection_id}`) && (
88
93
  <img
89
94
  src={collection.collection_image}
90
95
  alt={collection.collection_name}
91
96
  className="h-5 w-5 shrink-0 rounded object-cover"
97
+ onError={() => handleImageError(`collection-${collection.collection_id}`)}
92
98
  />
93
99
  )}
94
100
  <p className="font-neue-montreal-medium text-[14px] text-[#3f3f46]">
@@ -115,17 +121,23 @@ export function AccountAssets({ nfts, isLoading }: AccountAssetsProps) {
115
121
  {isExpanded && (
116
122
  <div className="flex gap-3 overflow-x-auto">
117
123
  {collection.nfts.map(nft => (
118
- <div key={nft.nft_id} className="relative h-[98px] w-[98px] shrink-0 overflow-hidden rounded-lg">
119
- <img
120
- src={
121
- nft.previews?.image_medium_url ||
122
- nft.extra_metadata?.image_original_url ||
123
- nft.collection?.image_url ||
124
- ""
125
- }
126
- alt={nft.name || "NFT"}
127
- className="h-full w-full object-cover"
128
- />
124
+ <div
125
+ key={nft.nft_id}
126
+ className="bg-b3-react-muted relative h-[98px] w-[98px] shrink-0 overflow-hidden rounded-lg"
127
+ >
128
+ {!failedImages.has(nft.nft_id) && (
129
+ <img
130
+ src={
131
+ nft.previews?.image_medium_url ||
132
+ nft.extra_metadata?.image_original_url ||
133
+ nft.collection?.image_url ||
134
+ ""
135
+ }
136
+ alt={nft.name || "NFT"}
137
+ className="h-full w-full object-cover"
138
+ onError={() => handleImageError(nft.nft_id)}
139
+ />
140
+ )}
129
141
  </div>
130
142
  ))}
131
143
  </div>
@@ -10,16 +10,15 @@ import {
10
10
  AnySpendTournament,
11
11
  OrderHistory,
12
12
  } from "@b3dotfun/sdk/anyspend/react";
13
+ import { AnySpendDeposit } from "@b3dotfun/sdk/anyspend/react/components/AnySpendDeposit";
13
14
  import { AnySpendDepositHype } from "@b3dotfun/sdk/anyspend/react/components/AnyspendDepositHype";
14
15
  import { AnySpendDepositUpside } from "@b3dotfun/sdk/anyspend/react/components/AnySpendDepositUpside";
15
16
  import { AnySpendStakeUpside } from "@b3dotfun/sdk/anyspend/react/components/AnySpendStakeUpside";
16
17
  import { AnySpendStakeUpsideExactIn } from "@b3dotfun/sdk/anyspend/react/components/AnySpendStakeUpsideExactIn";
17
- import { useB3Config, useGlobalAccount, useIsMobile, useModalStore } from "@b3dotfun/sdk/global-account/react";
18
+ import { useB3Config, useIsMobile, useModalStore } from "@b3dotfun/sdk/global-account/react";
18
19
  import { cn } from "@b3dotfun/sdk/shared/utils/cn";
19
20
  import { debugB3React } from "@b3dotfun/sdk/shared/utils/debug";
20
21
  import { AnimatePresence, motion } from "framer-motion";
21
- import { useEffect, useRef } from "react";
22
- import { useSetActiveWallet } from "thirdweb/react";
23
22
  import { AvatarEditor } from "./AvatarEditor/AvatarEditor";
24
23
  import { Deposit } from "./Deposit/Deposit";
25
24
  import { LinkAccount } from "./LinkAccount/LinkAccount";
@@ -43,22 +42,8 @@ export function B3DynamicModal() {
43
42
  const navigateBack = useModalStore(state => state.navigateBack);
44
43
  const { theme } = useB3Config();
45
44
  const isMobile = useIsMobile();
46
- const prevIsOpenRef = useRef(isOpen);
47
- const { wallet } = useGlobalAccount();
48
- const setActiveWallet = useSetActiveWallet();
49
45
  const { toasts, removeToast } = useToastContext();
50
46
 
51
- // anyspend cleanup global account chnages by setting account back
52
- useEffect(() => {
53
- if (prevIsOpenRef.current && !isOpen) {
54
- if (wallet) {
55
- setActiveWallet(wallet);
56
- }
57
- }
58
-
59
- prevIsOpenRef.current = isOpen;
60
- }, [isOpen, wallet, setActiveWallet]);
61
-
62
47
  // Define arrays for different modal type groups
63
48
  const fullWidthTypes = [
64
49
  "anySpend",
@@ -81,6 +66,7 @@ export function B3DynamicModal() {
81
66
  "deposit",
82
67
  "send",
83
68
  "notifications",
69
+ "anySpendDeposit",
84
70
  ];
85
71
 
86
72
  const freestyleTypes = [
@@ -169,6 +155,8 @@ export function B3DynamicModal() {
169
155
  return <AnySpendDepositHype {...contentType} mode="modal" />;
170
156
  case "anySpendCollectorClubPurchase":
171
157
  return <AnySpendCollectorClubPurchase {...contentType} mode="modal" />;
158
+ case "anySpendDeposit":
159
+ return <AnySpendDeposit {...contentType} mode="modal" />;
172
160
  case "avatarEditor":
173
161
  return <AvatarEditor onSetAvatar={contentType.onSuccess} />;
174
162
  case "deposit":
@@ -0,0 +1,84 @@
1
+ import { CreateOnrampOrderParams } from "@b3dotfun/sdk/anyspend/react/hooks/useAnyspendCreateOnrampOrder";
2
+ import { CreateOrderParams } from "@b3dotfun/sdk/anyspend/react/hooks/useAnyspendCreateOrder";
3
+ import { PermissionsConfig } from "@b3dotfun/sdk/global-account/types/permissions";
4
+ import { createContext, useContext } from "react";
5
+ import { Account } from "thirdweb/wallets";
6
+ import { ClientType } from "../../../client-manager";
7
+
8
+ /**
9
+ * Default permissions configuration for B3 provider
10
+ */
11
+ const DEFAULT_PERMISSIONS: PermissionsConfig = {
12
+ approvedTargets: ["0xa8e42121e318e3D3BeD7f5969AF6D360045317DD"],
13
+ nativeTokenLimitPerTransaction: 0.1,
14
+ startDate: new Date(),
15
+ endDate: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365), // 1 year from now
16
+ };
17
+
18
+ export interface B3ConfigContextType {
19
+ accountOverride?: Account;
20
+ automaticallySetFirstEoa: boolean;
21
+ environment: "development" | "production";
22
+ defaultPermissions: PermissionsConfig;
23
+ theme: "light" | "dark";
24
+ clientType: ClientType;
25
+ partnerId: string;
26
+ stripePublishableKey?: string;
27
+ createClientReferenceId?: (params: CreateOrderParams | CreateOnrampOrderParams) => Promise<string>;
28
+ enableTurnkey: boolean;
29
+ }
30
+
31
+ const B3ConfigContext = createContext<B3ConfigContextType | null>(null);
32
+
33
+ export function B3ConfigProvider({
34
+ children,
35
+ accountOverride,
36
+ environment = "development",
37
+ defaultPermissions = DEFAULT_PERMISSIONS,
38
+ automaticallySetFirstEoa = false,
39
+ theme = "light",
40
+ clientType = "rest",
41
+ partnerId,
42
+ stripePublishableKey,
43
+ createClientReferenceId,
44
+ enableTurnkey = false,
45
+ }: {
46
+ children: React.ReactNode;
47
+ accountOverride?: Account;
48
+ environment?: "development" | "production";
49
+ defaultPermissions?: PermissionsConfig;
50
+ automaticallySetFirstEoa?: boolean;
51
+ theme?: "light" | "dark";
52
+ clientType?: ClientType;
53
+ partnerId: string;
54
+ stripePublishableKey?: string;
55
+ createClientReferenceId?: (params: CreateOrderParams | CreateOnrampOrderParams) => Promise<string>;
56
+ enableTurnkey?: boolean;
57
+ }) {
58
+ return (
59
+ <B3ConfigContext.Provider
60
+ value={{
61
+ accountOverride,
62
+ environment,
63
+ defaultPermissions,
64
+ automaticallySetFirstEoa,
65
+ theme,
66
+ clientType,
67
+ partnerId,
68
+ stripePublishableKey,
69
+ createClientReferenceId,
70
+ enableTurnkey,
71
+ }}
72
+ >
73
+ {children}
74
+ </B3ConfigContext.Provider>
75
+ );
76
+ }
77
+
78
+ export function useB3Config(): B3ConfigContextType {
79
+ const context = useContext(B3ConfigContext);
80
+ if (!context) {
81
+ throw new Error("useB3Config must be used within a B3ConfigProvider");
82
+ }
83
+ return context;
84
+ }
@@ -1,15 +1,14 @@
1
1
  import { PermissionsConfig } from "@b3dotfun/sdk/global-account/types/permissions";
2
2
  import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
3
- import { useEffect } from "react";
4
3
  import { ThirdwebProvider } from "thirdweb/react";
5
4
  import { Account, Wallet } from "thirdweb/wallets";
6
5
 
7
6
  import { ClientType } from "../../../client-manager";
8
7
 
9
8
  import { WagmiProvider } from "wagmi";
10
- import { useB3ConfigStore } from "../../stores/configStore";
11
9
  import { createWagmiConfig } from "../../utils/createWagmiConfig";
12
10
  import AuthenticationProvider from "./AuthenticationProvider";
11
+ import { B3ConfigProvider } from "./B3ConfigProvider";
13
12
  import { LocalSDKProvider } from "./LocalSDKProvider";
14
13
 
15
14
  // Create queryClient instance
@@ -39,28 +38,23 @@ export function B3Provider({
39
38
  onConnect?: (wallet: Wallet, b3Jwt: string) => void | Promise<void>;
40
39
  defaultPermissions?: PermissionsConfig;
41
40
  }) {
42
- const setConfig = useB3ConfigStore(state => state.setConfig);
43
-
44
- // Initialize config store on mount - props are static and never change
45
- useEffect(() => {
46
- setConfig({
47
- accountOverride,
48
- environment: environment ?? "development",
49
- automaticallySetFirstEoa: false,
50
- theme,
51
- clientType,
52
- partnerId,
53
- defaultPermissions,
54
- });
55
- }, []); // eslint-disable-line react-hooks/exhaustive-deps
56
-
57
41
  return (
58
42
  <ThirdwebProvider>
59
43
  <LocalSDKProvider onConnectCallback={onConnect}>
60
- {/* <RelayKitProviderWrapper> */}
61
- {children}
62
- <AuthenticationProvider partnerId={partnerId} automaticallySetFirstEoa={false} />
63
- {/* </RelayKitProviderWrapper> */}
44
+ <B3ConfigProvider
45
+ accountOverride={accountOverride}
46
+ environment={environment}
47
+ automaticallySetFirstEoa={false}
48
+ theme={theme}
49
+ clientType={clientType}
50
+ partnerId={partnerId}
51
+ defaultPermissions={defaultPermissions}
52
+ >
53
+ {/* <RelayKitProviderWrapper> */}
54
+ {children}
55
+ <AuthenticationProvider partnerId={partnerId} automaticallySetFirstEoa={false} />
56
+ {/* </RelayKitProviderWrapper> */}
57
+ </B3ConfigProvider>
64
58
  </LocalSDKProvider>
65
59
  </ThirdwebProvider>
66
60
  );
@@ -88,25 +82,23 @@ export function InnerProvider({
88
82
  partnerId: string;
89
83
  rpcUrls?: Record<number, string>;
90
84
  }) {
91
- const setConfig = useB3ConfigStore(state => state.setConfig);
92
85
  const wagmiConfig = createWagmiConfig({ partnerId, rpcUrls });
93
86
 
94
- // Initialize config store on mount - props are static and never change
95
- useEffect(() => {
96
- setConfig({
97
- accountOverride,
98
- environment: environment ?? "development",
99
- automaticallySetFirstEoa: false,
100
- theme,
101
- clientType,
102
- partnerId,
103
- defaultPermissions,
104
- });
105
- }, []); // eslint-disable-line react-hooks/exhaustive-deps
106
-
107
87
  return (
108
88
  <WagmiProvider config={wagmiConfig}>
109
- <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
89
+ <QueryClientProvider client={queryClient}>
90
+ <B3ConfigProvider
91
+ accountOverride={accountOverride}
92
+ environment={environment}
93
+ automaticallySetFirstEoa={false}
94
+ theme={theme}
95
+ clientType={clientType}
96
+ partnerId={partnerId}
97
+ defaultPermissions={defaultPermissions}
98
+ >
99
+ {children}
100
+ </B3ConfigProvider>
101
+ </QueryClientProvider>
110
102
  </WagmiProvider>
111
103
  );
112
104
  }
@@ -1,3 +1,4 @@
1
+ import { Users } from "@b3dotfun/b3-api";
1
2
  import { CreateOnrampOrderParams } from "@b3dotfun/sdk/anyspend/react/hooks/useAnyspendCreateOnrampOrder";
2
3
  import { CreateOrderParams } from "@b3dotfun/sdk/anyspend/react/hooks/useAnyspendCreateOrder";
3
4
  import { RelayKitProviderWrapper, TooltipProvider } from "@b3dotfun/sdk/global-account/react";
@@ -11,10 +12,10 @@ import { ThirdwebProvider } from "thirdweb/react";
11
12
  import { Account, Wallet } from "thirdweb/wallets";
12
13
  import { CreateConnectorFn, WagmiProvider } from "wagmi";
13
14
  import { ClientType, setClientType } from "../../../client-manager";
14
- import { useB3ConfigStore } from "../../stores/configStore";
15
15
  import { StyleRoot } from "../StyleRoot";
16
16
  import { setToastContext, ToastProvider, useToastContext } from "../Toast/index";
17
17
  import AuthenticationProvider from "./AuthenticationProvider";
18
+ import { B3ConfigProvider } from "./B3ConfigProvider";
18
19
  import { LocalSDKProvider } from "./LocalSDKProvider";
19
20
 
20
21
  // Create queryClient instance
@@ -37,11 +38,13 @@ export function B3Provider({
37
38
  partnerId,
38
39
  stripePublishableKey,
39
40
  onConnect,
41
+ onLogout,
40
42
  connectors,
41
43
  overrideDefaultConnectors = false,
42
44
  createClientReferenceId,
43
45
  enableTurnkey = false,
44
46
  defaultPermissions,
47
+ onTurnkeyConnect,
45
48
  }: {
46
49
  theme: "light" | "dark";
47
50
  children: React.ReactNode;
@@ -59,42 +62,14 @@ export function B3Provider({
59
62
  /** Partner-specific Stripe publishable key. If not provided, uses default B3 Stripe account. */
60
63
  stripePublishableKey?: string;
61
64
  onConnect?: (wallet: Wallet, b3Jwt: string) => void | Promise<void>;
65
+ onLogout?: () => void | Promise<void>;
62
66
  connectors?: CreateConnectorFn[];
63
67
  overrideDefaultConnectors?: boolean;
64
68
  createClientReferenceId?: (params: CreateOrderParams | CreateOnrampOrderParams) => Promise<string>;
65
69
  enableTurnkey?: boolean;
66
70
  defaultPermissions?: PermissionsConfig;
71
+ onTurnkeyConnect?: (user: Users) => void | Promise<void>;
67
72
  }) {
68
- const setConfig = useB3ConfigStore(state => state.setConfig);
69
-
70
- // Initialize config store on mount
71
- useEffect(() => {
72
- setConfig({
73
- accountOverride,
74
- environment: environment ?? "development",
75
- automaticallySetFirstEoa: !!automaticallySetFirstEoa,
76
- theme,
77
- clientType,
78
- partnerId,
79
- stripePublishableKey,
80
- createClientReferenceId,
81
- enableTurnkey,
82
- defaultPermissions,
83
- });
84
- }, [
85
- accountOverride,
86
- environment,
87
- automaticallySetFirstEoa,
88
- theme,
89
- clientType,
90
- partnerId,
91
- stripePublishableKey,
92
- createClientReferenceId,
93
- enableTurnkey,
94
- defaultPermissions,
95
- setConfig,
96
- ]); // eslint-disable-line react-hooks/exhaustive-deps
97
-
98
73
  // Initialize Google Analytics on mount
99
74
  useEffect(() => {
100
75
  loadGA4Script();
@@ -116,14 +91,31 @@ export function B3Provider({
116
91
  <QueryClientProvider client={queryClient}>
117
92
  <TooltipProvider>
118
93
  <ToastProvider>
119
- <LocalSDKProvider onConnectCallback={onConnect}>
120
- <ToastContextConnector />
121
- <RelayKitProviderWrapper simDuneApiKey={simDuneApiKey}>
122
- {children}
123
- {/* For the modal https://github.com/b3-fun/b3/blob/main/packages/sdk/src/global-account/react/components/ui/dialog.tsx#L46 */}
124
- <StyleRoot id="b3-root" />
125
- </RelayKitProviderWrapper>
126
- <AuthenticationProvider partnerId={partnerId} automaticallySetFirstEoa={!!automaticallySetFirstEoa} />
94
+ <LocalSDKProvider
95
+ onConnectCallback={onConnect}
96
+ onLogoutCallback={onLogout}
97
+ onTurnkeyConnect={onTurnkeyConnect}
98
+ >
99
+ <B3ConfigProvider
100
+ accountOverride={accountOverride}
101
+ environment={environment}
102
+ automaticallySetFirstEoa={!!automaticallySetFirstEoa}
103
+ theme={theme}
104
+ clientType={clientType}
105
+ partnerId={partnerId}
106
+ stripePublishableKey={stripePublishableKey}
107
+ createClientReferenceId={createClientReferenceId}
108
+ enableTurnkey={enableTurnkey}
109
+ defaultPermissions={defaultPermissions}
110
+ >
111
+ <ToastContextConnector />
112
+ <RelayKitProviderWrapper simDuneApiKey={simDuneApiKey}>
113
+ {children}
114
+ {/* For the modal https://github.com/b3-fun/b3/blob/main/packages/sdk/src/global-account/react/components/ui/dialog.tsx#L46 */}
115
+ <StyleRoot id="b3-root" />
116
+ </RelayKitProviderWrapper>
117
+ <AuthenticationProvider partnerId={partnerId} automaticallySetFirstEoa={!!automaticallySetFirstEoa} />
118
+ </B3ConfigProvider>
127
119
  </LocalSDKProvider>
128
120
  </ToastProvider>
129
121
  </TooltipProvider>
@@ -1,3 +1,4 @@
1
+ import { Users } from "@b3dotfun/b3-api";
1
2
  import { createContext } from "react";
2
3
  import { Wallet } from "thirdweb/wallets";
3
4
 
@@ -7,10 +8,14 @@ import { Wallet } from "thirdweb/wallets";
7
8
  */
8
9
  export interface LocalSDKContextType {
9
10
  onConnectCallback?: (wallet: Wallet, b3Jwt: string) => void | Promise<void>;
11
+ onLogoutCallback?: () => void | Promise<void>;
12
+ onTurnkeyConnect?: (user: Users) => void | Promise<void>;
10
13
  }
11
14
 
12
15
  export const LocalSDKContext = createContext<LocalSDKContextType>({
13
16
  onConnectCallback: undefined,
17
+ onLogoutCallback: undefined,
18
+ onTurnkeyConnect: undefined,
14
19
  });
15
20
 
16
21
  /**
@@ -19,14 +24,20 @@ export const LocalSDKContext = createContext<LocalSDKContextType>({
19
24
  export function LocalSDKProvider({
20
25
  children,
21
26
  onConnectCallback,
27
+ onLogoutCallback,
28
+ onTurnkeyConnect,
22
29
  }: {
23
30
  children: React.ReactNode;
24
31
  onConnectCallback?: (wallet: Wallet, b3Jwt: string) => void | Promise<void>;
32
+ onLogoutCallback?: () => void | Promise<void>;
33
+ onTurnkeyConnect?: (user: Users) => void | Promise<void>;
25
34
  }) {
26
35
  return (
27
36
  <LocalSDKContext.Provider
28
37
  value={{
29
38
  onConnectCallback,
39
+ onLogoutCallback,
40
+ onTurnkeyConnect,
30
41
  }}
31
42
  >
32
43
  {children}
@@ -1,21 +1 @@
1
- import { useB3ConfigStore } from "../../stores/configStore";
2
-
3
- /**
4
- * Hook to access B3 configuration
5
- * Returns all config values from the Zustand store
6
- * Since config is static (set once at initialization), destructuring is fine here
7
- */
8
- export const useB3Config = () => {
9
- return useB3ConfigStore(state => ({
10
- automaticallySetFirstEoa: state.automaticallySetFirstEoa,
11
- environment: state.environment,
12
- theme: state.theme,
13
- clientType: state.clientType,
14
- partnerId: state.partnerId,
15
- createClientReferenceId: state.createClientReferenceId,
16
- enableTurnkey: state.enableTurnkey,
17
- stripePublishableKey: state.stripePublishableKey,
18
- defaultPermissions: state.defaultPermissions,
19
- accountOverride: state.accountOverride,
20
- }));
21
- };
1
+ export { useB3Config } from "./B3ConfigProvider";
@@ -1,6 +1,6 @@
1
1
  import { useActiveWallet } from "thirdweb/react";
2
2
  import { AccountAssets } from "..";
3
- import { useAccountAssets } from "../../hooks";
3
+ import { useSimCollectibles } from "../../hooks";
4
4
 
5
5
  const NFTContent = () => {
6
6
  // Get active wallet state
@@ -8,12 +8,12 @@ const NFTContent = () => {
8
8
  const activeAccount = activeWallet?.getAccount();
9
9
  const activeAddress = activeAccount?.address;
10
10
 
11
- const { data: nfts, isLoading } = useAccountAssets(activeAddress);
11
+ const { data: nfts, isLoading } = useSimCollectibles(activeAddress, [1, 8453], { filterSpam: true });
12
12
 
13
13
  return (
14
14
  <div style={{ minHeight: "100px" }}>
15
- {nfts?.nftResponse ? (
16
- <AccountAssets nfts={nfts.nftResponse} isLoading={isLoading} />
15
+ {nfts ? (
16
+ <AccountAssets nfts={nfts} isLoading={isLoading} />
17
17
  ) : (
18
18
  <div className="py-12 text-center text-gray-500">No NFTs found</div>
19
19
  )}