@b3dotfun/sdk 0.1.70-alpha.18 → 0.1.70-alpha.19

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 (155) hide show
  1. package/README.md +3 -3
  2. package/dist/cjs/anyspend/constants/rpc.d.ts +1 -0
  3. package/dist/cjs/anyspend/constants/rpc.js +3 -1
  4. package/dist/cjs/anyspend/react/components/AnySpendDeposit.d.ts +1 -3
  5. package/dist/cjs/anyspend/react/components/AnySpendDeposit.js +14 -12
  6. package/dist/cjs/anyspend/react/components/AnySpendStakeB3.js +32 -13
  7. package/dist/cjs/anyspend/react/components/AnySpendStakeB3ExactIn.js +32 -10
  8. package/dist/cjs/anyspend/react/components/checkout/CryptoPayPanel.js +16 -8
  9. package/dist/cjs/anyspend/react/components/common/TokenBalance.js +4 -5
  10. package/dist/cjs/anyspend/react/hooks/useSigMint.d.ts +1 -1
  11. package/dist/cjs/anyspend/utils/chain.d.ts +45 -0
  12. package/dist/cjs/anyspend/utils/chain.js +51 -2
  13. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.d.ts +1 -2
  14. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.js +2 -2
  15. package/dist/cjs/global-account/react/components/B3Provider/RelayKitProviderWrapper.d.ts +1 -2
  16. package/dist/cjs/global-account/react/components/B3Provider/RelayKitProviderWrapper.js +4 -5
  17. package/dist/cjs/global-account/react/components/ManageAccount/ContentTokens.js +23 -15
  18. package/dist/cjs/global-account/react/components/ManageAccount/NFTContent.js +2 -2
  19. package/dist/cjs/global-account/react/components/ManageAccount/ProfileSection.js +8 -6
  20. package/dist/cjs/global-account/react/components/ManageAccount/TokenContent.js +17 -8
  21. package/dist/cjs/global-account/react/components/Send/Send.js +15 -11
  22. package/dist/cjs/global-account/react/hooks/index.d.ts +2 -2
  23. package/dist/cjs/global-account/react/hooks/index.js +7 -8
  24. package/dist/cjs/global-account/react/hooks/useAuth.d.ts +2 -1
  25. package/dist/cjs/global-account/react/hooks/useAuth.js +1 -0
  26. package/dist/cjs/global-account/react/hooks/useAuthentication.d.ts +2 -1
  27. package/dist/cjs/global-account/react/hooks/useAuthentication.js +1 -0
  28. package/dist/cjs/global-account/react/hooks/useFirstEOA.d.ts +4 -7666
  29. package/dist/cjs/global-account/react/hooks/useFirstEOA.js +1 -0
  30. package/dist/cjs/global-account/react/hooks/usePortfolioBalance.d.ts +15 -0
  31. package/dist/cjs/global-account/react/hooks/usePortfolioBalance.js +76 -0
  32. package/dist/cjs/global-account/react/hooks/usePortfolioCollectibles.d.ts +12 -0
  33. package/dist/cjs/global-account/react/hooks/usePortfolioCollectibles.js +178 -0
  34. package/dist/cjs/global-account/react/stores/useModalStore.d.ts +0 -2
  35. package/dist/cjs/global-account/react/utils/createWagmiConfig.d.ts +2 -2
  36. package/dist/cjs/shared/constants/chains/b3Chain.d.ts +24 -0
  37. package/dist/cjs/shared/constants/chains/supported.d.ts +4 -4
  38. package/dist/cjs/shared/constants/index.d.ts +4 -0
  39. package/dist/cjs/shared/utils/zerionPositions.d.ts +96 -0
  40. package/dist/cjs/shared/utils/zerionPositions.js +186 -0
  41. package/dist/cjs/wallet/utils/createWalletConfig.d.ts +2 -2
  42. package/dist/esm/anyspend/constants/rpc.d.ts +1 -0
  43. package/dist/esm/anyspend/constants/rpc.js +2 -0
  44. package/dist/esm/anyspend/react/components/AnySpendDeposit.d.ts +1 -3
  45. package/dist/esm/anyspend/react/components/AnySpendDeposit.js +15 -13
  46. package/dist/esm/anyspend/react/components/AnySpendStakeB3.js +33 -14
  47. package/dist/esm/anyspend/react/components/AnySpendStakeB3ExactIn.js +33 -11
  48. package/dist/esm/anyspend/react/components/checkout/CryptoPayPanel.js +18 -10
  49. package/dist/esm/anyspend/react/components/common/TokenBalance.js +6 -7
  50. package/dist/esm/anyspend/react/hooks/useSigMint.d.ts +1 -1
  51. package/dist/esm/anyspend/utils/chain.d.ts +45 -0
  52. package/dist/esm/anyspend/utils/chain.js +50 -3
  53. package/dist/esm/global-account/react/components/B3Provider/B3Provider.d.ts +1 -2
  54. package/dist/esm/global-account/react/components/B3Provider/B3Provider.js +2 -2
  55. package/dist/esm/global-account/react/components/B3Provider/RelayKitProviderWrapper.d.ts +1 -2
  56. package/dist/esm/global-account/react/components/B3Provider/RelayKitProviderWrapper.js +4 -5
  57. package/dist/esm/global-account/react/components/ManageAccount/ContentTokens.js +24 -16
  58. package/dist/esm/global-account/react/components/ManageAccount/NFTContent.js +3 -3
  59. package/dist/esm/global-account/react/components/ManageAccount/ProfileSection.js +9 -7
  60. package/dist/esm/global-account/react/components/ManageAccount/TokenContent.js +18 -9
  61. package/dist/esm/global-account/react/components/Send/Send.js +16 -12
  62. package/dist/esm/global-account/react/hooks/index.d.ts +2 -2
  63. package/dist/esm/global-account/react/hooks/index.js +2 -2
  64. package/dist/esm/global-account/react/hooks/useAuth.d.ts +2 -1
  65. package/dist/esm/global-account/react/hooks/useAuth.js +1 -0
  66. package/dist/esm/global-account/react/hooks/useAuthentication.d.ts +2 -1
  67. package/dist/esm/global-account/react/hooks/useAuthentication.js +1 -0
  68. package/dist/esm/global-account/react/hooks/useFirstEOA.d.ts +4 -7666
  69. package/dist/esm/global-account/react/hooks/useFirstEOA.js +1 -0
  70. package/dist/esm/global-account/react/hooks/usePortfolioBalance.d.ts +15 -0
  71. package/dist/esm/global-account/react/hooks/usePortfolioBalance.js +72 -0
  72. package/dist/esm/global-account/react/hooks/usePortfolioCollectibles.d.ts +12 -0
  73. package/dist/esm/global-account/react/hooks/usePortfolioCollectibles.js +175 -0
  74. package/dist/esm/global-account/react/stores/useModalStore.d.ts +0 -2
  75. package/dist/esm/global-account/react/utils/createWagmiConfig.d.ts +2 -2
  76. package/dist/esm/shared/constants/chains/b3Chain.d.ts +24 -0
  77. package/dist/esm/shared/constants/chains/supported.d.ts +4 -4
  78. package/dist/esm/shared/constants/index.d.ts +4 -0
  79. package/dist/esm/shared/utils/zerionPositions.d.ts +96 -0
  80. package/dist/esm/shared/utils/zerionPositions.js +178 -0
  81. package/dist/esm/wallet/utils/createWalletConfig.d.ts +2 -2
  82. package/dist/types/anyspend/constants/rpc.d.ts +1 -0
  83. package/dist/types/anyspend/react/components/AnySpendDeposit.d.ts +1 -3
  84. package/dist/types/anyspend/react/hooks/useSigMint.d.ts +1 -1
  85. package/dist/types/anyspend/utils/chain.d.ts +45 -0
  86. package/dist/types/global-account/react/components/B3Provider/B3Provider.d.ts +1 -2
  87. package/dist/types/global-account/react/components/B3Provider/RelayKitProviderWrapper.d.ts +1 -2
  88. package/dist/types/global-account/react/hooks/index.d.ts +2 -2
  89. package/dist/types/global-account/react/hooks/useAuth.d.ts +2 -1
  90. package/dist/types/global-account/react/hooks/useAuthentication.d.ts +2 -1
  91. package/dist/types/global-account/react/hooks/useFirstEOA.d.ts +4 -7666
  92. package/dist/types/global-account/react/hooks/usePortfolioBalance.d.ts +15 -0
  93. package/dist/types/global-account/react/hooks/usePortfolioCollectibles.d.ts +12 -0
  94. package/dist/types/global-account/react/stores/useModalStore.d.ts +0 -2
  95. package/dist/types/global-account/react/utils/createWagmiConfig.d.ts +2 -2
  96. package/dist/types/shared/constants/chains/b3Chain.d.ts +24 -0
  97. package/dist/types/shared/constants/chains/supported.d.ts +4 -4
  98. package/dist/types/shared/constants/index.d.ts +4 -0
  99. package/dist/types/shared/utils/zerionPositions.d.ts +96 -0
  100. package/dist/types/wallet/utils/createWalletConfig.d.ts +2 -2
  101. package/node_modules/@b3/chain-registry/chains.json +29 -1
  102. package/node_modules/@b3/chain-registry/package.json +18 -2
  103. package/package.json +2 -2
  104. package/src/anyspend/README.md +2 -2
  105. package/src/anyspend/constants/rpc.ts +2 -0
  106. package/src/anyspend/docs/components.md +6 -6
  107. package/src/anyspend/docs/contributing.md +1 -1
  108. package/src/anyspend/docs/hooks.md +3 -3
  109. package/src/anyspend/docs/installation.md +2 -2
  110. package/src/anyspend/react/components/AnySpendDeposit.tsx +26 -19
  111. package/src/anyspend/react/components/AnySpendStakeB3.tsx +55 -14
  112. package/src/anyspend/react/components/AnySpendStakeB3ExactIn.tsx +55 -11
  113. package/src/anyspend/react/components/__tests__/QRDeposit.test.tsx +3 -4
  114. package/src/anyspend/react/components/checkout/CryptoPayPanel.tsx +25 -12
  115. package/src/anyspend/react/components/common/TokenBalance.tsx +10 -7
  116. package/src/anyspend/utils/__tests__/deprecatedChains.test.ts +44 -0
  117. package/src/anyspend/utils/__tests__/toRegistryChainId.test.ts +17 -0
  118. package/src/anyspend/utils/chain.ts +53 -2
  119. package/src/global-account/react/components/B3Provider/B3Provider.tsx +1 -3
  120. package/src/global-account/react/components/B3Provider/RelayKitProviderWrapper.tsx +4 -11
  121. package/src/global-account/react/components/ManageAccount/ContentTokens.tsx +50 -21
  122. package/src/global-account/react/components/ManageAccount/NFTContent.tsx +5 -3
  123. package/src/global-account/react/components/ManageAccount/ProfileSection.tsx +10 -6
  124. package/src/global-account/react/components/ManageAccount/TokenContent.tsx +22 -9
  125. package/src/global-account/react/components/Send/Send.tsx +39 -15
  126. package/src/global-account/react/hooks/index.ts +2 -2
  127. package/src/global-account/react/hooks/useAuth.ts +3 -2
  128. package/src/global-account/react/hooks/useAuthentication.ts +3 -2
  129. package/src/global-account/react/hooks/useFirstEOA.tsx +9 -2
  130. package/src/global-account/react/hooks/usePortfolioBalance.ts +89 -0
  131. package/src/global-account/react/hooks/usePortfolioCollectibles.ts +212 -0
  132. package/src/global-account/react/stores/useModalStore.ts +0 -2
  133. package/src/shared/constants/index.ts +8 -0
  134. package/src/shared/utils/__tests__/zerionPositions.test.ts +226 -0
  135. package/src/shared/utils/zerionPositions.ts +244 -0
  136. package/dist/cjs/global-account/react/hooks/useSimBalance.d.ts +0 -59
  137. package/dist/cjs/global-account/react/hooks/useSimBalance.js +0 -98
  138. package/dist/cjs/global-account/react/hooks/useSimCollectibles.d.ts +0 -45
  139. package/dist/cjs/global-account/react/hooks/useSimCollectibles.js +0 -190
  140. package/dist/cjs/global-account/react/utils/simdune.d.ts +0 -7
  141. package/dist/cjs/global-account/react/utils/simdune.js +0 -21
  142. package/dist/esm/global-account/react/hooks/useSimBalance.d.ts +0 -59
  143. package/dist/esm/global-account/react/hooks/useSimBalance.js +0 -93
  144. package/dist/esm/global-account/react/hooks/useSimCollectibles.d.ts +0 -45
  145. package/dist/esm/global-account/react/hooks/useSimCollectibles.js +0 -187
  146. package/dist/esm/global-account/react/utils/simdune.d.ts +0 -7
  147. package/dist/esm/global-account/react/utils/simdune.js +0 -17
  148. package/dist/types/global-account/react/hooks/useSimBalance.d.ts +0 -59
  149. package/dist/types/global-account/react/hooks/useSimCollectibles.d.ts +0 -45
  150. package/dist/types/global-account/react/utils/simdune.d.ts +0 -7
  151. package/node_modules/@b3/chain-registry/src/index.ts +0 -169
  152. package/node_modules/@b3/chain-registry/tsconfig.json +0 -16
  153. package/src/global-account/react/hooks/useSimBalance.ts +0 -164
  154. package/src/global-account/react/hooks/useSimCollectibles.ts +0 -238
  155. package/src/global-account/react/utils/simdune.ts +0 -20
@@ -1,169 +0,0 @@
1
- import chainsData from "../chains.json";
2
-
3
- export interface ManualToken {
4
- address: `0x${string}`;
5
- symbol: string;
6
- decimals: number;
7
- name: string;
8
- logoUrl?: string;
9
- }
10
-
11
- /**
12
- * Known integration tags that can appear in `ChainDefinition.integrations`.
13
- * Adding a new integration → extend this union. Consumers calling
14
- * `chainsByIntegration("foo")` get autocomplete + typo safety.
15
- */
16
- export type KnownIntegration =
17
- | "aerodrome"
18
- | "anyspend"
19
- | "cow-swap"
20
- | "evm-log"
21
- | "morpho"
22
- | "railgun"
23
- | "x402"
24
- | "zerodev";
25
-
26
- export interface ChainDefinition {
27
- chainId: number;
28
- key: string;
29
- name: string;
30
- network: string;
31
- type: "evm" | "solana";
32
- isTestnet: boolean;
33
- integrations: KnownIntegration[];
34
- nativeCurrency: {
35
- name: string;
36
- symbol: string;
37
- decimals: number;
38
- };
39
- explorer: string;
40
- rpcEnvKey: string | null;
41
- fallbackRpc: string | null;
42
- quicknodeSlug: string | null;
43
- quicknodeRpcPath?: string;
44
- coingecko: {
45
- platform: string;
46
- nativeCoinId: string;
47
- } | null;
48
- /**
49
- * GeckoTerminal network slug (differs from `coingecko.platform`: GT uses
50
- * "eth", CoinGecko uses "ethereum"). Used for on-chain pool lookups and
51
- * OHLCV charts. Null when GeckoTerminal does not index this chain.
52
- */
53
- geckoTerminalNetwork?: string | null;
54
- trustwalletSlug: string | null;
55
- logoUrl: string | null;
56
- tags: string[];
57
- manualTokens?: ManualToken[];
58
- /**
59
- * Wrapped-native ERC20 address (e.g. WETH on Ethereum, WPLUME on Plume).
60
- * Used for GeckoTerminal pool lookups on the native coin and for DEX
61
- * routing that needs an ERC20 form of the gas token.
62
- */
63
- wrappedNative?: `0x${string}`;
64
- }
65
-
66
- export const chains: ChainDefinition[] = chainsData as ChainDefinition[];
67
-
68
- export const evmChains = chains.filter(c => c.type === "evm");
69
-
70
- export const chainById = new Map(chains.map(c => [c.chainId, c]));
71
-
72
- export const CHAIN_IDS: Record<string, number> = Object.fromEntries(chains.map(c => [c.key, c.chainId]));
73
-
74
- export const CHAIN_NAMES: Record<number, string> = Object.fromEntries(chains.map(c => [c.chainId, c.name]));
75
-
76
- export const CHAIN_ID_TO_NETWORK: Record<number, string> = Object.fromEntries(chains.map(c => [c.chainId, c.network]));
77
-
78
- export const FALLBACK_RPC_URLS: Record<number, string> = Object.fromEntries(
79
- chains.filter(c => c.fallbackRpc).map(c => [c.chainId, c.fallbackRpc!]),
80
- );
81
-
82
- export const BLOCK_EXPLORERS: Record<number, string> = Object.fromEntries(chains.map(c => [c.chainId, c.explorer]));
83
-
84
- export const COINGECKO_MAPPINGS: Record<number, { platform: string; nativeCoinId: string }> = Object.fromEntries(
85
- chains.filter(c => c.coingecko).map(c => [c.chainId, c.coingecko!]),
86
- );
87
-
88
- export const TRUSTWALLET_SLUGS: Record<number, string> = Object.fromEntries(
89
- chains.filter(c => c.trustwalletSlug).map(c => [c.chainId, c.trustwalletSlug!]),
90
- );
91
-
92
- export const CHAIN_TAG_MAP: Record<string, number> = Object.fromEntries(
93
- chains.flatMap(c => c.tags.map(tag => [tag, c.chainId])),
94
- );
95
-
96
- export const LOGO_URLS: Record<number, string> = Object.fromEntries(
97
- chains.filter(c => c.logoUrl).map(c => [c.chainId, c.logoUrl!]),
98
- );
99
-
100
- export function buildQuicknodeUrl(subdomain: string, key: string, chain: ChainDefinition): string | null {
101
- if (chain.quicknodeSlug === null) return null;
102
- const network = chain.quicknodeSlug === "" ? "" : `.${chain.quicknodeSlug}`;
103
- const path = chain.quicknodeRpcPath ?? "";
104
- return `https://${subdomain}${network}.quiknode.pro/${key}${path}`;
105
- }
106
-
107
- export function buildQuicknodeRpcMap(subdomain: string, key: string): Record<number, string> {
108
- return Object.fromEntries(
109
- chains.filter(c => c.quicknodeSlug !== null).map(c => [c.chainId, buildQuicknodeUrl(subdomain, key, c)!]),
110
- );
111
- }
112
-
113
- export function chainsByIntegration(integration: KnownIntegration): ChainDefinition[] {
114
- return chains.filter(c => c.integrations.includes(integration));
115
- }
116
-
117
- export function chainIdsByIntegration(integration: KnownIntegration): number[] {
118
- return chainsByIntegration(integration).map(c => c.chainId);
119
- }
120
-
121
- export function chainNamesByIntegration(integration: KnownIntegration): Record<number, string> {
122
- return Object.fromEntries(chainsByIntegration(integration).map(c => [c.chainId, c.name]));
123
- }
124
-
125
- export const ZERODEV_SUPPORTED_CHAINS: ChainDefinition[] = chainsByIntegration("zerodev");
126
-
127
- /**
128
- * Chains tagged with the "anyspend" integration AND of EVM type — the set
129
- * consumed by SDK `supportedChains` / `supportedChainsTW` for AnySpend's
130
- * wallet-switch gate (`useUnifiedChainSwitchAndExecute`). Solana (also tagged
131
- * anyspend) is excluded here because it's handled by Phantom-based flows that
132
- * key off `RELAY_SOLANA_MAINNET_CHAIN_ID`, not viem.
133
- */
134
- export const ANYSPEND_EVM_CHAINS: ChainDefinition[] = chainsByIntegration("anyspend").filter(c => c.type === "evm");
135
-
136
- // Validate at module init: every anyspend EVM chain must have a fallbackRpc.
137
- // The SDK transformers (toViemChain / toThirdwebChain) assume this invariant
138
- // holds — catching a missing RPC here is far better than throwing on first
139
- // pay-button click in production.
140
- {
141
- const missingRpc = ANYSPEND_EVM_CHAINS.filter(c => !c.fallbackRpc);
142
- if (missingRpc.length > 0) {
143
- throw new Error(
144
- `chain-registry: anyspend EVM chains missing fallbackRpc: ${missingRpc.map(c => `${c.chainId} (${c.key})`).join(", ")}`,
145
- );
146
- }
147
- }
148
-
149
- /**
150
- * Chain IDs that the default indexer (Sim Dune) does not support.
151
- * These chains require RPC + CoinGecko fallback for balance/metadata.
152
- */
153
- export const MANUAL_CHAIN_IDS: ReadonlySet<number> = new Set(
154
- chains.filter(c => c.manualTokens && c.manualTokens.length > 0).map(c => c.chainId),
155
- );
156
-
157
- export function hasManualTokens(chainId: number): boolean {
158
- return MANUAL_CHAIN_IDS.has(chainId);
159
- }
160
-
161
- export function getManualTokens(chainId: number): ManualToken[] {
162
- return chainById.get(chainId)?.manualTokens ?? [];
163
- }
164
-
165
- export function findManualToken(chainId: number, address: string): ManualToken | null {
166
- const lower = address.toLowerCase();
167
- const tokens = getManualTokens(chainId);
168
- return tokens.find(t => t.address.toLowerCase() === lower) ?? null;
169
- }
@@ -1,16 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "ESNext",
5
- "moduleResolution": "bundler",
6
- "strict": true,
7
- "esModuleInterop": true,
8
- "skipLibCheck": true,
9
- "declaration": true,
10
- "declarationMap": true,
11
- "resolveJsonModule": true,
12
- "outDir": "./dist",
13
- "rootDir": "./src"
14
- },
15
- "include": ["src/**/*"]
16
- }
@@ -1,164 +0,0 @@
1
- import { useQuery } from "@tanstack/react-query";
2
- import { buildSimduneUrl } from "../utils/simdune";
3
-
4
- export interface SimTokenMetadata {
5
- logo?: string;
6
- }
7
-
8
- export interface SimBalanceItem {
9
- chain: string;
10
- chain_id: number;
11
- address: string;
12
- amount: string;
13
- symbol: string;
14
- decimals: number;
15
- price_usd?: number;
16
- value_usd?: number;
17
- name?: string;
18
- token_metadata?: SimTokenMetadata;
19
- pool_size?: number;
20
- low_liquidity?: boolean;
21
- }
22
-
23
- export interface SimBalanceResponse {
24
- request_time: string;
25
- response_time: string;
26
- wallet_address: string;
27
- balances: SimBalanceItem[];
28
- }
29
-
30
- // SVM-specific types
31
- export interface SvmBalanceItem {
32
- chain: string;
33
- address: string;
34
- amount: string;
35
- balance: string;
36
- raw_balance: string;
37
- value_usd?: number;
38
- program_id: string | null;
39
- decimals: number;
40
- total_supply: string;
41
- metadata_address?: string;
42
- name?: string;
43
- symbol: string;
44
- uri?: string | null;
45
- price_usd?: number;
46
- liquidity_usd?: number;
47
- pool_type?: string | null;
48
- pool_address?: string | null;
49
- mint_authority?: string | null;
50
- }
51
-
52
- export interface SvmBalanceResponse {
53
- processing_time_ms?: number;
54
- wallet_address: string;
55
- next_offset?: string;
56
- balances_count?: number;
57
- balances: SvmBalanceItem[];
58
- }
59
-
60
- async function fetchSimBalance(address: string, chainIdsParam: number[]): Promise<SimBalanceResponse> {
61
- if (!address) throw new Error("Address is required");
62
-
63
- const chainIds = chainIdsParam.length === 0 ? "mainnet" : chainIdsParam.join(",");
64
- const queryParams = new URLSearchParams();
65
- queryParams.append("metadata", "logo");
66
- queryParams.append("chain_ids", chainIds);
67
- queryParams.append("exclude_spam_tokens", "true");
68
-
69
- const url = buildSimduneUrl(`/v1/evm/balances/${address}`, queryParams);
70
- const response = await fetch(url);
71
-
72
- if (!response.ok) {
73
- throw new Error(`Failed to fetch balance: ${response.statusText}`);
74
- }
75
-
76
- const balanceData: SimBalanceResponse = await response.json();
77
- return balanceData;
78
- }
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
-
103
- async function fetchSimSvmBalance(address: string, chains?: string[], limit?: number): Promise<SvmBalanceResponse> {
104
- if (!address) throw new Error("Address is required");
105
-
106
- const queryParams = new URLSearchParams();
107
- if (chains && chains.length > 0) {
108
- queryParams.append("chains", chains.join(","));
109
- }
110
- if (limit) {
111
- queryParams.append("limit", limit.toString());
112
- }
113
-
114
- const url = buildSimduneUrl(`/beta/svm/balances/${address}`, queryParams.toString() ? queryParams : undefined);
115
- const response = await fetch(url);
116
-
117
- if (!response.ok) {
118
- throw new Error(`Failed to fetch SVM balance: ${response.statusText}`);
119
- }
120
-
121
- const balanceData: SvmBalanceResponse = await response.json();
122
- return balanceData;
123
- }
124
-
125
- export function useSimBalance(address?: string, chainIdsParam?: number[]) {
126
- return useQuery({
127
- queryKey: ["simBalance", address, chainIdsParam],
128
- queryFn: () => {
129
- if (!address) throw new Error("Address is required");
130
- return fetchSimBalance(address, chainIdsParam || []);
131
- },
132
- enabled: Boolean(address),
133
- });
134
- }
135
-
136
- export function useSimSvmBalance(address?: string, chains?: ("solana" | "eclipse")[], limit?: number) {
137
- return useQuery({
138
- queryKey: ["svmBalance", address, chains, limit],
139
- queryFn: () => {
140
- if (!address) throw new Error("Address is required");
141
- return fetchSimSvmBalance(address, chains, limit);
142
- },
143
- enabled: Boolean(address),
144
- });
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
- }
@@ -1,238 +0,0 @@
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,20 +0,0 @@
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
- }