@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
@@ -39,7 +39,8 @@ export { useQueryBSMNT } from "./useQueryBSMNT";
39
39
  export { useRemoveSessionKey } from "./useRemoveSessionKey";
40
40
  export { useRouter } from "./useRouter";
41
41
  export { useSearchParamsSSR } from "./useSearchParamsSSR";
42
- export { useSimBalance, useSimSvmBalance } from "./useSimBalance";
42
+ export { useSimBalance, useSimSvmBalance, useSimTokenBalance } from "./useSimBalance";
43
+ export { useSimCollectibles } from "./useSimCollectibles";
43
44
  export { useSiwe } from "./useSiwe";
44
45
  export { useTokenBalance } from "./useTokenBalance";
45
46
  export { useTokenBalanceDirect } from "./useTokenBalanceDirect";
@@ -25,7 +25,7 @@ import { useUserQuery } from "./useUserQuery";
25
25
  const debug = debugB3React("useAuthentication");
26
26
 
27
27
  export function useAuthentication(partnerId: string) {
28
- const { onConnectCallback } = useContext(LocalSDKContext);
28
+ const { onConnectCallback, onLogoutCallback } = useContext(LocalSDKContext);
29
29
  const { disconnect } = useDisconnect();
30
30
  const wallets = useConnectedWallets();
31
31
  const activeWallet = useActiveWallet();
@@ -181,8 +181,12 @@ export function useAuthentication(partnerId: string) {
181
181
  setIsConnected(false);
182
182
  setUser();
183
183
  callback?.();
184
+
185
+ if (onLogoutCallback) {
186
+ await onLogoutCallback();
187
+ }
184
188
  },
185
- [activeWallet, disconnect, wallets, setIsAuthenticated, setUser, setIsConnected],
189
+ [activeWallet, disconnect, wallets, setIsAuthenticated, setUser, setIsConnected, onLogoutCallback],
186
190
  );
187
191
 
188
192
  const onConnect = useCallback(
@@ -1,4 +1,5 @@
1
1
  import { useQuery } from "@tanstack/react-query";
2
+ import { fetchProfile, PROFILES_API_URL } from "../utils/profileApi";
2
3
 
3
4
  // TypeScript interface for profile data
4
5
  export interface Profile {
@@ -37,38 +38,6 @@ export interface DisplayNameRequestBody {
37
38
  timestamp: number;
38
39
  }
39
40
 
40
- const PROFILES_API_URL = "https://profiles.b3.fun";
41
-
42
- async function fetchProfile({
43
- address,
44
- name,
45
- b3GlobalId,
46
- fresh = false,
47
- }: {
48
- address?: string;
49
- name?: string;
50
- b3GlobalId?: string;
51
- fresh?: boolean;
52
- }): Promise<CombinedProfile> {
53
- if (!address && !name && !b3GlobalId) {
54
- throw new Error("Either address or name or b3GlobalId must be provided");
55
- }
56
-
57
- const params = new URLSearchParams();
58
- if (address) params.append("address", address);
59
- if (name) params.append("name", name);
60
- if (b3GlobalId) params.append("b3GlobalId", b3GlobalId);
61
- if (fresh) params.append("fresh", "true");
62
-
63
- const response = await fetch(`${PROFILES_API_URL}?${params.toString()}`);
64
-
65
- if (!response.ok) {
66
- throw new Error(`Failed to fetch profile: ${response.statusText}`);
67
- }
68
-
69
- return response.json();
70
- }
71
-
72
41
  async function setProfilePreference({
73
42
  key,
74
43
  preferredType,
@@ -1,4 +1,5 @@
1
1
  import { useQuery } from "@tanstack/react-query";
2
+ import { buildSimduneUrl } from "../utils/simdune";
2
3
 
3
4
  export interface SimTokenMetadata {
4
5
  logo?: string;
@@ -60,11 +61,12 @@ async function fetchSimBalance(address: string, chainIdsParam: number[]): Promis
60
61
  if (!address) throw new Error("Address is required");
61
62
 
62
63
  const chainIds = chainIdsParam.length === 0 ? "mainnet" : chainIdsParam.join(",");
63
- let url = `https://simdune-api.sean-430.workers.dev/?url=https://api.sim.dune.com/v1/evm/balances/${address}?metadata=logo&chain_ids=${chainIds}&exclude_spam_tokens=true`;
64
- if (process.env.NEXT_PUBLIC_DEVMODE_SHARED_SECRET) {
65
- url += `&localkey=${process.env.NEXT_PUBLIC_DEVMODE_SHARED_SECRET}`;
66
- }
64
+ const queryParams = new URLSearchParams();
65
+ queryParams.append("metadata", "logo");
66
+ queryParams.append("chain_ids", chainIds);
67
+ queryParams.append("exclude_spam_tokens", "true");
67
68
 
69
+ const url = buildSimduneUrl(`/v1/evm/balances/${address}`, queryParams);
68
70
  const response = await fetch(url);
69
71
 
70
72
  if (!response.ok) {
@@ -75,6 +77,29 @@ async function fetchSimBalance(address: string, chainIdsParam: number[]): Promis
75
77
  return balanceData;
76
78
  }
77
79
 
80
+ async function fetchSimTokenBalance(
81
+ walletAddress: string,
82
+ tokenAddress: string,
83
+ chainId: number,
84
+ ): Promise<SimBalanceResponse> {
85
+ if (!walletAddress) throw new Error("Wallet address is required");
86
+ if (!tokenAddress) throw new Error("Token address is required");
87
+ if (!chainId) throw new Error("Chain ID is required");
88
+
89
+ const queryParams = new URLSearchParams();
90
+ queryParams.append("chain_ids", chainId.toString());
91
+
92
+ const url = buildSimduneUrl(`/v1/evm/balances/${walletAddress}/token/${tokenAddress}`, queryParams);
93
+ const response = await fetch(url);
94
+
95
+ if (!response.ok) {
96
+ throw new Error(`Failed to fetch token balance: ${response.statusText}`);
97
+ }
98
+
99
+ const balanceData: SimBalanceResponse = await response.json();
100
+ return balanceData;
101
+ }
102
+
78
103
  async function fetchSimSvmBalance(address: string, chains?: string[], limit?: number): Promise<SvmBalanceResponse> {
79
104
  if (!address) throw new Error("Address is required");
80
105
 
@@ -86,14 +111,7 @@ async function fetchSimSvmBalance(address: string, chains?: string[], limit?: nu
86
111
  queryParams.append("limit", limit.toString());
87
112
  }
88
113
 
89
- let url = `https://simdune-api.sean-430.workers.dev/?url=https://api.sim.dune.com/beta/svm/balances/${address}`;
90
- if (queryParams.toString()) {
91
- url += `?${queryParams.toString()}`;
92
- }
93
- if (process.env.NEXT_PUBLIC_LOCAL_SIMDUNE_KEY) {
94
- url += `${queryParams.toString() ? "&" : "?"}localkey=${process.env.NEXT_PUBLIC_LOCAL_SIMDUNE_KEY}`;
95
- }
96
-
114
+ const url = buildSimduneUrl(`/beta/svm/balances/${address}`, queryParams.toString() ? queryParams : undefined);
97
115
  const response = await fetch(url);
98
116
 
99
117
  if (!response.ok) {
@@ -125,3 +143,22 @@ export function useSimSvmBalance(address?: string, chains?: ("solana" | "eclipse
125
143
  enabled: Boolean(address),
126
144
  });
127
145
  }
146
+
147
+ /**
148
+ * Hook to fetch a single token balance for a wallet.
149
+ * @param walletAddress - The wallet address to fetch balance for
150
+ * @param tokenAddress - The token contract address, or "native" for native token (ETH, etc.)
151
+ * @param chainId - Chain ID to query (defaults to 1 for Ethereum mainnet)
152
+ */
153
+ export function useSimTokenBalance(walletAddress?: string, tokenAddress?: string, chainId?: number) {
154
+ return useQuery({
155
+ queryKey: ["simTokenBalance", walletAddress, tokenAddress, chainId],
156
+ queryFn: () => {
157
+ if (!walletAddress || !tokenAddress || !chainId) {
158
+ throw new Error("Missing required parameters");
159
+ }
160
+ return fetchSimTokenBalance(walletAddress, tokenAddress, chainId);
161
+ },
162
+ enabled: Boolean(walletAddress) && Boolean(tokenAddress),
163
+ });
164
+ }
@@ -0,0 +1,238 @@
1
+ import type { NFT, SimpleHashNFTResponse } from "@b3dotfun/sdk/global-account/types/simplehash.types";
2
+ import { useQuery } from "@tanstack/react-query";
3
+ import { buildSimduneUrl } from "../utils/simdune";
4
+
5
+ /**
6
+ * Safely parse a balance string to a number, capping at MAX_SAFE_INTEGER
7
+ * to prevent overflow issues with large ERC1155 balances.
8
+ */
9
+ function safeParseBalance(balance: string | undefined): number {
10
+ if (!balance) return 1;
11
+ const parsed = parseInt(balance, 10);
12
+ if (Number.isNaN(parsed)) return 1;
13
+ return Math.min(parsed, Number.MAX_SAFE_INTEGER);
14
+ }
15
+
16
+ // Simdune Collectibles types
17
+ export interface SimCollectibleMetadata {
18
+ uri: string;
19
+ attributes?: Array<{
20
+ trait_type: string;
21
+ value: string;
22
+ display_type?: string | null;
23
+ }>;
24
+ }
25
+
26
+ export interface SimCollectibleEntry {
27
+ contract_address: string;
28
+ token_standard: "ERC721" | "ERC1155";
29
+ token_id: string;
30
+ chain: string;
31
+ chain_id: number;
32
+ name?: string;
33
+ description?: string;
34
+ symbol?: string;
35
+ image_url?: string;
36
+ last_sale_price?: string;
37
+ metadata?: SimCollectibleMetadata;
38
+ is_spam?: boolean;
39
+ spam_score?: number;
40
+ explanations?: string[];
41
+ balance?: string;
42
+ last_acquired?: string;
43
+ }
44
+
45
+ export interface SimCollectiblesResponse {
46
+ address: string;
47
+ entries: SimCollectibleEntry[];
48
+ next_offset?: string;
49
+ request_time: string;
50
+ response_time: string;
51
+ }
52
+
53
+ async function fetchSimCollectibles(
54
+ address: string,
55
+ chainIdsParam?: number[],
56
+ options?: { limit?: number; filterSpam?: boolean },
57
+ ): Promise<SimCollectiblesResponse> {
58
+ if (!address) throw new Error("Address is required");
59
+
60
+ const queryParams = new URLSearchParams();
61
+ if (chainIdsParam && chainIdsParam.length > 0) {
62
+ queryParams.append("chain_ids", chainIdsParam.join(","));
63
+ }
64
+ if (options?.limit) {
65
+ queryParams.append("limit", options.limit.toString());
66
+ }
67
+ if (options?.filterSpam !== undefined) {
68
+ queryParams.append("filter_spam", options.filterSpam.toString());
69
+ }
70
+
71
+ const url = buildSimduneUrl(`/v1/evm/collectibles/${address}`, queryParams);
72
+ const response = await fetch(url);
73
+
74
+ if (!response.ok) {
75
+ throw new Error(`Failed to fetch collectibles: ${response.statusText}`);
76
+ }
77
+
78
+ const data: SimCollectiblesResponse = await response.json();
79
+ return data;
80
+ }
81
+
82
+ /**
83
+ * Transforms Simdune collectibles response to SimpleHash NFT format
84
+ * for compatibility with existing AccountAssets component
85
+ */
86
+ function transformToSimpleHashFormat(data: SimCollectiblesResponse): SimpleHashNFTResponse {
87
+ const nfts: NFT[] = data.entries.map(entry => ({
88
+ nft_id: `${entry.chain}.${entry.contract_address}.${entry.token_id}`,
89
+ chain: entry.chain,
90
+ contract_address: entry.contract_address,
91
+ token_id: entry.token_id,
92
+ name: entry.name || "",
93
+ description: entry.description || "",
94
+ previews: {
95
+ image_small_url: entry.image_url || "",
96
+ image_medium_url: entry.image_url || "",
97
+ image_large_url: entry.image_url || "",
98
+ image_opengraph_url: entry.image_url || "",
99
+ blurhash: "",
100
+ predominant_color: "",
101
+ },
102
+ image_url: entry.image_url || "",
103
+ image_properties: {
104
+ width: 0,
105
+ height: 0,
106
+ size: 0,
107
+ mime_type: "",
108
+ exif_orientation: null,
109
+ },
110
+ video_url: null,
111
+ video_properties: null,
112
+ audio_url: null,
113
+ audio_properties: null,
114
+ model_url: null,
115
+ model_properties: null,
116
+ other_url: null,
117
+ other_properties: null,
118
+ background_color: null,
119
+ external_url: null,
120
+ created_date: "",
121
+ status: "minted",
122
+ token_count: 1,
123
+ owner_count: 1,
124
+ owners: [
125
+ {
126
+ owner_address: data.address,
127
+ quantity: safeParseBalance(entry.balance),
128
+ quantity_string: entry.balance || "1",
129
+ first_acquired_date: entry.last_acquired || "",
130
+ last_acquired_date: entry.last_acquired || "",
131
+ },
132
+ ],
133
+ contract: {
134
+ type: entry.token_standard,
135
+ name: entry.name || "",
136
+ symbol: entry.symbol || null,
137
+ deployed_by: "",
138
+ deployed_via_contract: "",
139
+ owned_by: "",
140
+ has_multiple_collections: false,
141
+ },
142
+ collection: {
143
+ collection_id: entry.contract_address,
144
+ name: entry.symbol || "Unknown Collection",
145
+ description: null,
146
+ image_url: entry.image_url || "",
147
+ image_properties: {
148
+ width: 0,
149
+ height: 0,
150
+ mime_type: "",
151
+ },
152
+ banner_image_url: null,
153
+ category: null,
154
+ is_nsfw: null,
155
+ external_url: null,
156
+ twitter_username: null,
157
+ discord_url: null,
158
+ instagram_username: null,
159
+ medium_username: null,
160
+ telegram_url: null,
161
+ marketplace_pages: [],
162
+ metaplex_mint: null,
163
+ metaplex_candy_machine: null,
164
+ metaplex_first_verified_creator: null,
165
+ floor_prices: [],
166
+ top_bids: [],
167
+ distinct_owner_count: 0,
168
+ distinct_nft_count: 0,
169
+ total_quantity: 0,
170
+ chains: [entry.chain],
171
+ top_contracts: [entry.contract_address],
172
+ collection_royalties: [],
173
+ },
174
+ last_sale: entry.last_sale_price
175
+ ? {
176
+ price: entry.last_sale_price,
177
+ }
178
+ : null,
179
+ primary_sale: null,
180
+ first_created: {
181
+ minted_to: data.address,
182
+ quantity: 1,
183
+ quantity_string: "1",
184
+ timestamp: "",
185
+ block_number: 0,
186
+ transaction: "",
187
+ transaction_initiator: "",
188
+ },
189
+ rarity: {
190
+ rank: null,
191
+ score: null,
192
+ unique_attributes: null,
193
+ },
194
+ royalty: [],
195
+ extra_metadata: {
196
+ attributes: (entry.metadata?.attributes || []).map(attr => ({
197
+ trait_type: attr.trait_type,
198
+ value: attr.value,
199
+ display_type: attr.display_type ?? null,
200
+ })),
201
+ image_original_url: entry.image_url || "",
202
+ animation_original_url: null,
203
+ metadata_original_url: entry.metadata?.uri || "",
204
+ },
205
+ }));
206
+
207
+ return {
208
+ next_cursor: data.next_offset || null,
209
+ next: null,
210
+ previous: null,
211
+ nfts,
212
+ };
213
+ }
214
+
215
+ /**
216
+ * Hook to fetch NFT collectibles from Simdune API.
217
+ * Returns data in SimpleHash format for compatibility with AccountAssets component.
218
+ * @param address - Wallet address to fetch collectibles for
219
+ * @param chainIdsParam - Optional array of chain IDs to filter by
220
+ * @param options - Optional parameters (limit, filterSpam)
221
+ */
222
+ export function useSimCollectibles(
223
+ address?: string,
224
+ chainIdsParam?: number[],
225
+ options?: { limit?: number; filterSpam?: boolean },
226
+ ) {
227
+ return useQuery({
228
+ queryKey: ["simCollectibles", address, chainIdsParam, options],
229
+ queryFn: async () => {
230
+ if (!address) throw new Error("Address is required");
231
+ const data = await fetchSimCollectibles(address, chainIdsParam, options);
232
+ return transformToSimpleHashFormat(data);
233
+ },
234
+ enabled: Boolean(address),
235
+ staleTime: 30 * 1000,
236
+ gcTime: 5 * 60 * 1000,
237
+ });
238
+ }
@@ -1,5 +1,4 @@
1
1
  export { useAuthStore } from "./useAuthStore";
2
- export { useB3ConfigStore } from "./configStore";
3
2
  export { useModalStore } from "./useModalStore";
4
3
  export { useRecentAddressesStore } from "./useRecentAddressesStore";
5
4
 
@@ -511,6 +511,65 @@ export interface AnySpendCollectorClubPurchaseProps extends BaseModalProps {
511
511
  forceFiatPayment?: boolean;
512
512
  }
513
513
 
514
+ /**
515
+ * Props for the AnySpend Deposit modal
516
+ * Flexible deposit component with optional chain selection
517
+ */
518
+ export interface AnySpendDepositModalProps extends BaseModalProps {
519
+ /** Modal type identifier */
520
+ type: "anySpendDeposit";
521
+ /** Order ID to load an existing order */
522
+ loadOrder?: string;
523
+ /** The recipient address for the deposit */
524
+ recipientAddress: string;
525
+ /** Payment type - crypto or fiat. If not set, shows chain selection first */
526
+ paymentType?: "crypto" | "fiat";
527
+ /** Source token address to pre-select */
528
+ sourceTokenAddress?: string;
529
+ /** Source chain ID to pre-select. If not provided, shows chain selection */
530
+ sourceTokenChainId?: number;
531
+ /** The destination token address */
532
+ destinationTokenAddress: string;
533
+ /** The destination chain ID */
534
+ destinationTokenChainId: number;
535
+ /** Callback when deposit succeeds */
536
+ onSuccess?: (amount: string) => void;
537
+ /** Callback for opening a custom modal (e.g., for special token handling) */
538
+ onOpenCustomModal?: () => void;
539
+ /** Custom footer content */
540
+ mainFooter?: React.ReactNode;
541
+ /** Called when a token is selected. Call event.preventDefault() to prevent default behavior */
542
+ onTokenSelect?: (token: components["schemas"]["Token"], event: { preventDefault: () => void }) => void;
543
+ /** Custom USD input value presets for fiat payment */
544
+ customUsdInputValues?: string[];
545
+ /** Whether to prefer using connected EOA wallet */
546
+ preferEoa?: boolean;
547
+ /** Minimum destination amount required */
548
+ minDestinationAmount?: number;
549
+ /** Order type for the deposit */
550
+ orderType?: "hype_duel" | "custom_exact_in" | "swap";
551
+ /** Custom action label displayed on buttons */
552
+ actionLabel?: string;
553
+ /** Whether to show chain selection step. Defaults to true if sourceTokenChainId is not provided */
554
+ showChainSelection?: boolean;
555
+ /** Minimum pool size for filtering tokens (default: 1,000,000) */
556
+ minPoolSize?: number;
557
+ /** Custom title for chain selection step */
558
+ chainSelectionTitle?: string;
559
+ /** Custom description for chain selection step */
560
+ chainSelectionDescription?: string;
561
+ /** Number of top chains to show (default: 3) */
562
+ topChainsCount?: number;
563
+ /** Custom URL to redirect to when clicking "Return to Home" on complete order screen */
564
+ returnToHomeUrl?: string;
565
+ /** Custom label for recipient display (e.g., "OBSN Telegram Bot") */
566
+ customRecipientLabel?: string;
567
+ /** Custom label for the return home button (overrides "Return to Home" / "Close") */
568
+ returnHomeLabel?: string;
569
+ /** Whether the deposit requires a custom function (uses AnySpendCustomExactIn). Defaults to false. */
570
+ isCustomDeposit?: boolean;
571
+ }
572
+
514
573
  /**
515
574
  * Union type of all possible modal content types
516
575
  */
@@ -540,7 +599,8 @@ export type ModalContentType =
540
599
  | DepositModalProps
541
600
  | SendModalProps
542
601
  | NotificationsModalProps
543
- | AnySpendCollectorClubPurchaseProps;
602
+ | AnySpendCollectorClubPurchaseProps
603
+ | AnySpendDepositModalProps;
544
604
  // Add other modal types here like: | OtherModalProps | AnotherModalProps
545
605
 
546
606
  /**
@@ -571,6 +631,8 @@ interface ModalState {
571
631
  linkingMethod: string | null;
572
632
  /** Function to set the linking state */
573
633
  setLinkingState: (isLinking: boolean, method?: string | null) => void;
634
+ /** Function to update closable property of current content without adding to history */
635
+ setClosable: (closable: boolean) => void;
574
636
  }
575
637
 
576
638
  /**
@@ -610,4 +672,8 @@ export const useModalStore = create<ModalState>(set => ({
610
672
  linkingMethod: null,
611
673
  setLinkingState: (isLinking: boolean, method: string | null = null) =>
612
674
  set({ isLinking, linkingMethod: isLinking ? method : null }),
675
+ setClosable: (closable: boolean) =>
676
+ set(state => ({
677
+ contentType: state.contentType ? { ...state.contentType, closable } : null,
678
+ })),
613
679
  }));
@@ -0,0 +1,38 @@
1
+ import type { CombinedProfile } from "../hooks/useProfile";
2
+
3
+ export const PROFILES_API_URL = "https://profiles.b3.fun";
4
+
5
+ /**
6
+ * Fetch a user profile from the B3 Profiles API
7
+ * @param params - Search parameters (address, name, or b3GlobalId)
8
+ * @returns Promise resolving to CombinedProfile or null if not found
9
+ */
10
+ export async function fetchProfile({
11
+ address,
12
+ name,
13
+ b3GlobalId,
14
+ fresh = false,
15
+ }: {
16
+ address?: string;
17
+ name?: string;
18
+ b3GlobalId?: string;
19
+ fresh?: boolean;
20
+ }): Promise<CombinedProfile> {
21
+ if (!address && !name && !b3GlobalId) {
22
+ throw new Error("Either address or name or b3GlobalId must be provided");
23
+ }
24
+
25
+ const params = new URLSearchParams();
26
+ if (address) params.append("address", address);
27
+ if (name) params.append("name", name);
28
+ if (b3GlobalId) params.append("b3GlobalId", b3GlobalId);
29
+ if (fresh) params.append("fresh", "true");
30
+
31
+ const response = await fetch(`${PROFILES_API_URL}?${params.toString()}`);
32
+
33
+ if (!response.ok) {
34
+ throw new Error(`Failed to fetch profile: ${response.statusText}`);
35
+ }
36
+
37
+ return response.json();
38
+ }
@@ -0,0 +1,20 @@
1
+ export const SIMDUNE_API_HOST = "https://simdune-api.sean-430.workers.dev";
2
+
3
+ /**
4
+ * Builds a Simdune API URL with the proxy wrapper and optional dev mode key.
5
+ * @param endpoint - The Simdune API endpoint (e.g., "/v1/evm/balances/0x...")
6
+ * @param queryParams - Optional URLSearchParams to append
7
+ */
8
+ export function buildSimduneUrl(endpoint: string, queryParams?: URLSearchParams): string {
9
+ const baseUrl = `${SIMDUNE_API_HOST}/?url=https://api.sim.dune.com${endpoint}`;
10
+
11
+ let url = baseUrl;
12
+ if (queryParams && queryParams.toString()) {
13
+ url += `?${queryParams.toString()}`;
14
+ }
15
+ if (process.env.NEXT_PUBLIC_DEVMODE_SHARED_SECRET) {
16
+ url += `${queryParams?.toString() ? "&" : "?"}localkey=${process.env.NEXT_PUBLIC_DEVMODE_SHARED_SECRET}`;
17
+ }
18
+
19
+ return url;
20
+ }
@@ -1,24 +0,0 @@
1
- import { CreateOnrampOrderParams } from "../../../anyspend/react/hooks/useAnyspendCreateOnrampOrder";
2
- import { CreateOrderParams } from "../../../anyspend/react/hooks/useAnyspendCreateOrder";
3
- import { PermissionsConfig } from "../../../global-account/types/permissions";
4
- import { Account } from "thirdweb/wallets";
5
- import { ClientType } from "../../client-manager";
6
- interface ConfigStore {
7
- accountOverride?: Account;
8
- automaticallySetFirstEoa: boolean;
9
- environment: "development" | "production";
10
- defaultPermissions: PermissionsConfig;
11
- theme: "light" | "dark";
12
- clientType: ClientType;
13
- partnerId: string;
14
- stripePublishableKey?: string;
15
- createClientReferenceId?: (params: CreateOrderParams | CreateOnrampOrderParams) => Promise<string>;
16
- enableTurnkey: boolean;
17
- setConfig: (config: Partial<Omit<ConfigStore, "setConfig">>) => void;
18
- }
19
- /**
20
- * Zustand store for B3 configuration
21
- * NOT persisted - these are developer-set configuration values
22
- */
23
- export declare const useB3ConfigStore: import("zustand").UseBoundStore<import("zustand").StoreApi<ConfigStore>>;
24
- export {};
@@ -1,30 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useB3ConfigStore = void 0;
4
- const zustand_1 = require("zustand");
5
- /**
6
- * Default permissions configuration for B3 provider
7
- */
8
- const DEFAULT_PERMISSIONS = {
9
- approvedTargets: ["0xa8e42121e318e3D3BeD7f5969AF6D360045317DD"],
10
- nativeTokenLimitPerTransaction: 0.1,
11
- startDate: new Date(),
12
- endDate: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365), // 1 year from now
13
- };
14
- /**
15
- * Zustand store for B3 configuration
16
- * NOT persisted - these are developer-set configuration values
17
- */
18
- exports.useB3ConfigStore = (0, zustand_1.create)(set => ({
19
- accountOverride: undefined,
20
- automaticallySetFirstEoa: false,
21
- environment: "development",
22
- defaultPermissions: DEFAULT_PERMISSIONS,
23
- theme: "light",
24
- clientType: "rest",
25
- partnerId: "",
26
- stripePublishableKey: undefined,
27
- createClientReferenceId: undefined,
28
- enableTurnkey: false,
29
- setConfig: config => set(state => ({ ...state, ...config })),
30
- }));
@@ -1,24 +0,0 @@
1
- import { CreateOnrampOrderParams } from "../../../anyspend/react/hooks/useAnyspendCreateOnrampOrder";
2
- import { CreateOrderParams } from "../../../anyspend/react/hooks/useAnyspendCreateOrder";
3
- import { PermissionsConfig } from "../../../global-account/types/permissions";
4
- import { Account } from "thirdweb/wallets";
5
- import { ClientType } from "../../client-manager";
6
- interface ConfigStore {
7
- accountOverride?: Account;
8
- automaticallySetFirstEoa: boolean;
9
- environment: "development" | "production";
10
- defaultPermissions: PermissionsConfig;
11
- theme: "light" | "dark";
12
- clientType: ClientType;
13
- partnerId: string;
14
- stripePublishableKey?: string;
15
- createClientReferenceId?: (params: CreateOrderParams | CreateOnrampOrderParams) => Promise<string>;
16
- enableTurnkey: boolean;
17
- setConfig: (config: Partial<Omit<ConfigStore, "setConfig">>) => void;
18
- }
19
- /**
20
- * Zustand store for B3 configuration
21
- * NOT persisted - these are developer-set configuration values
22
- */
23
- export declare const useB3ConfigStore: import("zustand").UseBoundStore<import("zustand").StoreApi<ConfigStore>>;
24
- export {};
@@ -1,27 +0,0 @@
1
- import { create } from "zustand";
2
- /**
3
- * Default permissions configuration for B3 provider
4
- */
5
- const DEFAULT_PERMISSIONS = {
6
- approvedTargets: ["0xa8e42121e318e3D3BeD7f5969AF6D360045317DD"],
7
- nativeTokenLimitPerTransaction: 0.1,
8
- startDate: new Date(),
9
- endDate: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365), // 1 year from now
10
- };
11
- /**
12
- * Zustand store for B3 configuration
13
- * NOT persisted - these are developer-set configuration values
14
- */
15
- export const useB3ConfigStore = create(set => ({
16
- accountOverride: undefined,
17
- automaticallySetFirstEoa: false,
18
- environment: "development",
19
- defaultPermissions: DEFAULT_PERMISSIONS,
20
- theme: "light",
21
- clientType: "rest",
22
- partnerId: "",
23
- stripePublishableKey: undefined,
24
- createClientReferenceId: undefined,
25
- enableTurnkey: false,
26
- setConfig: config => set(state => ({ ...state, ...config })),
27
- }));